-
Notifications
You must be signed in to change notification settings - Fork 1
Refactor component creation and retrieval logic; enhance error handli… #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
e36dbed
Refactor component creation and retrieval logic; enhance error handli…
angelmp01 bcf02b3
Enhance error handling in ProjectExceptionHandler and ProjectValidati…
jorge-romero 0feb6b8
Improve flavor request validation in FlavorRestrictionEvaluator to ch…
jorge-romero a39a07a
Refactor error messages in ComponentErrorKey; streamline error handli…
angelmp01 cfa972e
Merge branch 'chore/component-api-error-handling' of github.com:opend…
angelmp01 788f042
Fix formatting of error message in ProjectExceptionHandlerTest for be…
angelmp01 c6599fc
Refactor error messages in ComponentErrorKey; use constants for consi…
angelmp01 d794fd0
Refactor error handling; replace string literals with constants in Co…
angelmp01 7d308c9
Refactor component API schema and model; rename EnvironmentsTypeDTO t…
angelmp01 941aaf2
Add private constructor to ComponentErrorMessage to prevent instantia…
angelmp01 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,7 +27,7 @@ paths: | |
| - name: projectId | ||
| in: path | ||
| required: true | ||
| description: Project id | ||
| description: Project key | ||
| schema: | ||
| type: string | ||
| requestBody: | ||
|
|
@@ -37,8 +37,8 @@ paths: | |
| schema: | ||
| $ref: '#/components/schemas/CreateComponentRequest' | ||
| responses: | ||
| '201': | ||
| description: Created | ||
| '200': | ||
| description: OK | ||
| headers: | ||
| Location: | ||
| schema: | ||
|
|
@@ -49,14 +49,26 @@ paths: | |
| $ref: '#/components/schemas/CreateComponentResponse' | ||
| '400': | ||
| description: Bad Request | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/CreateComponentResponse' | ||
| '401': | ||
| $ref: '#/components/responses/UnauthorizedError' | ||
| '403': | ||
| description: Forbidden | ||
| '404': | ||
| description: Endpoint not found / Project not found / Product not found | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/CreateComponentResponse' | ||
| '500': | ||
| description: Internal Server Error | ||
| content: | ||
| application/json: | ||
| schema: | ||
| $ref: '#/components/schemas/CreateComponentResponse' | ||
|
|
||
| /projects/{projectId}/components/{componentId}: | ||
| get: | ||
|
|
@@ -69,7 +81,7 @@ paths: | |
| - name: projectId | ||
| in: path | ||
| required: true | ||
| description: Project id | ||
| description: Project key | ||
| schema: | ||
| type: string | ||
| - name: componentId | ||
|
|
@@ -78,6 +90,7 @@ paths: | |
| description: Component id | ||
| schema: | ||
| type: string | ||
| format: uuid | ||
| responses: | ||
| '200': | ||
| description: Component information | ||
|
|
@@ -105,6 +118,10 @@ components: | |
| schemas: | ||
| Component: | ||
| type: object | ||
| x-class-extra-annotation: | | ||
| @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL) | ||
| required: | ||
| - params | ||
| properties: | ||
| id: | ||
| type: string | ||
|
|
@@ -117,50 +134,94 @@ components: | |
| description: Description of the product | ||
| productName: | ||
| type: string | ||
| description: Name of the product (e.g. Docker plain) | ||
| description: Name of the product | ||
| productId: | ||
| type: string | ||
| description: Product ID | ||
| environment: | ||
| type: string | ||
| description: Environment (e.g. DEV) | ||
| $ref: '#/components/schemas/EnvironmentsTypeDTO' | ||
| description: Environment | ||
| status: | ||
| type: string | ||
| description: Status of the component (e.g. READY, NOT_READY) | ||
| $ref: '#/components/schemas/EnvironmentsStatusDTO' | ||
| description: Status of the component | ||
| resultTraceback: | ||
| type: string | ||
| type: object | ||
| nullable: true | ||
| description: Traceback information in case of error | ||
| x-field-extra-annotation: | | ||
| @com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY) | ||
| repositoryURL: | ||
| type: string | ||
| description: URL of the repository (for ODS products) | ||
| params: | ||
| type: object | ||
| description: Additional parameters (key-value pairs) | ||
| additionalProperties: true | ||
| component-type: | ||
| type: string | ||
| description: Type of component (ods|awx) | ||
| CreateComponentResponse: | ||
| type: object | ||
| required: | ||
| - timestamp | ||
| - httpStatus | ||
| - errorKey | ||
| - message | ||
| - path | ||
| properties: | ||
| errorCode: | ||
| timestamp: | ||
| type: integer | ||
| field: | ||
| format: int64 | ||
| httpStatus: | ||
| type: string | ||
| errorKey: | ||
| type: string | ||
| error: | ||
| type: string | ||
| message: | ||
| type: string | ||
| location: | ||
| path: | ||
| type: string | ||
| format: url | ||
| CreateComponentRequest: | ||
| type: object | ||
| required: | ||
| - name | ||
| - productId | ||
| - params | ||
| properties: | ||
| name: | ||
| type: string | ||
| description: component name | ||
| description: Component name | ||
| minLength: 2 | ||
| maxLength: 52 | ||
| pattern: "^[a-z]+(-?[a-z0-9]+)*$" | ||
| x-field-extra-annotation: | | ||
| @Size(min=2, message = "The component name must contain more than 1 character.") | ||
| @Size(max=52, message = "The component name must contain less than 53 characters.") | ||
| @Pattern(regexp = "^[a-z]+(-?[a-z0-9]+)*$", message = "Only lowercase letters and numbers are allowed (example: componentname8), with optional dashes in between (example: my-component). The first character must be a letter.") | ||
| productId: | ||
| type: string | ||
| description: product id | ||
| description: Product id | ||
| registerOnly: | ||
| type: boolean | ||
| description: Register only flag (no provisioning) | ||
| default: false | ||
| params: | ||
| type: object | ||
| additionalProperties: | ||
| type: string | ||
| description: Additional parameters (key-value pairs) | ||
| additionalProperties: true | ||
| EnvironmentsTypeDTO: | ||
| type: string | ||
| enum: | ||
| - DEV | ||
| - QA | ||
| - PROD | ||
| EnvironmentsStatusDTO: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not the status of the environment, it is the status of the Component / Project provisioning
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| type: string | ||
| enum: | ||
| - READY | ||
| - RUNNING | ||
| - FAILED | ||
| - DELETING | ||
| - DELETED | ||
| - UNKNOWN | ||
26 changes: 26 additions & 0 deletions
26
...onent-v0/src/main/java/org/opendevstack/apiservice/project/config/JsonNullableConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package org.opendevstack.apiservice.project.config; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonInclude; | ||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import org.openapitools.jackson.nullable.JsonNullable; | ||
| import org.openapitools.jackson.nullable.JsonNullableModule; | ||
| import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
|
|
||
| @Configuration | ||
| public class JsonNullableConfig { | ||
|
|
||
| @Bean | ||
| public Jackson2ObjectMapperBuilderCustomizer jsonNullableCustomizer() { | ||
| return builder -> { | ||
| builder.modulesToInstall(JsonNullableModule.class); | ||
| builder.postConfigurer(this::configureJsonNullableInclusion); | ||
| }; | ||
| } | ||
|
|
||
| private void configureJsonNullableInclusion(ObjectMapper objectMapper) { | ||
| objectMapper.configOverride(JsonNullable.class) | ||
| .setInclude(JsonInclude.Value.construct(JsonInclude.Include.NON_ABSENT, JsonInclude.Include.NON_ABSENT)); | ||
| } | ||
| } |
44 changes: 37 additions & 7 deletions
44
...c/main/java/org/opendevstack/apiservice/project/controller/ComponentsResponseFactory.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,54 @@ | ||
| package org.opendevstack.apiservice.project.controller; | ||
|
|
||
| import org.opendevstack.apiservice.project.exception.ComponentErrorKey; | ||
| import org.opendevstack.apiservice.project.model.CreateComponentResponse; | ||
| import org.springframework.http.HttpStatus; | ||
|
|
||
| public class ComponentsResponseFactory { | ||
| public final class ComponentsResponseFactory { | ||
|
|
||
| private ComponentsResponseFactory() { | ||
| } | ||
|
|
||
| public static CreateComponentResponse error(String projectId) { | ||
| public static CreateComponentResponse entityCreated(String projectId, String componentId) { | ||
| String path = String.format("/api/pub/v0/projects/%s/components/%s", projectId, componentId); | ||
| return ok(path, "Component created"); | ||
| } | ||
|
|
||
| public static CreateComponentResponse badRequest(String path, String message, ComponentErrorKey errorKey) { | ||
| return buildResponse(HttpStatus.BAD_REQUEST, errorKey, path, message); | ||
| } | ||
|
|
||
| public static CreateComponentResponse forbidden(String path, String message, ComponentErrorKey errorKey) { | ||
| return buildResponse(HttpStatus.FORBIDDEN, errorKey, path, message); | ||
| } | ||
|
|
||
| public static CreateComponentResponse notFound(String path, String message, ComponentErrorKey errorKey) { | ||
| return buildResponse(HttpStatus.NOT_FOUND, errorKey, path, message); | ||
| } | ||
|
|
||
| public static CreateComponentResponse internalError(String path, String message, ComponentErrorKey errorKey) { | ||
| return buildResponse(HttpStatus.INTERNAL_SERVER_ERROR, errorKey, path, message); | ||
| } | ||
|
|
||
| private static CreateComponentResponse buildResponse(HttpStatus httpStatus, ComponentErrorKey errorKey, String path, | ||
| String message) { | ||
| CreateComponentResponse response = new CreateComponentResponse(); | ||
| response.setErrorCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); | ||
| response.setMessage("Failed to create component for project '" + projectId + "'"); | ||
| response.setTimestamp(System.currentTimeMillis()); | ||
| response.setHttpStatus(httpStatus.name()); | ||
| response.setErrorKey(errorKey.getKey()); | ||
| response.setError(errorKey.getMessage()); | ||
| response.setMessage(message); | ||
| response.setPath(path); | ||
| return response; | ||
| } | ||
|
|
||
| public static CreateComponentResponse entityCreated(String projectId, String componentId) { | ||
| public static CreateComponentResponse ok(String path, String message) { | ||
| CreateComponentResponse response = new CreateComponentResponse(); | ||
| response.setErrorCode(HttpStatus.CREATED.value()); | ||
| response.setMessage(componentId + " component created successfully in project " + projectId); | ||
| response.setTimestamp(System.currentTimeMillis()); | ||
| response.setHttpStatus(HttpStatus.OK.name()); | ||
| response.setErrorKey(ComponentErrorKey.OK.getKey()); | ||
| response.setMessage(message); | ||
| response.setPath(path); | ||
| return response; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check if it is needed for the new Markeplace 2.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done