Assign multiple distribution sets to a target via mgmt api (#886)

* Add multiassignment to mgmt api target endpoint
* Remove single assignment ds to targets offline
* Fix tests
* Add quota for maxResultingActionsPerManualAssignment
* Fix assignment with same target or distribution set multiple times in one request
* Log UI error
* Add tests
* Enable single assignment requests with multiple DSs and types
* Remove redundant target to DS assignment methods
* Add tests, fix assignment
* Fix possible nullpointer during target assignment request
* Update api docu
* Clean up deployment management code
* Enforce MaxActions quota for offline assignment
* Fix review findings
* Rename property, add migration into
* Add builder for DeploymentRequest
* Change offline assignment method to accept an assignment list, like online assignment
* Fix PR findings

Signed-off-by: Stefan Klotz <stefan.klotz@bosch-si.com>
This commit is contained in:
Stefan Klotz
2019-09-17 14:20:26 +02:00
committed by Stefan Behl
parent dba972423b
commit 8687510131
50 changed files with 1466 additions and 559 deletions

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.ui.management;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -17,12 +18,14 @@ import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper;
import org.eclipse.hawkbit.repository.exception.InvalidMaintenanceScheduleException;
import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
import org.eclipse.hawkbit.repository.model.DeploymentRequestBuilder;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.eclipse.hawkbit.ui.UiProperties;
import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab;
import org.eclipse.hawkbit.ui.common.entity.TargetIdName;
@@ -80,6 +83,7 @@ public final class TargetAssignmentOperations {
* the Vaadin Message Source for multi language
* @param eventSource
* the source object for sending potential events
* @throws MultiAssignmentIsNotEnabledException
*/
public static void saveAllAssignments(final List<Target> targets, final List<DistributionSet> distributionSets,
final ManagementUIState managementUIState,
@@ -101,31 +105,39 @@ public final class TargetAssignmentOperations {
final String maintenanceTimeZone = maintenanceWindowLayout.getMaintenanceTimeZone();
final Set<Long> dsIds = distributionSets.stream().map(DistributionSet::getId).collect(Collectors.toSet());
final List<TargetWithActionType> trgActionType = targets.stream()
.map(t -> maintenanceWindowLayout.isEnabled()
? new TargetWithActionType(t.getControllerId(), actionType, forcedTimeStamp,
maintenanceSchedule, maintenanceDuration, maintenanceTimeZone)
: new TargetWithActionType(t.getControllerId(), actionType, forcedTimeStamp))
.collect(Collectors.toList());
final List<DeploymentRequest> deploymentRequests = new ArrayList<>();
dsIds.forEach(dsId -> targets.forEach(t -> {
final DeploymentRequestBuilder request = DeploymentManagement.deploymentRequest(t.getControllerId(), dsId)
.setActionType(actionType).setForceTime(forcedTimeStamp);
if (maintenanceWindowLayout.isEnabled()) {
request.setMaintenance(maintenanceSchedule, maintenanceDuration, maintenanceTimeZone);
}
deploymentRequests.add(request.build());
}));
final List<DistributionSetAssignmentResult> results = deploymentManagement.assignDistributionSets(dsIds,
trgActionType);
try {
final List<DistributionSetAssignmentResult> results = deploymentManagement
.assignDistributionSets(deploymentRequests);
// use the last one for the notification box
final DistributionSetAssignmentResult assignmentResult = results.get(results.size() - 1);
if (assignmentResult.getAssigned() > 0) {
notification
.displaySuccess(i18n.getMessage("message.target.assignment", assignmentResult.getAssigned()));
}
if (assignmentResult.getAlreadyAssigned() > 0) {
notification.displaySuccess(
i18n.getMessage("message.target.alreadyAssigned", assignmentResult.getAlreadyAssigned()));
}
// use the last one for the notification box
final DistributionSetAssignmentResult assignmentResult = results.get(results.size() - 1);
if (assignmentResult.getAssigned() > 0) {
notification.displaySuccess(i18n.getMessage("message.target.assignment", assignmentResult.getAssigned()));
final Set<Long> targetIds = targets.stream().map(Target::getId).collect(Collectors.toSet());
refreshPinnedDetails(dsIds, targetIds, managementUIState, eventBus, eventSource);
notification.displaySuccess(i18n.getMessage("message.target.ds.assign.success"));
eventBus.publish(eventSource, SaveActionWindowEvent.SAVED_ASSIGNMENTS);
} catch (final MultiAssignmentIsNotEnabledException e) {
notification.displayValidationError(i18n.getMessage("message.target.ds.multiassign.error"));
LOG.error("UI allowed multiassignment although it is not enabled: {}", e);
}
if (assignmentResult.getAlreadyAssigned() > 0) {
notification.displaySuccess(
i18n.getMessage("message.target.alreadyAssigned", assignmentResult.getAlreadyAssigned()));
}
final Set<Long> targetIds = targets.stream().map(Target::getId).collect(Collectors.toSet());
refreshPinnedDetails(dsIds, targetIds, managementUIState, eventBus, eventSource);
notification.displaySuccess(i18n.getMessage("message.target.ds.assign.success"));
eventBus.publish(eventSource, SaveActionWindowEvent.SAVED_ASSIGNMENTS);
}
private static void refreshPinnedDetails(final Set<Long> dsIds, final Set<Long> targetIds,
@@ -275,4 +287,4 @@ public final class TargetAssignmentOperations {
return SPUIComponentProvider.getHelpLink(i18n, maintenanceWindowHelpUrl);
}
}
}

View File

@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
@@ -32,6 +33,7 @@ import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
import org.eclipse.hawkbit.ui.common.tagdetails.TagData;
import org.eclipse.hawkbit.ui.components.HawkbitErrorNotificationMessage;
import org.eclipse.hawkbit.ui.management.event.BulkUploadValidationMessageEvent;
@@ -300,13 +302,17 @@ public class BulkUploadHandler extends CustomComponent
final ActionType actionType = ActionType.FORCED;
final long forcedTimeStamp = new Date().getTime();
final TargetBulkUpload targetBulkUpload = managementUIState.getTargetTableFilters().getBulkUpload();
final List<String> targetsList = targetBulkUpload.getTargetsCreated();
final List<String> targetIds = targetBulkUpload.getTargetsCreated();
final Long dsSelected = (Long) comboBox.getValue();
if (!distributionSetManagement.get(dsSelected).isPresent()) {
return i18n.getMessage("message.bulk.upload.assignment.failed");
}
deploymentManagement.assignDistributionSet(targetBulkUpload.getDsNameAndVersion(), actionType,
forcedTimeStamp, targetsList);
final List<DeploymentRequest> deploymentRequests = targetIds.stream()
.map(targetId -> DeploymentManagement
.deploymentRequest(targetId, targetBulkUpload.getDsNameAndVersion())
.setActionType(actionType).setForceTime(forcedTimeStamp).build())
.collect(Collectors.toList());
deploymentManagement.assignDistributionSets(deploymentRequests);
return null;
}

View File

@@ -516,6 +516,7 @@ message.dist.type.discard.success = All Distribution Types are discarded success
message.dist.discard.success = All Distributions are discarded successfully !
message.assign.discard.success = All assignments are discarded successfully !
message.target.ds.assign.success = Assignment saved successfully !
message.target.ds.multiassign.error = Cannot assign multiple distribution sets to a target!
message.bulk.upload.assignment.failed = Distribution set assignment failed as distribution set no longer exists!
message.bulk.upload.result.success = Successful: {0}
message.bulk.upload.result.fail = Failed: {0}