From dce3263df303c124b8697f8a5914a33b20f43786 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 8 Feb 2017 08:57:05 +0100 Subject: [PATCH] Fix bulk progress bar (#428) * Fix progress par computation for bulk upload. Fixed sonar issues on the way. Signed-off-by: kaizimmerm --- .../documentation/guide/clustering.md | 5 +- .../test/util/AbstractIntegrationTest.java | 4 +- .../footer/AbstractDeleteActionsLayout.java | 2 +- .../hawkbit/ui/management/DeploymentView.java | 6 +- .../actionhistory/ActionHistoryTable.java | 1 - .../actionhistory/ActionStatusIconMapper.java | 2 +- .../footer/DeleteActionsLayout.java | 4 +- .../ui/management/state/TargetBulkUpload.java | 12 +- .../targettable/BulkUploadHandler.java | 187 +++++++----------- .../TargetBulkUpdateWindowLayout.java | 58 +++--- .../targettable/TargetTableHeader.java | 19 +- .../targettable/TargetTableLayout.java | 7 +- .../client/GroupsPieChartWidget.java | 3 +- .../hawkbit/ui/utils/HawkbitCommonUtil.java | 31 --- 14 files changed, 141 insertions(+), 200 deletions(-) diff --git a/docs/src/main/resources/documentation/guide/clustering.md b/docs/src/main/resources/documentation/guide/clustering.md index a4ff6d383..a90cb7150 100644 --- a/docs/src/main/resources/documentation/guide/clustering.md +++ b/docs/src/main/resources/documentation/guide/clustering.md @@ -18,15 +18,14 @@ _hawkBit_ is able to run in a cluster with some constraints. This guide provides Event communication between nodes is based on [Spring Cloud Bus](https://cloud.spring.io/spring-cloud-bus/) and [Spring Cloud Stream](http://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/). There are different [binder implementations](http://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/#_binders) available. The _hawkbit example app_ uses RabbitMQ binder. Every node gets his own queue to receive cluster events, the default payload is JSON. If an event is thrown locally at one node, it will be automatically delivered to all other available nodes via the Spring Cloud Bus's topic exchange: -[[images/eventing-within-cluster.png]] +![](../images/eventing-within-cluster.png){:width="100%"} Via the ServiceMatcher you can check whether an event happened locally at one node or on a different node. `serviceMatcher.isFromSelf(event)` # Caching -Every node is maintaining its own caches independent from other nodes. So there is no globally shared/synchronized cache instance within the cluster. In order to keep nodes in sync a TTL (time to live) can be set for all caches to ensure that after some time the cache is refreshed from the database. To enable the TTL just set the property "hawkbit.cache.global.ttl" (value in milliseconds). -Of course you can implement a shared cache, e.g. Redis. +Every node is maintaining its own caches independent from other nodes. So there is no globally shared/synchronized cache instance within the cluster. In order to keep nodes in sync a TTL (time to live) can be set for all caches to ensure that after some time the cache is refreshed from the database. To enable the TTL just set the property "hawkbit.cache.global.ttl" (value in milliseconds). Of course you can implement a shared cache, e.g. Redis. See [CacheAutoConfiguration](https://github.com/eclipse/hawkbit/blob/master/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/cache/CacheAutoConfiguration.java) # Schedulers diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 556be5fcc..6e6368732 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -213,12 +213,12 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @Override protected void starting(final Description description) { LOG.info("Starting Test {}...", description.getMethodName()); - }; + } @Override protected void succeeded(final Description description) { LOG.info("Test {} succeeded.", description.getMethodName()); - }; + } @Override protected void failed(final Throwable e, final Description description) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java index 8b1c58317..04aec943c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/footer/AbstractDeleteActionsLayout.java @@ -172,7 +172,7 @@ public abstract class AbstractDeleteActionsLayout extends VerticalLayout impleme showBulkUploadWindow(); } - protected void setUploadStatusButtonCaption(final Long count) { + protected void setUploadStatusButtonCaption(final int count) { if (bulkUploadStatusButton == null) { return; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java index 77e011a64..d2d865419 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/DeploymentView.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.management; import java.util.Map; +import java.util.concurrent.Executor; import javax.annotation.PostConstruct; @@ -55,6 +56,7 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.vaadin.spring.events.EventBus.UIEventBus; import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; @@ -113,7 +115,7 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW final ManagementViewClientCriterion managementViewClientCriterion, final TagManagement tagManagement, final TargetFilterQueryManagement targetFilterQueryManagement, final SystemManagement systemManagement, final NotificationUnreadButton notificationUnreadButton, - final DeploymentViewMenuItem deploymentViewMenuItem) { + final DeploymentViewMenuItem deploymentViewMenuItem, @Qualifier("uiExecutor") final Executor uiExecutor) { super(eventBus, notificationUnreadButton); this.permChecker = permChecker; this.i18n = i18n; @@ -132,7 +134,7 @@ public class DeploymentView extends AbstractNotificationView implements BrowserW this.targetTableLayout = new TargetTableLayout(eventbus, targetTable, targetManagement, entityFactory, i18n, eventBus, uiNotification, managementUIState, managementViewClientCriterion, deploymentManagement, - uiproperties, permChecker, uiNotification, tagManagement, distributionSetManagement); + uiproperties, permChecker, uiNotification, tagManagement, distributionSetManagement, uiExecutor); this.distributionTagLayout = new DistributionTagLayout(eventbus, managementUIState, i18n, permChecker, eventBus, tagManagement, entityFactory, uiNotification, distFilterParameters, distributionSetManagement, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java index 0ef2635fb..08e3e37f1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java @@ -509,7 +509,6 @@ public class ActionHistoryTable extends TreeTable { final ActionStatusIconMapper mapping = ActionStatusIconMapper.MAPPINGS.get(status); if (mapping == null) { - LOG.error("Unknown status icon mapping"); label.setDescription(""); label.setValue(""); return label; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusIconMapper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusIconMapper.java index e8f75e52c..026cffd95 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusIconMapper.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusIconMapper.java @@ -22,7 +22,7 @@ import com.vaadin.server.FontAwesome; * */ public final class ActionStatusIconMapper { - static final Map MAPPINGS = Maps.newHashMapWithExpectedSize(10); + static final Map MAPPINGS = Maps.newEnumMap(Action.Status.class); static { MAPPINGS.put(Action.Status.FINISHED, new ActionStatusIconMapper("label.finished", diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java index 3fc48940b..3448bd6b3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/DeleteActionsLayout.java @@ -403,8 +403,8 @@ public class DeleteActionsLayout extends AbstractDeleteActionsLayout { @Override protected void restoreBulkUploadStatusCount() { - final Long failedCount = managementUIState.getTargetTableFilters().getBulkUpload().getFailedUploadCount(); - final Long successCount = managementUIState.getTargetTableFilters().getBulkUpload().getSucessfulUploadCount(); + final int failedCount = managementUIState.getTargetTableFilters().getBulkUpload().getFailedUploadCount(); + final int successCount = managementUIState.getTargetTableFilters().getBulkUpload().getSucessfulUploadCount(); if (failedCount != 0 || successCount != 0) { setUploadStatusButtonCaption(failedCount + successCount); enableBulkUploadStatusButton(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/TargetBulkUpload.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/TargetBulkUpload.java index b5e40b16e..ae29476f5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/TargetBulkUpload.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/state/TargetBulkUpload.java @@ -24,9 +24,9 @@ public class TargetBulkUpload implements Serializable { private String description; - private long sucessfulUploadCount; + private int sucessfulUploadCount; - private long failedUploadCount; + private int failedUploadCount; private float progressBarCurrentValue; @@ -96,7 +96,7 @@ public class TargetBulkUpload implements Serializable { /** * @return the sucessfulUploadCount */ - public long getSucessfulUploadCount() { + public int getSucessfulUploadCount() { return sucessfulUploadCount; } @@ -104,14 +104,14 @@ public class TargetBulkUpload implements Serializable { * @param sucessfulUploadCount * the sucessfulUploadCount to set */ - public void setSucessfulUploadCount(final long sucessfulUploadCount) { + public void setSucessfulUploadCount(final int sucessfulUploadCount) { this.sucessfulUploadCount = sucessfulUploadCount; } /** * @return the failedUploadCount */ - public long getFailedUploadCount() { + public int getFailedUploadCount() { return failedUploadCount; } @@ -119,7 +119,7 @@ public class TargetBulkUpload implements Serializable { * @param failedUploadCount * the failedUploadCount to set */ - public void setFailedUploadCount(final long failedUploadCount) { + public void setFailedUploadCount(final int failedUploadCount) { this.failedUploadCount = failedUploadCount; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 106c00883..720c36445 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.management.targettable; -import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -16,7 +15,10 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.LineNumberReader; import java.io.OutputStream; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Date; @@ -29,9 +31,8 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.model.Action.ActionType; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.common.tagdetails.AbstractTagToken.TagData; import org.eclipse.hawkbit.ui.components.HawkbitErrorNotificationMessage; import org.eclipse.hawkbit.ui.management.event.BulkUploadValidationMessageEvent; @@ -42,11 +43,14 @@ import org.eclipse.hawkbit.ui.management.state.TargetBulkUpload; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vaadin.spring.events.EventBus; +import com.google.common.base.Splitter; +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; +import com.google.common.io.LineProcessor; import com.vaadin.server.Page; import com.vaadin.ui.Alignment; import com.vaadin.ui.ComboBox; @@ -74,6 +78,8 @@ public class BulkUploadHandler extends CustomComponent private static final long serialVersionUID = -1273494705754674501L; private static final Logger LOG = LoggerFactory.getLogger(BulkUploadHandler.class); + private static final Splitter SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults(); + private final transient TargetManagement targetManagement; private final transient TagManagement tagManagement; @@ -91,18 +97,19 @@ public class BulkUploadHandler extends CustomComponent private final TargetBulkTokenTags targetBulkTokenTags; private final Label targetsCountLabel; - private long failedTargetCount; - private long successfullTargetCount; + private int successfullTargetCount; - private final transient Executor executor; + private final transient Executor uiExecutor; private final transient EventBus.UIEventBus eventBus; - private transient EntityFactory entityFactory; + private final transient EntityFactory entityFactory; private final UI uiInstance; - public BulkUploadHandler(final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout, - final TargetManagement targetManagement, final ManagementUIState managementUIState, - final DeploymentManagement deploymentManagement, final I18N i18n, final UI uiInstance) { + BulkUploadHandler(final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout, + final TargetManagement targetManagement, final TagManagement tagManagement, + final EntityFactory entityFactory, final DistributionSetManagement distributionSetManagement, + final ManagementUIState managementUIState, final DeploymentManagement deploymentManagement, final I18N i18n, + final UI uiInstance, final Executor uiExecutor) { this.uiInstance = uiInstance; this.comboBox = targetBulkUpdateWindowLayout.getDsNamecomboBox(); this.descTextArea = targetBulkUpdateWindowLayout.getDescTextArea(); @@ -113,11 +120,11 @@ public class BulkUploadHandler extends CustomComponent this.targetsCountLabel = targetBulkUpdateWindowLayout.getTargetsCountLabel(); this.targetBulkTokenTags = targetBulkUpdateWindowLayout.getTargetBulkTokenTags(); this.i18n = i18n; - executor = (Executor) SpringContextHelper.getBean("uiExecutor"); + this.uiExecutor = uiExecutor; this.eventBus = targetBulkUpdateWindowLayout.getEventBus(); - distributionSetManagement = SpringContextHelper.getBean(DistributionSetManagement.class); - tagManagement = SpringContextHelper.getBean(TagManagement.class); - entityFactory = SpringContextHelper.getBean(EntityFactory.class); + this.distributionSetManagement = distributionSetManagement; + this.tagManagement = tagManagement; + this.entityFactory = entityFactory; } void buildLayout() { @@ -148,7 +155,7 @@ public class BulkUploadHandler extends CustomComponent } catch (final IOException e) { LOG.error("Error while reading file {}", filename, e); } - return new NullOutputStream(); + return ByteStreams.nullOutputStream(); } @Override @@ -158,7 +165,7 @@ public class BulkUploadHandler extends CustomComponent @Override public void uploadSucceeded(final SucceededEvent event) { - executor.execute(new UploadAsync()); + uiExecutor.execute(new UploadAsync()); } class UploadAsync implements Runnable { @@ -179,11 +186,10 @@ public class BulkUploadHandler extends CustomComponent private void readFileStream(final InputStream tempStream) { String line; - final long totalNumberOfLines = getTotalNumberOfLines(); - try (final BufferedReader reader = new BufferedReader( + final BigDecimal totalNumberOfLines = getTotalNumberOfLines(); + try (final LineNumberReader reader = new LineNumberReader( new InputStreamReader(tempStream, Charset.defaultCharset()))) { LOG.info("Bulk file upload started"); - long innerCounter = 0; /** * Once control is in upload succeeded method automatically @@ -191,9 +197,9 @@ public class BulkUploadHandler extends CustomComponent * below event. */ eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_PROCESS_STARTED)); + while ((line = reader.readLine()) != null) { - innerCounter++; - readEachLine(line, innerCounter, totalNumberOfLines); + readLine(line, reader.getLineNumber(), totalNumberOfLines); } } catch (final IOException e) { @@ -203,46 +209,48 @@ public class BulkUploadHandler extends CustomComponent } finally { deleteFile(); } - syncCountAfterUpload(totalNumberOfLines); + syncCountAfterUpload(totalNumberOfLines.intValue()); doAssignments(); eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_COMPLETED)); // Clearing after assignments are done managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().clear(); - resetCounts(); + resetSuccessfullTargetCount(); } - private void syncCountAfterUpload(final long totalNumberOfLines) { - if ((successfullTargetCount + failedTargetCount) != totalNumberOfLines) { - // something went wrong due to runtimeexception etc. - final long syncedFailedTargetCount = totalNumberOfLines - successfullTargetCount; - managementUIState.getTargetTableFilters().getBulkUpload() - .setSucessfulUploadCount(successfullTargetCount); - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_CREATED)); - managementUIState.getTargetTableFilters().getBulkUpload().setFailedUploadCount(syncedFailedTargetCount); - managementUIState.getTargetTableFilters().getBulkUpload().setProgressBarCurrentValue(1); - } + private void syncCountAfterUpload(final int totalNumberOfLines) { + final int syncedFailedTargetCount = totalNumberOfLines - successfullTargetCount; + managementUIState.getTargetTableFilters().getBulkUpload().setSucessfulUploadCount(successfullTargetCount); + managementUIState.getTargetTableFilters().getBulkUpload().setFailedUploadCount(syncedFailedTargetCount); + managementUIState.getTargetTableFilters().getBulkUpload().setProgressBarCurrentValue(1); + eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_CREATED)); } - private long getTotalNumberOfLines() { + private BigDecimal getTotalNumberOfLines() { + try { + return new BigDecimal(Files.readLines(tempFile, Charset.defaultCharset(), new LineProcessor() { + private int count; + + @Override + public Integer getResult() { + return count; + } + + @Override + public boolean processLine(final String line) { + count++; + return true; + } + })); - long totalFileSize = 0; - try (InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(tempFile), - Charset.defaultCharset())) { - try (BufferedReader readerForSize = new BufferedReader(inputStreamReader)) { - totalFileSize = readerForSize.lines().count(); - } - } catch (final FileNotFoundException e) { - LOG.error("Error reading file {}", tempFile.getName(), e); } catch (final IOException e) { - LOG.error("Error while closing reader of file {}", tempFile.getName(), e); + LOG.error("Error while reading temp file for upload.", e); } - return totalFileSize; + return new BigDecimal(0); } - private void resetCounts() { + private void resetSuccessfullTargetCount() { successfullTargetCount = 0; - failedTargetCount = 0; } private void deleteFile() { @@ -255,25 +263,22 @@ public class BulkUploadHandler extends CustomComponent tempFile = null; } - private void readEachLine(final String line, final long innerCounter, final long totalNumberOfLines) { - final String csvDelimiter = ","; - final String[] targets = line.split(csvDelimiter); - if (targets.length == 2) { - final String controllerId = targets[0]; - final String targetName = targets[1]; + private void readLine(final String line, final int lineNumber, final BigDecimal totalNumberOfLines) { + final List targets = SPLITTER.splitToList(line); + if (targets.size() == 2) { + final String controllerId = targets.get(0); + final String targetName = targets.get(1); addNewTarget(controllerId, targetName); - } else { - failedTargetCount++; } - final float current = managementUIState.getTargetTableFilters().getBulkUpload() + + final float previous = managementUIState.getTargetTableFilters().getBulkUpload() .getProgressBarCurrentValue(); - final float next = innerCounter / totalNumberOfLines; - if (Math.abs(next - 0.1) < 0.00001 || current - next >= 0 || next - current >= 0.05 - || Math.abs(next - 1) < 0.00001) { - managementUIState.getTargetTableFilters().getBulkUpload().setProgressBarCurrentValue(next); + final float done = new BigDecimal(lineNumber).divide(totalNumberOfLines, 2, RoundingMode.UP).floatValue(); + + if (done > previous) { managementUIState.getTargetTableFilters().getBulkUpload() .setSucessfulUploadCount(successfullTargetCount); - managementUIState.getTargetTableFilters().getBulkUpload().setFailedUploadCount(failedTargetCount); + managementUIState.getTargetTableFilters().getBulkUpload().setProgressBarCurrentValue(done); eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_CREATED)); } } @@ -332,25 +337,14 @@ public class BulkUploadHandler extends CustomComponent return targetBulkTokenTags.getTokenField().getValue() != null; } - /** - * @return - */ private boolean ifDsSelected() { return comboBox.getValue() != null; } - /** - * @return - */ private boolean ifTargetsCreatedSuccessfully() { return !managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().isEmpty(); } - /** - * @param errorMessage - * @param dsAssignmentFailedMsg - * @param tagAssignmentFailedMsg - */ private void displayValidationMessage(final StringBuilder errorMessage, final String dsAssignmentFailedMsg, final String tagAssignmentFailedMsg) { if (dsAssignmentFailedMsg != null) { @@ -367,53 +361,22 @@ public class BulkUploadHandler extends CustomComponent } } + // Exception squid:S1166 - Targets that exist already are simply ignored + @SuppressWarnings("squid:S1166") private void addNewTarget(final String controllerId, final String name) { final String newControllerId = HawkbitCommonUtil.trimAndNullIfEmpty(controllerId); - if (mandatoryCheck(newControllerId) && duplicateCheck(newControllerId)) { - final String newName = HawkbitCommonUtil.trimAndNullIfEmpty(name); - final String newDesc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); + final String description = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); - final Target newTarget = targetManagement.createTarget(entityFactory.target().create() - .controllerId(newControllerId).name(newName).description(newDesc)); - - eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.ADD_ENTITY, newTarget)); + try { + targetManagement.createTarget(entityFactory.target().create().controllerId(newControllerId).name(name) + .description(description)); managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().add(newControllerId); successfullTargetCount++; + + } catch (final EntityAlreadyExistsException ex) { + // Targets that exist already are simply ignored } - - } - } - - private boolean mandatoryCheck(final String newControlllerId) { - if (newControlllerId == null) { - failedTargetCount++; - return false; - } else { - return true; - } - } - - private boolean duplicateCheck(final String newControlllerId) { - final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim()); - if (existingTarget != null) { - failedTargetCount++; - return false; - } else { - return true; - } - } - - private static class NullOutputStream extends OutputStream { - /** - * null output stream. - * - * @param i - * byte - */ - @Override - public void write(final int i) throws IOException { - // do nothing } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index 7ea9edcba..c554abfcd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -8,12 +8,13 @@ */ package org.eclipse.hawkbit.ui.management.targettable; -import java.util.ArrayList; -import java.util.List; import java.util.Map; +import java.util.concurrent.Executor; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DeploymentManagement; +import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.ui.SpPermissionChecker; @@ -64,6 +65,12 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { private final I18N i18n; private final transient TargetManagement targetManagement; + private final transient DistributionSetManagement distributionSetManagement; + private final transient TagManagement tagManagement; + + private final transient EntityFactory entityFactory; + + private final transient Executor uiExecutor; private final transient EventBus.UIEventBus eventBus; @@ -92,7 +99,8 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { TargetBulkUpdateWindowLayout(final I18N i18n, final TargetManagement targetManagement, final UIEventBus eventBus, final ManagementUIState managementUIState, final DeploymentManagement deploymentManagement, final UiProperties uiproperties, final SpPermissionChecker checker, final UINotification uinotification, - final TagManagement tagManagement) { + final TagManagement tagManagement, final DistributionSetManagement distributionSetManagement, + final EntityFactory entityFactory, final Executor uiExecutor) { this.i18n = i18n; this.targetManagement = targetManagement; this.eventBus = eventBus; @@ -101,6 +109,10 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { this.managementUIState = managementUIState; this.deploymentManagement = deploymentManagement; this.uiproperties = uiproperties; + this.tagManagement = tagManagement; + this.distributionSetManagement = distributionSetManagement; + this.entityFactory = entityFactory; + this.uiExecutor = uiExecutor; createRequiredComponents(); buildLayout(); @@ -113,8 +125,8 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { targetBulkUpload.setDsNameAndVersion((Long) dsNamecomboBox.getValue()); targetBulkUpload.setDescription(descTextArea.getValue()); targetBulkUpload.setProgressBarCurrentValue(0F); - targetBulkUpload.setFailedUploadCount(0L); - targetBulkUpload.setSucessfulUploadCount(0L); + targetBulkUpload.setFailedUploadCount(0); + targetBulkUpload.setSucessfulUploadCount(0); closeButton.setEnabled(false); minimizeButton.setEnabled(true); } @@ -163,8 +175,9 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { } private BulkUploadHandler getBulkUploadHandler() { - final BulkUploadHandler bulkUploadHandler = new BulkUploadHandler(this, targetManagement, managementUIState, - deploymentManagement, i18n, UI.getCurrent()); + final BulkUploadHandler bulkUploadHandler = new BulkUploadHandler(this, targetManagement, tagManagement, + entityFactory, distributionSetManagement, managementUIState, deploymentManagement, i18n, + UI.getCurrent(), uiExecutor); bulkUploadHandler.buildLayout(); bulkUploadHandler.addStyleName(SPUIStyleDefinitions.BULK_UPLOAD_BUTTON); return bulkUploadHandler; @@ -231,14 +244,11 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { final Map queryConfiguration = Maps.newHashMapWithExpectedSize(2); - final List list = new ArrayList<>(); queryConfiguration.put(SPUIDefinitions.FILTER_BY_NO_TAG, managementUIState.getDistributionTableFilters().isNoTagSelected()); - if (!managementUIState.getDistributionTableFilters().getDistSetTags().isEmpty()) { - list.addAll(managementUIState.getDistributionTableFilters().getDistSetTags()); - } - queryConfiguration.put(SPUIDefinitions.FILTER_BY_TAG, list); + queryConfiguration.put(SPUIDefinitions.FILTER_BY_TAG, + managementUIState.getDistributionTableFilters().getDistSetTags()); final BeanQueryFactory distributionQF = new BeanQueryFactory<>( DistributionBeanQuery.class); @@ -287,8 +297,8 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { final TargetBulkUpload targetBulkUpload = managementUIState.getTargetTableFilters().getBulkUpload(); targetBulkUpload.setDescription(null); targetBulkUpload.setDsNameAndVersion(null); - targetBulkUpload.setFailedUploadCount(0L); - targetBulkUpload.setSucessfulUploadCount(0L); + targetBulkUpload.setFailedUploadCount(0); + targetBulkUpload.setSucessfulUploadCount(0); targetBulkUpload.getAssignedTagNames().clear(); targetBulkUpload.getTargetsCreated().clear(); } @@ -303,14 +313,12 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { dsNamecomboBox.setValue(targetBulkUpload.getDsNameAndVersion()); descTextArea.setValue(targetBulkUpload.getDescription()); targetBulkTokenTags.addAlreadySelectedTags(); - if (targetBulkUpload.getSucessfulUploadCount() > 0 || targetBulkUpload.getFailedUploadCount() > 0) { + + if (targetBulkUpload.getProgressBarCurrentValue() >= 1) { targetsCountLabel.setVisible(true); targetsCountLabel.setCaption(getFormattedCountLabelValue(targetBulkUpload.getSucessfulUploadCount(), targetBulkUpload.getFailedUploadCount())); } - if (targetBulkUpload.getProgressBarCurrentValue() < 1) { - bulkUploader.getUpload().setEnabled(false); - } } /** @@ -324,13 +332,11 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { getTargetsCountLabel().setVisible(true); getTargetsCountLabel().setCaption(targetCountLabel); - getBulkUploader().getUpload().setEnabled(true); - closeButton.setEnabled(true); minimizeButton.setEnabled(false); } - private static String getFormattedCountLabelValue(final long succussfulUploadCount, final long failedUploadCount) { + private static String getFormattedCountLabelValue(final int succussfulUploadCount, final int failedUploadCount) { return new StringBuilder().append("Successful :").append(succussfulUploadCount) .append(" Failed :").append(failedUploadCount).append("").toString(); } @@ -347,18 +353,14 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { .buildWindow(); bulkUploadWindow.addStyleName("bulk-upload-window"); bulkUploadWindow.setImmediate(true); - if (isNoBulkUploadInProgress()) { + if (managementUIState.getTargetTableFilters().getBulkUpload().getProgressBarCurrentValue() <= 0) { bulkUploader.getUpload().setEnabled(true); + } else { + bulkUploader.getUpload().setEnabled(false); } return bulkUploadWindow; } - private boolean isNoBulkUploadInProgress() { - final float progressBarCurrentValue = managementUIState.getTargetTableFilters().getBulkUpload() - .getProgressBarCurrentValue(); - return Math.abs(progressBarCurrentValue - 0) < 0.00001 || Math.abs(progressBarCurrentValue - 1) < 0.00001; - } - private void minimizeWindow() { bulkUploadWindow.close(); managementUIState.setBulkUploadWindowMinimised(true); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java index 9b99d921c..eaf6f094c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.management.targettable; import java.util.Set; +import java.util.concurrent.Executor; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -79,14 +80,16 @@ public class TargetTableHeader extends AbstractTableHeader { final UINotification notification, final ManagementUIState managementUIState, final ManagementViewClientCriterion managementViewClientCriterion, final TargetManagement targetManagement, final DeploymentManagement deploymentManagement, final UiProperties uiproperties, final UIEventBus eventBus, - final EntityFactory entityFactory, final UINotification uinotification, final TagManagement tagManagement, DistributionSetManagement distributionSetManagement) { + final EntityFactory entityFactory, final UINotification uinotification, final TagManagement tagManagement, + final DistributionSetManagement distributionSetManagement, final Executor uiExecutor) { super(i18n, permChecker, eventbus, managementUIState, null, null); this.notification = notification; this.managementViewClientCriterion = managementViewClientCriterion; this.targetAddUpdateWindow = new TargetAddUpdateWindowLayout(i18n, targetManagement, eventBus, uinotification, entityFactory); this.targetBulkUpdateWindow = new TargetBulkUpdateWindowLayout(i18n, targetManagement, eventBus, - managementUIState, deploymentManagement, uiproperties, permChecker, uinotification, tagManagement); + managementUIState, deploymentManagement, uiproperties, permChecker, uinotification, tagManagement, + distributionSetManagement, entityFactory, uiExecutor); this.distributionSetManagement = distributionSetManagement; onLoadRestoreState(); } @@ -336,12 +339,13 @@ public class TargetTableHeader extends AbstractTableHeader { return; } final Long distributionSetId = distributionIdSet.iterator().next(); - DistributionSet distributionSet =distributionSetManagement.findDistributionSetById(distributionSetId); - if(distributionSet == null){ + final DistributionSet distributionSet = distributionSetManagement + .findDistributionSetById(distributionSetId); + if (distributionSet == null) { notification.displayWarning(i18n.get("distributionset.not.exists")); return; } - DistributionSetIdName distributionSetIdName = new DistributionSetIdName(distributionSet); + final DistributionSetIdName distributionSetIdName = new DistributionSetIdName(distributionSet); managementUIState.getTargetTableFilters().setDistributionSet(distributionSetIdName); addFilterTextField(distributionSetIdName); } @@ -376,10 +380,9 @@ public class TargetTableHeader extends AbstractTableHeader { return isValid; } - private static Set getDropppedDistributionDetails(final TableTransferable transferable) { + private static Set getDropppedDistributionDetails(final TableTransferable transferable) { @SuppressWarnings("unchecked") - final AbstractTable distTable = (AbstractTable) transferable - .getSourceComponent(); + final AbstractTable distTable = (AbstractTable) transferable.getSourceComponent(); return distTable.getDeletedEntityByTransferable(transferable); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java index bb8f54628..fee6a755e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.management.targettable; +import java.util.concurrent.Executor; + import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; @@ -44,13 +46,14 @@ public class TargetTableLayout extends AbstractTableLayout { final ManagementViewClientCriterion managementViewClientCriterion, final DeploymentManagement deploymentManagement, final UiProperties uiproperties, final SpPermissionChecker permissionChecker, final UINotification uinotification, - final TagManagement tagManagement, final DistributionSetManagement distributionSetManagement) { + final TagManagement tagManagement, final DistributionSetManagement distributionSetManagement, + final Executor uiExecutor) { this.eventBus = eventBus; this.targetDetails = new TargetDetails(i18n, eventbus, permissionChecker, managementUIState, uinotification, tagManagement, targetManagement, entityFactory); this.targetTableHeader = new TargetTableHeader(i18n, permissionChecker, eventBus, notification, managementUIState, managementViewClientCriterion, targetManagement, deploymentManagement, uiproperties, - eventbus, entityFactory, uinotification, tagManagement, distributionSetManagement); + eventbus, entityFactory, uinotification, tagManagement, distributionSetManagement, uiExecutor); super.init(targetTableHeader, targetTable, targetDetails); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/groupschart/client/GroupsPieChartWidget.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/groupschart/client/GroupsPieChartWidget.java index 9b8ac153c..175ce0aa6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/groupschart/client/GroupsPieChartWidget.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/groupschart/client/GroupsPieChartWidget.java @@ -29,7 +29,8 @@ import java.util.List; * unassigned targets will be displayed. * */ -@SuppressWarnings("squid:TrailingCommentCheck") +// Exception squid - non Java 8 compatible GWT code that runs on browser +@SuppressWarnings({ "squid:TrailingCommentCheck", "squid:S1604" }) public class GroupsPieChartWidget extends DockLayoutPanel { private static final String ATTR_VISIBILITY = "visibility"; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java index 12e50ef87..ea8e59cd6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.utils; -import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.TimeZone; @@ -19,7 +18,6 @@ import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.PollStatus; import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; import org.eclipse.hawkbit.ui.rollout.StatusFontIcon; import org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; @@ -506,35 +504,6 @@ public final class HawkbitCommonUtil { return String.format("%.1f", tmpFinishedPercentage); } - /** - * Reset the values of status progress bar on change of values. - * - * @param bar - * DistributionBar - * @param item - * row of the table - */ - private static void setProgressBarDetails(final DistributionBar bar, final Item item) { - bar.setNumberOfParts(6); - final Long notStartedTargetsCount = getStatusCount(SPUILabelDefinitions.VAR_COUNT_TARGETS_NOT_STARTED, item); - HawkbitCommonUtil.setBarPartSize(bar, TotalTargetCountStatus.Status.NOTSTARTED.toString().toLowerCase(), - notStartedTargetsCount.intValue(), 0); - HawkbitCommonUtil.setBarPartSize(bar, TotalTargetCountStatus.Status.SCHEDULED.toString().toLowerCase(), - getStatusCount(SPUILabelDefinitions.VAR_COUNT_TARGETS_SCHEDULED, item).intValue(), 1); - HawkbitCommonUtil.setBarPartSize(bar, TotalTargetCountStatus.Status.RUNNING.toString().toLowerCase(), - getStatusCount(SPUILabelDefinitions.VAR_COUNT_TARGETS_RUNNING, item).intValue(), 2); - HawkbitCommonUtil.setBarPartSize(bar, TotalTargetCountStatus.Status.ERROR.toString().toLowerCase(), - getStatusCount(SPUILabelDefinitions.VAR_COUNT_TARGETS_ERROR, item).intValue(), 3); - HawkbitCommonUtil.setBarPartSize(bar, TotalTargetCountStatus.Status.FINISHED.toString().toLowerCase(), - getStatusCount(SPUILabelDefinitions.VAR_COUNT_TARGETS_FINISHED, item).intValue(), 4); - HawkbitCommonUtil.setBarPartSize(bar, TotalTargetCountStatus.Status.CANCELLED.toString().toLowerCase(), - getStatusCount(SPUILabelDefinitions.VAR_COUNT_TARGETS_CANCELLED, item).intValue(), 5); - } - - private static boolean isNoTargets(final Long... statusCount) { - return (Arrays.asList(statusCount).stream().filter(value -> value > 0).toArray().length) == 0; - } - private static Long getStatusCount(final String propertName, final Item item) { return (Long) item.getItemProperty(propertName).getValue(); }