Mgmt/actions confirm (#2271)
* Extend MGMT API to be possible to confirm/deny Actions on Targets as Operators. * Added tests * Fixed permissions in api doc * added missing license header --------- Co-authored-by: vasilchev <vasil.ilchev@bosch.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Contributors to the Eclipse Foundation
|
||||
*
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.hawkbit.mgmt.json.model.action;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* New update actions require confirmation when confirmation flow is switched on.
|
||||
* The confirmation message has a mandatory field confirmation with possible values: "confirmed" and "denied".
|
||||
*/
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class MgmtActionConfirmationRequestBodyPut {
|
||||
|
||||
@NotNull
|
||||
@Valid
|
||||
@Schema(description = "Action confirmation state")
|
||||
private final Confirmation confirmation;
|
||||
|
||||
@Schema(description = "(Optional) Individual status code", example = "200")
|
||||
private final Integer code;
|
||||
|
||||
@Schema(description = "List of detailed message information", example = "[ \"Feedback message\" ]")
|
||||
private final List<String> details;
|
||||
|
||||
/**
|
||||
* Constructs a confirmation-feedback
|
||||
*
|
||||
* @param confirmation confirmation value for the action. Valid values are "Confirmed" and "Denied
|
||||
* @param code code for confirmation
|
||||
* @param details messages
|
||||
*/
|
||||
@JsonCreator
|
||||
public MgmtActionConfirmationRequestBodyPut(
|
||||
@JsonProperty(value = "confirmation", required = true) final Confirmation confirmation,
|
||||
@JsonProperty(value = "code") final Integer code,
|
||||
@JsonProperty(value = "details") final List<String> details) {
|
||||
this.confirmation = confirmation;
|
||||
this.code = code;
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public List<String> getDetails() {
|
||||
if (details == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.unmodifiableList(details);
|
||||
}
|
||||
|
||||
public enum Confirmation {
|
||||
/**
|
||||
* Confirm the action.
|
||||
*/
|
||||
CONFIRMED("confirmed"),
|
||||
|
||||
/**
|
||||
* Deny the action.
|
||||
*/
|
||||
DENIED("denied");
|
||||
|
||||
private final String name;
|
||||
|
||||
Confirmation(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadataBodyPut;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtAction;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionConfirmationRequestBodyPut;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionRequestBodyPut;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionStatus;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||
@@ -504,6 +505,51 @@ public interface MgmtTargetRestApi {
|
||||
@PathVariable("actionId") Long actionId,
|
||||
@RequestBody MgmtActionRequestBodyPut actionUpdate);
|
||||
|
||||
/**
|
||||
* Handles the PUT update request to either 'confirm' or 'deny' single action on a target.
|
||||
|
||||
*/
|
||||
@Operation(summary = "Controls (confirm/deny) actions waiting for confirmation", description = """
|
||||
Either confirm or deny an action which is waiting for confirmation.
|
||||
The action will be transferred into the RUNNING state in case confirming it.
|
||||
The action will remain in WAITING_FOR_CONFIRMATION state in case denying it.
|
||||
Required Permission: READ_REPOSITORY AND UPDATE_TARGET
|
||||
""")
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(responseCode = "200", description = "Successfully updated confirmation status of the action"),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))),
|
||||
@ApiResponse(responseCode = "401", description = "The request requires user authentication.",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||
@ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " +
|
||||
"changed (i.e. read-only) or data volume restriction applies.",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||
@ApiResponse(responseCode = "404", description = "Target or Action not found",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||
@ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||
@ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||
@ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " +
|
||||
"user in another request at the same time. You may retry your modification request.",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||
@ApiResponse(responseCode = "410", description = "Action is not active anymore.",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||
@ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " +
|
||||
"supported by the server for this resource.",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
|
||||
@ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " +
|
||||
"and the client has to wait another second.",
|
||||
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
|
||||
})
|
||||
@PutMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}/confirmation",
|
||||
consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE },
|
||||
produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<Void> updateActionConfirmation(
|
||||
@PathVariable("targetId") String targetId,
|
||||
@PathVariable("actionId") Long actionId,
|
||||
@Valid @RequestBody MgmtActionConfirmationRequestBodyPut actionConfirmation);
|
||||
|
||||
/**
|
||||
* Handles the GET request of retrieving the ActionStatus of a specific target and action.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user