Skip to content

Commit

Permalink
Merge pull request #150 from kbss-cvut/82-rest-doc
Browse files Browse the repository at this point in the history
Document one REST endpoint with springdoc #82
  • Loading branch information
blcham authored Dec 17, 2024
2 parents b981c1f + 3cc7b62 commit 13da195
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 4 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/cz/cvut/kbss/analysis/config/OpenApiConfig.java
Original file line number Diff line number Diff line change
@@ -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 {
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 = "Retrieved all components")
})
@GetMapping(produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE})
public List<Component> findAll() {
return repositoryService.findAll();
}


@Operation(summary = "Create a new component")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "Component created"),
})
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE, JsonLd.MEDIA_TYPE})
public Component create(@RequestBody Component component) {
Expand All @@ -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"),
})
@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"),
@ApiResponse(responseCode = "404", description = "Component not found")
})
@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping(value = "/{componentFragment}")
public void delete(@PathVariable(name = "componentFragment") String componentFragment) {
Expand All @@ -59,29 +80,50 @@ 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"),
@ApiResponse(responseCode = "404", description = "Component not found")
})
@GetMapping(value = "/{componentFragment}/functions", produces = {JsonLd.MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE})
public Set<Function> getFunctions(@PathVariable(name = "componentFragment") String componentFragment) {
log.info("> getFunctions - {}", componentFragment);
URI componentUri = identifierService.composeIdentifier(Vocabulary.s_c_component, componentFragment);
return repositoryService.getFunctions(componentUri);
}

@Operation(summary = "Retrieve failure modes of a component")
@ApiResponses(value = {
@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})
public Set<FailureMode> getFailureModes(@PathVariable(name = "componentFragment") String componentFragment) {
log.info("> getFailureModes - {}", componentFragment);
URI componentUri = identifierService.composeIdentifier(Vocabulary.s_c_component, componentFragment);
return repositoryService.getFailureModes(componentUri);
}


@Operation(summary = "Add new failure mode to a component")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "Failure mode added"),
@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) {
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"),
@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) {
Expand All @@ -91,6 +133,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 "),
@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);
Expand All @@ -101,6 +148,11 @@ 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"),
@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) {
Expand All @@ -110,16 +162,27 @@ 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"),
@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);
Expand All @@ -130,6 +193,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"),
@ApiResponse(responseCode = "404", description = "Component not found")
})
@PostMapping(value = "/{componentFragment}/linkComponent/{linkFragment}")
public Component linkComponents(
@PathVariable(name = "componentFragment") String componentFragment,
Expand All @@ -141,6 +209,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"),
@ApiResponse(responseCode = "404", description = "Component not found")
})
@DeleteMapping(value = "/{componentFragment}/linkComponent")
public void unlinkComponents(@PathVariable(name = "componentFragment") String componentFragment) {
log.info("> unlinkComponents - {}", componentFragment);
Expand All @@ -150,9 +223,14 @@ 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"),
@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);
Expand Down
8 changes: 7 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
fhaBasedoperationalFailureRateService: http://localhost:9998/stats/fha-failure-rate

springdoc:
api-docs:
path: /v1/api-docs
swagger-ui:
path: /swagger-ui.html

0 comments on commit 13da195

Please sign in to comment.