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:
committed by
Stefan Behl
parent
dba972423b
commit
8687510131
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Copyright (c) 2019 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.mgmt.rest.resource;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMaintenanceWindowRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtDistributionSetAssignment;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper;
|
||||
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
||||
import org.eclipse.hawkbit.repository.model.DeploymentRequestBuilder;
|
||||
|
||||
/**
|
||||
* A mapper for assignment requests
|
||||
*/
|
||||
public final class MgmtDeploymentRequestMapper {
|
||||
private MgmtDeploymentRequestMapper() {
|
||||
// Utility class
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert assignment information to an {@link DeploymentRequest}
|
||||
*
|
||||
* @param dsAssignment
|
||||
* DS assignment information
|
||||
* @param targetId
|
||||
* target to assign the DS to
|
||||
* @return resulting {@link DeploymentRequest}
|
||||
*/
|
||||
public static DeploymentRequest createAssignmentRequest(final MgmtDistributionSetAssignment dsAssignment,
|
||||
final String targetId) {
|
||||
|
||||
return createAssignmentRequest(targetId, dsAssignment.getId(), dsAssignment.getType(),
|
||||
dsAssignment.getForcetime(), dsAssignment.getMaintenanceWindow());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert assignment information to an {@link DeploymentRequest}
|
||||
*
|
||||
* @param targetAssignment
|
||||
* target assignment information
|
||||
* @param dsId
|
||||
* DS to assign the target to
|
||||
* @return resulting {@link DeploymentRequest}
|
||||
*/
|
||||
public static DeploymentRequest createAssignmentRequest(final MgmtTargetAssignmentRequestBody targetAssignment,
|
||||
final Long dsId) {
|
||||
|
||||
return createAssignmentRequest(targetAssignment.getId(), dsId, targetAssignment.getType(),
|
||||
targetAssignment.getForcetime(), targetAssignment.getMaintenanceWindow());
|
||||
}
|
||||
|
||||
private static DeploymentRequest createAssignmentRequest(final String targetId, final Long dsId,
|
||||
final MgmtActionType type, final long forcetime, final MgmtMaintenanceWindowRequestBody maintenanceWindow) {
|
||||
final DeploymentRequestBuilder request = DeploymentManagement.deploymentRequest(targetId, dsId)
|
||||
.setActionType(MgmtRestModelMapper.convertActionType(type)).setForceTime(forcetime);
|
||||
if (maintenanceWindow != null) {
|
||||
final String cronSchedule = maintenanceWindow.getSchedule();
|
||||
final String duration = maintenanceWindow.getDuration();
|
||||
final String timezone = maintenanceWindow.getTimezone();
|
||||
MaintenanceScheduleHelper.validateMaintenanceSchedule(cronSchedule, duration, timezone);
|
||||
request.setMaintenance(cronSchedule, duration, timezone);
|
||||
}
|
||||
return request.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -144,6 +144,20 @@ public final class MgmtDistributionSetMapper {
|
||||
return result;
|
||||
}
|
||||
|
||||
static MgmtTargetAssignmentResponseBody toResponse(
|
||||
final List<DistributionSetAssignmentResult> dsAssignmentResults) {
|
||||
final MgmtTargetAssignmentResponseBody result = new MgmtTargetAssignmentResponseBody();
|
||||
final int alreadyAssigned = dsAssignmentResults.stream()
|
||||
.mapToInt(DistributionSetAssignmentResult::getAlreadyAssigned).sum();
|
||||
final List<MgmtActionId> assignedActions = dsAssignmentResults.stream()
|
||||
.flatMap(assignmentResult -> assignmentResult.getAssignedEntity().stream())
|
||||
.map(action -> new MgmtActionId(action.getTarget().getControllerId(), action.getId()))
|
||||
.collect(Collectors.toList());
|
||||
result.setAlreadyAssigned(alreadyAssigned);
|
||||
result.setAssignedActions(assignedActions);
|
||||
return result;
|
||||
}
|
||||
|
||||
static List<MgmtDistributionSet> toResponseDistributionSets(final Collection<DistributionSet> sets) {
|
||||
if (sets == null) {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMaintenanceWindowRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadataBodyPut;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||
@@ -30,20 +31,19 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper;
|
||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||
import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
|
||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -250,33 +250,22 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
||||
@PathVariable("distributionSetId") final Long distributionSetId,
|
||||
@RequestBody final List<MgmtTargetAssignmentRequestBody> assignments,
|
||||
@RequestParam(value = "offline", required = false) final boolean offline) {
|
||||
|
||||
if (offline) {
|
||||
return ResponseEntity.ok(MgmtDistributionSetMapper
|
||||
.toResponse(this.deployManagament.offlineAssignedDistributionSet(distributionSetId, assignments
|
||||
.stream().map(MgmtTargetAssignmentRequestBody::getId).collect(Collectors.toList()))));
|
||||
final List<Entry<String, Long>> offlineAssignments = assignments.stream()
|
||||
.map(assignment -> new SimpleEntry<String, Long>(assignment.getId(), distributionSetId))
|
||||
.collect(Collectors.toList());
|
||||
return ResponseEntity
|
||||
.ok(MgmtDistributionSetMapper
|
||||
.toResponse(deployManagament.offlineAssignedDistributionSets(offlineAssignments)));
|
||||
}
|
||||
|
||||
final List<DeploymentRequest> deploymentRequests = assignments.stream()
|
||||
.map(assignment -> MgmtDeploymentRequestMapper.createAssignmentRequest(assignment, distributionSetId))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final DistributionSetAssignmentResult assignDistributionSet = this.deployManagament
|
||||
.assignDistributionSet(distributionSetId, assignments.stream().map(t -> {
|
||||
final MgmtMaintenanceWindowRequestBody maintenanceWindow = t.getMaintenanceWindow();
|
||||
|
||||
if (maintenanceWindow == null) {
|
||||
return new TargetWithActionType(t.getId(), MgmtRestModelMapper.convertActionType(t.getType()),
|
||||
t.getForcetime());
|
||||
}
|
||||
|
||||
final String cronSchedule = maintenanceWindow.getSchedule();
|
||||
final String duration = maintenanceWindow.getDuration();
|
||||
final String timezone = maintenanceWindow.getTimezone();
|
||||
|
||||
MaintenanceScheduleHelper.validateMaintenanceSchedule(cronSchedule, duration, timezone);
|
||||
|
||||
return new TargetWithActionType(t.getId(), MgmtRestModelMapper.convertActionType(t.getType()),
|
||||
t.getForcetime(), cronSchedule, duration, timezone);
|
||||
}).collect(Collectors.toList()));
|
||||
|
||||
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(assignDistributionSet));
|
||||
final List<DistributionSetAssignmentResult> assignmentResults = deployManagament
|
||||
.assignDistributionSets(deploymentRequests);
|
||||
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(assignmentResults));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,14 +8,16 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.rest.resource;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.ValidationException;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMaintenanceWindowRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadataBodyPut;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||
@@ -25,7 +27,7 @@ import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionStatus;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentResponseBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtDistributionSetAssignment;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtDistributionSetAssignments;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetAttributes;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetRequestBody;
|
||||
@@ -33,15 +35,15 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetRestApi;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.MaintenanceScheduleHelper;
|
||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetMetadata;
|
||||
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -281,36 +283,25 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtTargetAssignmentResponseBody> postAssignedDistributionSet(
|
||||
@PathVariable("targetId") final String targetId, @RequestBody final MgmtDistributionSetAssignment dsId,
|
||||
@PathVariable("targetId") final String targetId,
|
||||
@Valid @RequestBody final MgmtDistributionSetAssignments dsAssignments,
|
||||
@RequestParam(value = "offline", required = false) final boolean offline) {
|
||||
|
||||
if (offline) {
|
||||
final List<Entry<String, Long>> offlineAssignments = dsAssignments.stream()
|
||||
.map(dsAssignment -> new SimpleEntry<String, Long>(targetId, dsAssignment.getId()))
|
||||
.collect(Collectors.toList());
|
||||
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(
|
||||
deploymentManagement.offlineAssignedDistributionSet(dsId.getId(),
|
||||
Collections.singletonList(targetId))));
|
||||
deploymentManagement.offlineAssignedDistributionSets(offlineAssignments)));
|
||||
}
|
||||
|
||||
findTargetWithExceptionIfNotFound(targetId);
|
||||
final MgmtMaintenanceWindowRequestBody maintenanceWindow = dsId.getMaintenanceWindow();
|
||||
|
||||
if (maintenanceWindow == null) {
|
||||
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(this.deploymentManagement
|
||||
.assignDistributionSet(dsId.getId(), Collections.singletonList(new TargetWithActionType(targetId,
|
||||
MgmtRestModelMapper.convertActionType(dsId.getType()), dsId.getForcetime())))));
|
||||
}
|
||||
|
||||
final String cronSchedule = maintenanceWindow.getSchedule();
|
||||
final String duration = maintenanceWindow.getDuration();
|
||||
final String timezone = maintenanceWindow.getTimezone();
|
||||
|
||||
MaintenanceScheduleHelper.validateMaintenanceSchedule(cronSchedule, duration, timezone);
|
||||
|
||||
return ResponseEntity
|
||||
.ok(MgmtDistributionSetMapper.toResponse(this.deploymentManagement.assignDistributionSet(dsId.getId(),
|
||||
Collections.singletonList(new TargetWithActionType(targetId,
|
||||
MgmtRestModelMapper.convertActionType(dsId.getType()), dsId.getForcetime(),
|
||||
cronSchedule, duration, timezone)))));
|
||||
final List<DeploymentRequest> deploymentRequests = dsAssignments.stream()
|
||||
.map(dsAssignment -> MgmtDeploymentRequestMapper.createAssignmentRequest(dsAssignment, targetId))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final List<DistributionSetAssignmentResult> assignmentResults = deploymentManagement
|
||||
.assignDistributionSets(deploymentRequests);
|
||||
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(assignmentResults));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user