From 8a9edc0e0decd34abbe27a23244cff82c6ef3e63 Mon Sep 17 00:00:00 2001 From: Daniil Palagin Date: Thu, 22 Aug 2024 12:52:45 +0200 Subject: [PATCH 1/4] [#82] Add Doc to ComponentController --- build.gradle | 2 + .../controller/ComponentController.java | 74 +++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/build.gradle b/build.gradle index a90dce9..56f7958 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,8 @@ dependencies { implementation 'com.fasterxml:classmate:1.5.0' implementation 'com.opencsv:opencsv:5.3' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + implementation 'org.projectlombok:lombok:1.18.30' annotationProcessor 'org.projectlombok:lombok:1.18.30' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' diff --git a/src/main/java/cz/cvut/kbss/analysis/controller/ComponentController.java b/src/main/java/cz/cvut/kbss/analysis/controller/ComponentController.java index 15156b6..df3d377 100755 --- a/src/main/java/cz/cvut/kbss/analysis/controller/ComponentController.java +++ b/src/main/java/cz/cvut/kbss/analysis/controller/ComponentController.java @@ -9,6 +9,9 @@ import cz.cvut.kbss.analysis.service.IdentifierService; import cz.cvut.kbss.analysis.util.Vocabulary; import cz.cvut.kbss.jsonld.JsonLd; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -31,11 +34,20 @@ public class ComponentController { private final ComponentRepositoryService repositoryService; private final IdentifierService identifierService; + @Operation(summary = "Retrieve all components") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully retrieved all components") + }) @GetMapping(produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE}) public List findAll() { return repositoryService.findAll(); } + + @Operation(summary = "Create a new component") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Component created successfully"), + }) @ResponseStatus(HttpStatus.CREATED) @PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) public Component create(@RequestBody Component component) { @@ -44,12 +56,21 @@ public Component create(@RequestBody Component component) { return component; } + @Operation(summary = "Update an existing component") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Component updated successfully"), + }) @PutMapping(consumes = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}, produces = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) public Component update(@RequestBody ComponentUpdateDTO componentUpdate) { log.info("> update - {}", componentUpdate); return repositoryService.updateByDTO(componentUpdate); } + @Operation(summary = "Delete a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Component deleted successfully"), + @ApiResponse(responseCode = "404", description = "Component not found") + }) @ResponseStatus(HttpStatus.NO_CONTENT) @DeleteMapping(value = "/{componentFragment}") public void delete(@PathVariable(name = "componentFragment") String componentFragment) { @@ -59,6 +80,11 @@ public void delete(@PathVariable(name = "componentFragment") String componentFra repositoryService.remove(componentUri); } + @Operation(summary = "Retrieve functions of a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Functions retrieved successfully"), + @ApiResponse(responseCode = "404", description = "Component not found") + }) @GetMapping(value = "/{componentFragment}/functions", produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE}) public Set getFunctions(@PathVariable(name = "componentFragment") String componentFragment) { log.info("> getFunctions - {}", componentFragment); @@ -66,6 +92,11 @@ public Set getFunctions(@PathVariable(name = "componentFragment") Stri return repositoryService.getFunctions(componentUri); } + @Operation(summary = "Retrieve failure modes of a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Failure modes retrieved successfully"), + @ApiResponse(responseCode = "404", description = "Component not found") + }) @GetMapping(value = "/{componentFragment}/failureModes", produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE}) public Set getFailureModes(@PathVariable(name = "componentFragment") String componentFragment) { log.info("> getFailureModes - {}", componentFragment); @@ -73,6 +104,13 @@ public Set getFailureModes(@PathVariable(name = "componentFragment" return repositoryService.getFailureModes(componentUri); } + + @Operation(summary = "Add a failure mode to a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Failure mode added successfully"), + @ApiResponse(responseCode = "400", description = "Invalid input"), + @ApiResponse(responseCode = "404", description = "Component not found") + }) @ResponseStatus(HttpStatus.CREATED) @PostMapping(value = "/{componentFragment}/failureModes", produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE}, consumes = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) public FailureMode addFailureMode(@PathVariable(name = "componentFragment") String componentFragment, @RequestBody FailureMode failureMode) { @@ -82,6 +120,11 @@ public FailureMode addFailureMode(@PathVariable(name = "componentFragment") Stri return repositoryService.addFailureMode(componentUri,failureMode); } + @Operation(summary = "Add a failure mode by URI to a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Failure mode added by URI successfully"), + @ApiResponse(responseCode = "404", description = "Component or failure mode not found") + }) @ResponseStatus(HttpStatus.CREATED) @PostMapping(value = "/{componentFragment}/failureModes/{failureModeFragment}", produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE}, consumes = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) public void addFailureModeByURI(@PathVariable(name = "componentFragment") String componentFragment, @PathVariable(name = "failureModeFragment") String failureModeFragment) { @@ -91,6 +134,11 @@ public void addFailureModeByURI(@PathVariable(name = "componentFragment") String repositoryService.addFailureModeByUri(componentUri, failureModeUri); } + @Operation(summary = "Delete a failure mode from a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Failure mode deleted successfully"), + @ApiResponse(responseCode = "404", description = "Component or failure mode not found") + }) @DeleteMapping(value = "/{componentFragment}/failureModes/{failureModeFragment}") public void deleteFailureMode(@PathVariable(name = "componentFragment") String componentFragment, @PathVariable(name = "failureModeFragment") String failureModeFragment) { log.info("> deleteFailureMode - {}, {}", componentFragment, failureModeFragment); @@ -101,6 +149,12 @@ public void deleteFailureMode(@PathVariable(name = "componentFragment") String c log.info("< deleteFailureMode"); } + @Operation(summary = "Add a function to a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Function added successfully"), + @ApiResponse(responseCode = "400", description = "Invalid input"), + @ApiResponse(responseCode = "404", description = "Component not found") + }) @ResponseStatus(HttpStatus.CREATED) @PostMapping(value = "/{componentFragment}/functions", consumes = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) public Function addFunction(@PathVariable(name = "componentFragment") String componentFragment, @RequestBody Function function) { @@ -120,6 +174,11 @@ public Function addFunctionByURI(@PathVariable(name = "componentFragment") Strin return repositoryService.addFunctionByURI(componentUri, functionUri); } + @Operation(summary = "Add a function by URI to a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Function added by URI successfully"), + @ApiResponse(responseCode = "404", description = "Component or function not found") + }) @DeleteMapping(value = "/{componentFragment}/functions/{functionFragment}") public void deleteFunction(@PathVariable(name = "componentFragment") String componentFragment, @PathVariable(name = "functionFragment") String functionFragment) { log.info("> deleteFunction - {}, {}", componentFragment, functionFragment); @@ -130,6 +189,11 @@ public void deleteFunction(@PathVariable(name = "componentFragment") String comp log.info("< deleteFunction"); } + @Operation(summary = "Link two components") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Components linked successfully"), + @ApiResponse(responseCode = "404", description = "Component not found") + }) @PostMapping(value = "/{componentFragment}/linkComponent/{linkFragment}") public Component linkComponents( @PathVariable(name = "componentFragment") String componentFragment, @@ -141,6 +205,11 @@ public Component linkComponents( return repositoryService.linkComponents(componentUri, linkComponentUri); } + @Operation(summary = "Unlink a component from its linked components") + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Component unlinked successfully"), + @ApiResponse(responseCode = "404", description = "Component not found") + }) @DeleteMapping(value = "/{componentFragment}/linkComponent") public void unlinkComponents(@PathVariable(name = "componentFragment") String componentFragment) { log.info("> unlinkComponents - {}", componentFragment); @@ -150,6 +219,11 @@ public void unlinkComponents(@PathVariable(name = "componentFragment") String co log.info("< unlinkComponents"); } + @Operation(summary = "Merge two components into one") + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "Components merged successfully"), + @ApiResponse(responseCode = "404", description = "One or both components not found") + }) @PostMapping(value = "/mergeComponents/{sourceFragment}/{targetFragment}") public void mergeComponents(@PathVariable(name = "sourceFragment") String sourceFragment ,@PathVariable(name = "targetFragment") String targetFragment){ From 8bb90a7cd37be5a9d870f4a670a6cfa5c8159234 Mon Sep 17 00:00:00 2001 From: Daniil Palagin Date: Tue, 3 Sep 2024 13:46:56 +0200 Subject: [PATCH 2/4] [#82] Update ComponentController documentation --- .../controller/ComponentController.java | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/main/java/cz/cvut/kbss/analysis/controller/ComponentController.java b/src/main/java/cz/cvut/kbss/analysis/controller/ComponentController.java index df3d377..a6778f1 100755 --- a/src/main/java/cz/cvut/kbss/analysis/controller/ComponentController.java +++ b/src/main/java/cz/cvut/kbss/analysis/controller/ComponentController.java @@ -36,7 +36,7 @@ public class ComponentController { @Operation(summary = "Retrieve all components") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully retrieved all components") + @ApiResponse(responseCode = "200", description = "Retrieved all components") }) @GetMapping(produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE}) public List findAll() { @@ -46,7 +46,7 @@ public List findAll() { @Operation(summary = "Create a new component") @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Component created successfully"), + @ApiResponse(responseCode = "201", description = "Component created"), }) @ResponseStatus(HttpStatus.CREATED) @PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) @@ -58,7 +58,7 @@ public Component create(@RequestBody Component component) { @Operation(summary = "Update an existing component") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Component updated successfully"), + @ApiResponse(responseCode = "200", description = "Component updated"), }) @PutMapping(consumes = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}, produces = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) public Component update(@RequestBody ComponentUpdateDTO componentUpdate) { @@ -68,7 +68,7 @@ public Component update(@RequestBody ComponentUpdateDTO componentUpdate) { @Operation(summary = "Delete a component") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Component deleted successfully"), + @ApiResponse(responseCode = "204", description = "Component deleted"), @ApiResponse(responseCode = "404", description = "Component not found") }) @ResponseStatus(HttpStatus.NO_CONTENT) @@ -82,7 +82,7 @@ public void delete(@PathVariable(name = "componentFragment") String componentFra @Operation(summary = "Retrieve functions of a component") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Functions retrieved successfully"), + @ApiResponse(responseCode = "200", description = "Functions retrieved"), @ApiResponse(responseCode = "404", description = "Component not found") }) @GetMapping(value = "/{componentFragment}/functions", produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE}) @@ -94,7 +94,7 @@ public Set getFunctions(@PathVariable(name = "componentFragment") Stri @Operation(summary = "Retrieve failure modes of a component") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Failure modes retrieved successfully"), + @ApiResponse(responseCode = "200", description = "Failure modes retrieved"), @ApiResponse(responseCode = "404", description = "Component not found") }) @GetMapping(value = "/{componentFragment}/failureModes", produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE}) @@ -105,10 +105,9 @@ public Set getFailureModes(@PathVariable(name = "componentFragment" } - @Operation(summary = "Add a failure mode to a component") + @Operation(summary = "Add new failure mode to a component") @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Failure mode added successfully"), - @ApiResponse(responseCode = "400", description = "Invalid input"), + @ApiResponse(responseCode = "201", description = "Failure mode added"), @ApiResponse(responseCode = "404", description = "Component not found") }) @ResponseStatus(HttpStatus.CREATED) @@ -117,12 +116,12 @@ public FailureMode addFailureMode(@PathVariable(name = "componentFragment") Stri log.info("> addFailureMode - {}, {}", componentFragment, failureMode); URI componentUri = identifierService.composeIdentifier(Vocabulary.s_c_component, componentFragment); - return repositoryService.addFailureMode(componentUri,failureMode); + return repositoryService.addFailureMode(componentUri, failureMode); } @Operation(summary = "Add a failure mode by URI to a component") @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Failure mode added by URI successfully"), + @ApiResponse(responseCode = "201", description = "Failure mode added"), @ApiResponse(responseCode = "404", description = "Component or failure mode not found") }) @ResponseStatus(HttpStatus.CREATED) @@ -136,7 +135,7 @@ public void addFailureModeByURI(@PathVariable(name = "componentFragment") String @Operation(summary = "Delete a failure mode from a component") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Failure mode deleted successfully"), + @ApiResponse(responseCode = "204", description = "Failure mode deleted "), @ApiResponse(responseCode = "404", description = "Component or failure mode not found") }) @DeleteMapping(value = "/{componentFragment}/failureModes/{failureModeFragment}") @@ -151,8 +150,7 @@ public void deleteFailureMode(@PathVariable(name = "componentFragment") String c @Operation(summary = "Add a function to a component") @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Function added successfully"), - @ApiResponse(responseCode = "400", description = "Invalid input"), + @ApiResponse(responseCode = "201", description = "Function added"), @ApiResponse(responseCode = "404", description = "Component not found") }) @ResponseStatus(HttpStatus.CREATED) @@ -164,19 +162,25 @@ public Function addFunction(@PathVariable(name = "componentFragment") String com return repositoryService.addFunction(componentUri, function); } + + @Operation(summary = "Add function by URI to a component") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Function added to the component"), + @ApiResponse(responseCode = "404", description = "Component or Function not found"), + }) @ResponseStatus(HttpStatus.CREATED) @PostMapping(value = "/{componentFragment}/functions/{functionFragment}", produces = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE}) public Function addFunctionByURI(@PathVariable(name = "componentFragment") String componentFragment, @PathVariable(name = "functionFragment") String functionFragment) { log.info("> addFunction - {}, {}", componentFragment, functionFragment); URI componentUri = identifierService.composeIdentifier(Vocabulary.s_c_component, componentFragment); URI functionUri = identifierService.composeIdentifier(Vocabulary.s_c_function, functionFragment); - + return repositoryService.addFunctionByURI(componentUri, functionUri); } @Operation(summary = "Add a function by URI to a component") @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Function added by URI successfully"), + @ApiResponse(responseCode = "201", description = "Function added by URI"), @ApiResponse(responseCode = "404", description = "Component or function not found") }) @DeleteMapping(value = "/{componentFragment}/functions/{functionFragment}") @@ -191,7 +195,7 @@ public void deleteFunction(@PathVariable(name = "componentFragment") String comp @Operation(summary = "Link two components") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Components linked successfully"), + @ApiResponse(responseCode = "200", description = "Components linked"), @ApiResponse(responseCode = "404", description = "Component not found") }) @PostMapping(value = "/{componentFragment}/linkComponent/{linkFragment}") @@ -207,7 +211,7 @@ public Component linkComponents( @Operation(summary = "Unlink a component from its linked components") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Component unlinked successfully"), + @ApiResponse(responseCode = "204", description = "Component unlinked"), @ApiResponse(responseCode = "404", description = "Component not found") }) @DeleteMapping(value = "/{componentFragment}/linkComponent") @@ -221,12 +225,12 @@ public void unlinkComponents(@PathVariable(name = "componentFragment") String co @Operation(summary = "Merge two components into one") @ApiResponses(value = { - @ApiResponse(responseCode = "204", description = "Components merged successfully"), + @ApiResponse(responseCode = "204", description = "Components merged"), @ApiResponse(responseCode = "404", description = "One or both components not found") }) @PostMapping(value = "/mergeComponents/{sourceFragment}/{targetFragment}") public void mergeComponents(@PathVariable(name = "sourceFragment") String sourceFragment - ,@PathVariable(name = "targetFragment") String targetFragment){ + , @PathVariable(name = "targetFragment") String targetFragment) { log.info("> mergeComponents - {} {}", sourceFragment, targetFragment); URI sourceUri = identifierService.composeIdentifier(Vocabulary.s_c_component, sourceFragment); From d206678f242378a6d8632d193d0f17e227ae639d Mon Sep 17 00:00:00 2001 From: Daniil Palagin Date: Mon, 14 Oct 2024 12:26:56 +0200 Subject: [PATCH 3/4] [#82] Add Config for OpenAPI --- .../kbss/analysis/config/OpenApiConfig.java | 30 +++++++++++++++++++ src/main/resources/application.yml | 8 ++++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/main/java/cz/cvut/kbss/analysis/config/OpenApiConfig.java diff --git a/src/main/java/cz/cvut/kbss/analysis/config/OpenApiConfig.java b/src/main/java/cz/cvut/kbss/analysis/config/OpenApiConfig.java new file mode 100644 index 0000000..7e1476b --- /dev/null +++ b/src/main/java/cz/cvut/kbss/analysis/config/OpenApiConfig.java @@ -0,0 +1,30 @@ +package cz.cvut.kbss.analysis.config; + +import io.swagger.v3.oas.annotations.OpenAPIDefinition; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn; +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; +import io.swagger.v3.oas.annotations.info.Info; +import io.swagger.v3.oas.annotations.security.SecurityScheme; +import io.swagger.v3.oas.annotations.security.SecuritySchemes; + +/** + * Configuration class for OpenAPI documentation. + */ +@OpenAPIDefinition( + info = @Info( + title = "FTA and FMEA API", + description = "Docs for FTA and FMEA API", + version = "1.0" + ) +) +@SecuritySchemes({ + @SecurityScheme( + name = "basicAuth", + description = "Basic auth", + scheme = "basic", + type = SecuritySchemeType.HTTP, + in = SecuritySchemeIn.HEADER + ) +}) +public class OpenApiConfig { +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8af6507..d5226ed 100755 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -42,4 +42,10 @@ operational.data.filter: min-operational-hours: 200 operationalFailureRateService: http://localhost:9998/stats/failure-rate -fhaBasedoperationalFailureRateService: http://localhost:9998/stats/fha-failure-rate \ No newline at end of file +fhaBasedoperationalFailureRateService: http://localhost:9998/stats/fha-failure-rate + +springdoc: + api-docs: + path: /v1/api-docs + swagger-ui: + path: /swagger-ui.html From 3cc7b6250c645078af31fe44a0b80a3c0e3421f1 Mon Sep 17 00:00:00 2001 From: Daniil Palagin Date: Mon, 14 Oct 2024 12:27:07 +0200 Subject: [PATCH 4/4] [#82] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 6a8bfa6..993b559 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,9 @@ For more details see [README.md](ontology-generator/README.md) The data are mapped from Java objects to RDF entities via ontological mapping library JOPA and stored in a local GraphDB database. The database URL needs to be configured in `application.yml`. The repository first needs to be created. + +## API Documentation + +You can access the Swagger UI at the following URL: `http://localhost:9999/swagger-ui.html` + +The OpenAPI documentation for the API can be accessed at: `http://localhost:9999/v1/api-docs` \ No newline at end of file