Optimize API responses (#2880)

* remove generic 405 - put only where needed
* remove 429 from get/post update where not expected (not quota related in general)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2026-01-22 13:28:04 +02:00
committed by GitHub
parent 9aedbc6813
commit 5d562abd3c
12 changed files with 178 additions and 95 deletions

View File

@@ -13,6 +13,9 @@ import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.DISTRIBUTION_S
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.DeleteResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetIfExistResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.LOCKED_423;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.METHOD_NOT_ALLOWED_405;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.NOT_FOUND_404;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutNoContentResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutResponses;
@@ -323,7 +326,7 @@ public interface MgmtDistributionSetRestApi {
description = "Create a list of meta data entries Required permissions: READ_REPOSITORY and UPDATE_TARGET")
@PostCreateResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Distribution Set not found.",
@ApiResponse(responseCode = NOT_FOUND_404, description = "Distribution Set not found.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/metadata",
@@ -404,6 +407,9 @@ public interface MgmtDistributionSetRestApi {
always be a list of software module IDs. Required permissions: READ_REPOSITORY and UPDATE_REPOSITORY
""")
@PostUpdateNoContentResponses
@ApiResponses(value = {
@ApiResponse(responseCode = LOCKED_423, description = "Software module is locked", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/assignedSM",
consumes = { MediaType.APPLICATION_JSON_VALUE, MediaTypes.HAL_JSON_VALUE },
produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
@@ -421,6 +427,9 @@ public interface MgmtDistributionSetRestApi {
@Operation(summary = "Delete the assignment of the software module from the distribution set",
description = "Delete an assignment. Required permission: UPDATE_REPOSITORY")
@DeleteResponses
@ApiResponses(value = {
@ApiResponse(responseCode = LOCKED_423, description = "Distribution set is locked", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/assignedSM/{softwareModuleId}")
ResponseEntity<Void> deleteAssignSoftwareModules(
@PathVariable("distributionSetId") Long distributionSetId,
@@ -534,6 +543,10 @@ public interface MgmtDistributionSetRestApi {
cancel all actions connected to this distribution set. Required permission: UPDATE_REPOSITORY, UPDATE_TARGET
""")
@PostUpdateNoContentResponses
@ApiResponses(value = {
@ApiResponse(responseCode = METHOD_NOT_ALLOWED_405, description = "Software module is locked", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = LOCKED_423, description = "Distribution set is locked", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/invalidate",
consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE },
produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })

View File

@@ -13,6 +13,7 @@ import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.DISTRIBUTION_S
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.DeleteResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetIfExistResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.NOT_FOUND_404;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateNoContentResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutResponses;
@@ -271,7 +272,7 @@ public interface MgmtDistributionSetTypeRestApi {
"Required Permission: UPDATE_REPOSITORY and READ_REPOSITORY")
@PostCreateNoContentResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Distribution Set Type not found.",
@ApiResponse(responseCode = NOT_FOUND_404, description = "Distribution Set Type not found.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" +
@@ -294,7 +295,7 @@ public interface MgmtDistributionSetTypeRestApi {
"Required Permission: UPDATE_REPOSITORY and READ_REPOSITORY")
@PostCreateNoContentResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Distribution Set Type not found.",
@ApiResponse(responseCode = NOT_FOUND_404, description = "Distribution Set Type not found.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" +

View File

@@ -11,11 +11,16 @@ package org.eclipse.hawkbit.mgmt.rest.api;
import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.DOWNLOAD_ARTIFACT_ORDER;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.INTERNAL_SERVER_ERROR_500;
import java.io.InputStream;
import io.swagger.v3.oas.annotations.extensions.Extension;
import io.swagger.v3.oas.annotations.extensions.ExtensionProperty;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.eclipse.hawkbit.rest.OpenApi;
import org.springframework.http.ResponseEntity;
@@ -41,6 +46,10 @@ public interface MgmtDownloadArtifactRestApi {
* @return responseEntity with status ok if successful
*/
@GetResponses
@ApiResponses(value = {
@ApiResponse(responseCode = INTERNAL_SERVER_ERROR_500, description = "Artifact download or decryption failed",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts/{artifactId}/download")
@ResponseBody
ResponseEntity<InputStream> downloadArtifact(

View File

@@ -13,6 +13,7 @@ import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.ROLLOUT_ORDER;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.DeleteResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetIfExistResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.NOT_FOUND_404;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateNoContentResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutResponses;
@@ -372,7 +373,7 @@ public interface MgmtRolloutRestApi {
"Required Permission: CREATE_ROLLOUT")
@PostCreateResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Rollout not found.",
@ApiResponse(responseCode = NOT_FOUND_404, description = "Rollout not found.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/retry",

View File

@@ -11,8 +11,12 @@ package org.eclipse.hawkbit.mgmt.rest.api;
import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.SOFTWARE_MODULE_ORDER;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.DeleteResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GONE_410;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetIfExistResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.INTERNAL_SERVER_ERROR_500;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.LOCKED_423;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.NOT_FOUND_404;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutResponses;
@@ -73,7 +77,13 @@ public interface MgmtSoftwareModuleRestApi {
@Operation(summary = "Upload artifact", description = "Handles POST request for artifact upload. Required Permission: CREATE_REPOSITORY")
@PostCreateResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Software Module not found", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
@ApiResponse(responseCode = NOT_FOUND_404, description = "Software Module not found",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = GONE_410, description = "Artifact binary no longer exists",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = LOCKED_423, description = "Software module is locked",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = INTERNAL_SERVER_ERROR_500, description = "Upload / store to storage or encryption failed", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
@@ -96,6 +106,9 @@ public interface MgmtSoftwareModuleRestApi {
description = "Handles the GET request of retrieving all metadata of artifacts assigned to a " +
"software module. Required Permission: READ_REPOSITORY")
@GetResponses
@ApiResponses(value = {
@ApiResponse(responseCode = GONE_410, description = "Artifact binary no longer exists", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts",
produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
ResponseEntity<List<MgmtArtifact>> getArtifacts(
@@ -112,6 +125,9 @@ public interface MgmtSoftwareModuleRestApi {
*/
@Operation(summary = "Return single Artifact metadata", description = "Handles the GET request of retrieving a single Artifact metadata request. Required Permission: READ_REPOSITORY")
@GetResponses
@ApiResponses(value = {
@ApiResponse(responseCode = GONE_410, description = "Artifact binary no longer exists", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts/{artifactId}",
produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
@@ -129,6 +145,12 @@ public interface MgmtSoftwareModuleRestApi {
*/
@Operation(summary = "Delete artifact by Id", description = "Handles the DELETE request for a single Artifact assigned to a SoftwareModule. Required Permission: DELETE_REPOSITORY")
@DeleteResponses
@ApiResponses(value = {
@ApiResponse(responseCode = LOCKED_423, description = "Software module is locked",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
@ApiResponse(responseCode = INTERNAL_SERVER_ERROR_500, description = "Artifact delete failed with internal server error",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@DeleteMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts/{artifactId}")
@ResponseBody
ResponseEntity<Void> deleteArtifact(
@@ -195,6 +217,10 @@ public interface MgmtSoftwareModuleRestApi {
*/
@Operation(summary = "Create Software Module(s)", description = "Handles the POST request of creating new software modules. The request body must always be a list of modules. Required Permission: CREATE_REPOSITORY")
@PostCreateResponses
@ApiResponses(value = {
@ApiResponse(responseCode = INTERNAL_SERVER_ERROR_500, description = "Artifact encryption failed",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING,
consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE },
produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
@@ -237,7 +263,8 @@ public interface MgmtSoftwareModuleRestApi {
@Operation(summary = "Creates a list of metadata for a specific Software Module", description = "Create a list of metadata entries Required Permission: UPDATE_REPOSITORY")
@PostCreateResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Software Module not found", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
@ApiResponse(responseCode = NOT_FOUND_404, description = "Software Module not found",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/metadata",
consumes = { MediaType.APPLICATION_JSON_VALUE, MediaTypes.HAL_JSON_VALUE })

View File

@@ -13,6 +13,7 @@ import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.SOFTWARE_MODUL
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.DeleteResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetIfExistResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.NOT_FOUND_404;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutResponses;
@@ -148,7 +149,7 @@ public interface MgmtSoftwareModuleTypeRestApi {
"always be a list of module types. Required Permission: CREATE_REPOSITORY")
@PostCreateResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Software Module not found",
@ApiResponse(responseCode = NOT_FOUND_404, description = "Software Module not found",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING,

View File

@@ -11,8 +11,11 @@ package org.eclipse.hawkbit.mgmt.rest.api;
import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.TARGET_ORDER;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.DeleteResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GONE_410;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetIfExistResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.METHOD_NOT_ALLOWED_405;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.NOT_FOUND_404;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutNoContentResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutResponses;
@@ -288,6 +291,9 @@ public interface MgmtTargetRestApi {
*/
@Operation(summary = "Cancel action for a specific target", description = "Cancels an active action, only active actions can be deleted. Required Permission: UPDATE_TARGET")
@DeleteResponses
@ApiResponses(value = {
@ApiResponse(responseCode = METHOD_NOT_ALLOWED_405, description = "Software module is locked", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@DeleteMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}")
ResponseEntity<Void> cancelAction(
@PathVariable("targetId") String targetId,
@@ -323,7 +329,7 @@ public interface MgmtTargetRestApi {
""")
@PutNoContentResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "410", description = "Action is not active anymore.",
@ApiResponse(responseCode = GONE_410, description = "Action is not active anymore.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))),
})
@PutMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}/confirmation",
@@ -426,7 +432,7 @@ public interface MgmtTargetRestApi {
@Operation(summary = "Create a list of metadata for a specific target", description = "Create a list of metadata entries Required permissions: READ_REPOSITORY and UPDATE_TARGET")
@PostCreateResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Target not found", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
@ApiResponse(responseCode = NOT_FOUND_404, description = "Target not found", content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/metadata",
consumes = { MediaType.APPLICATION_JSON_VALUE, MediaTypes.HAL_JSON_VALUE })

View File

@@ -13,6 +13,7 @@ import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.TARGET_TYPE_OR
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.DeleteResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetIfExistResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.GetResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.NOT_FOUND_404;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PostCreateResponses;
import static org.eclipse.hawkbit.rest.ApiResponsesConstants.PutResponses;
@@ -146,7 +147,7 @@ public interface MgmtTargetTypeRestApi {
"types. The request body must always be a list of types. Required Permission: CREATE_TARGET")
@PostCreateResponses
@ApiResponses(value = {
@ApiResponse(responseCode = "404", description = "Target type not found.",
@ApiResponse(responseCode = NOT_FOUND_404, description = "Target type not found.",
content = @Content(mediaType = "application/json", schema = @Schema(hidden = true)))
})
@PostMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING,