diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index d22746d68..61151ec79 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -82,7 +82,7 @@ com.github.ben-manes.caffeine caffeine - 2.9.0 + 3.1.5 @@ -91,17 +91,17 @@ org.junit.jupiter junit-jupiter-api - 5.7.2 + 5.9.2 test org.postgresql postgresql - 42.2.22 + 42.6.0 - + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.1.0 + org.springframework.social diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/configurations/SwaggerConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/configurations/SwaggerConfiguration.java index 59448a0d6..f3284dfb4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/configurations/SwaggerConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/configurations/SwaggerConfiguration.java @@ -1,20 +1,12 @@ package eu.eudat.publicapi.configurations; -import eu.eudat.models.data.security.Principal; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.service.SecurityScheme; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; - -import java.util.Collections; -import java.util.HashSet; @Configuration public class SwaggerConfiguration { @@ -25,25 +17,16 @@ public class SwaggerConfiguration { private Environment environment; @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .host(this.environment.getProperty("publicapi.host")) - .protocols(new HashSet<>(Collections.singleton(this.environment.getProperty("publicapi.schema")))) - .select() - .apis(RequestHandlerSelectors.basePackage("eu.eudat.publicapi.controllers")) - .paths(PathSelectors.regex("/api/public/(dmps|datasets)/?.*")) - .build().apiInfo(apiInfo())//.ignoredParameterTypes(Principal.class) - .pathMapping(this.environment.getProperty("publicapi.basePath")) - .useDefaultResponseMessages(false); + public OpenAPI ArgosOpenApi() { + return new OpenAPI().info(apiInfo()); } - private ApiInfo apiInfo() { - return new ApiInfo( - "OpenDMP public API", - "Argos public API.", - "1.0", - "https://argos.openaire.eu/terms-and-conditions", - new Contact("Argos", "https://argos.openaire.eu/", "argos@openaire.eu "), - null, null, Collections.emptyList()); + private Info apiInfo() { + return new Info() + .title("OpenDMP public API") + .description("Argos public API.") + .version("1.0") + .termsOfService("https://argos.openaire.eu/terms-and-conditions") + .contact(new Contact().name("Argos").url("https://argos.openaire.eu/").email("argos@openaire.eu ")); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDatasetsDescriptionDocumentation.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDatasetsDescriptionDocumentation.java index a822c6d87..747ea7219 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDatasetsDescriptionDocumentation.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDatasetsDescriptionDocumentation.java @@ -13,6 +13,12 @@ import eu.eudat.publicapi.request.dataset.DatasetPublicTableRequest; import eu.eudat.types.ApiMessageCode; import eu.eudat.types.Authorities; import io.swagger.annotations.*; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -22,7 +28,7 @@ import org.springframework.web.bind.annotation.*; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -@Api(tags = "Datasets Description", description = "Provides Dataset description public API's.") +@Tag(name = "Datasets Description", description = "Provides Dataset description public API's.") @RestController @CrossOrigin @RequestMapping(value = {"/api/public/datasets/"}) @@ -214,34 +220,32 @@ public class PublicDatasetsDescriptionDocumentation extends BaseController { this.datasetManager = datasetManager; } - @ApiOperation(value = "This method is used to get a listing of public datasets.", notes = getPagedNotes) - @ApiResponses(value = {@ApiResponse( - code = 200, - message = "The following example is generated using body: *{\"criteria\": {},\"length\": 2,\"offset\": 0,\"orderings\": {\"fields\": []} }*", - examples = @Example({@ExampleProperty( - value = getPagedResponseExample, - mediaType = APPLICATION_JSON_VALUE + @Operation(summary = "This method is used to get a listing of public datasets.", description = getPagedNotes) + @io.swagger.v3.oas.annotations.responses.ApiResponses(value = {@io.swagger.v3.oas.annotations.responses.ApiResponse( + responseCode = "200", + description = "The following example is generated using body: *{\"criteria\": {},\"length\": 2,\"offset\": 0,\"orderings\": {\"fields\": []} }*", + content = @Content(mediaType = APPLICATION_JSON_VALUE, examples = {@ExampleObject( + value = getPagedResponseExample )}) )}) @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity>> getPaged(@RequestBody @ApiParam(value = getPagedRequestBodyDescription) DatasetPublicTableRequest datasetTableRequest) throws Exception { + ResponseEntity>> getPaged(@RequestBody @Parameter(description = getPagedRequestBodyDescription) DatasetPublicTableRequest datasetTableRequest) throws Exception { DataTableData dataTable = this.datasetManager.getPublicPaged(datasetTableRequest); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); } - @ApiOperation(value = "This method is used to get the overview of a public dataset.", notes = getOverviewSinglePublicNotes) - @ApiResponses(value = {@ApiResponse( - code = 200, - message = "The following example is generated using id: *ef7dfbdc-c5c1-46a7-a37b-c8d8692f1c0e*", - examples = @Example({@ExampleProperty( - value = getOverviewSinglePublicResponseExample, - mediaType = APPLICATION_JSON_VALUE + @Operation(summary = "This method is used to get the overview of a public dataset.", description = getOverviewSinglePublicNotes) + @io.swagger.v3.oas.annotations.responses.ApiResponses(value = {@ApiResponse( + responseCode = "200", + description = "The following example is generated using id: *ef7dfbdc-c5c1-46a7-a37b-c8d8692f1c0e*", + content = @Content(mediaType = APPLICATION_JSON_VALUE, examples = {@ExampleObject( + value = getOverviewSinglePublicResponseExample )}) )}) @RequestMapping(method = RequestMethod.GET, value = {"/{id}"}, produces = "application/json") public @ResponseBody - ResponseEntity> getOverviewSinglePublic(@PathVariable @ApiParam(value = "fetch the dataset with the given id", example = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") String id) throws Exception { + ResponseEntity> getOverviewSinglePublic(@PathVariable @Parameter(description = "fetch the dataset with the given id", example = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") String id) throws Exception { // try { DatasetPublicModel dataset = this.datasetManager.getOverviewSinglePublic(id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDmpsDocumentation.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDmpsDocumentation.java index b58c4bfec..cee43ccf8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDmpsDocumentation.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDmpsDocumentation.java @@ -1,18 +1,22 @@ package eu.eudat.publicapi.controllers; import eu.eudat.controllers.BaseController; -import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; -import eu.eudat.models.data.security.Principal; import eu.eudat.publicapi.managers.DataManagementPlanPublicManager; import eu.eudat.publicapi.models.listingmodels.DataManagementPlanPublicListingModel; import eu.eudat.publicapi.models.overviewmodels.DataManagementPlanPublicModel; import eu.eudat.publicapi.request.dmp.DataManagmentPlanPublicTableRequest; import eu.eudat.types.ApiMessageCode; -import eu.eudat.types.Authorities; import io.swagger.annotations.*; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -20,11 +24,9 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import jakarta.validation.Valid; - import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -@Api(tags = "DMPs", description = "Provides DMP public API's.") +@Tag(name = "DMPs", description = "Provides DMP public API's.") @RestController @CrossOrigin @RequestMapping(value = {"/api/public/dmps"}) @@ -39,17 +41,17 @@ public class PublicDmpsDocumentation extends BaseController { " 2. **statusCode**: integer, status code indicating if something unexpected happened, otherwise 0\n" + " 3. **responseType**: integer, 0 for json, 1 for file\n" + " 4. **payload**: DataTableData, containing the number of values of actual data returned and the data of type **DataManagementPlanPublicListingModel**\n" + - "4.1. id: string, id of dmp returned\n" + - "4.2. label: string, label of dmp\n" + - "4.3. grant: string, grant of dmp\n" + - "4.4. createdAt: date, creation time of dmp\n" + - "4.5. modifiedAt: date, modification time of dmp\n" + - "4.6. version: integer, version of dmp\n" + - "4.7. groupId: uuid, group id in which dmp belongs\n" + - "4.8. users: list of UserInfoPublicModel, user who collaborated on the dmp\n" + - "4.9. researchers: list of ResearcherPublicModel, researchers involved in the dmp\n" + - "4.9. finalizedAt: date, finalization date\n" + - "4.10. publishedAt: date, publication date\n"; + " 4.1. id: string, id of dmp returned\n" + + " 4.2. label: string, label of dmp\n" + + " 4.3. grant: string, grant of dmp\n" + + " 4.4. createdAt: date, creation time of dmp\n" + + " 4.5. modifiedAt: date, modification time of dmp\n" + + " 4.6. version: integer, version of dmp\n" + + " 4.7. groupId: uuid, group id in which dmp belongs\n" + + " 4.8. users: list of UserInfoPublicModel, user who collaborated on the dmp\n" + + " 4.9. researchers: list of ResearcherPublicModel, researchers involved in the dmp\n" + + " 4.10. finalizedAt: date, finalization date\n" + + " 4.11. publishedAt: date, publication date\n"; private static final String getPagedResponseExample = "{\n" + " \"statusCode\": 0,\n" + " \"responseType\": 0,\n" + @@ -115,23 +117,23 @@ public class PublicDmpsDocumentation extends BaseController { " 2. **statusCode**: integer, status code indicating if something unexpected happened, otherwise 0\n" + " 3. **responseType**: integer, 0 for json, 1 for file\n" + " 4. **payload**: DataManagementPlanPublicModel, dmp returned\n" + - "4.1. id: string, id of dmp returned\n" + - "4.2. label: string, label of dmp\n" + - "4.3. profile: string, profile of dmp\n" + - "4.4. grant: GrantPublicOverviewModel, grant of dmp\n" + - "4.5. createdAt: date, creation time of dmp\n" + - "4.6. modifiedAt: date, modification time of dmp\n" + - "4.7. finalizedAt: date, finalization date of dmp\n" + - "4.8. organisations: list of OrganizationPublicModel, organizations in which dmp belongs\n" + - "4.9. version: integer, version of dmp\n" + - "4.10. groupId: uuid, group id in which dmp belongs\n" + - "4.11. datasets: list of DatasetPublicModel, contained datasets\n" + - "4.12. associatedProfiles: list of AssociatedProfilePublicModel, associated profiles of dmp\n" + - "4.13. researchers: list of ResearcherPublicModel, researchers involved in dmp\n" + - "4.14. users: list of UserInfoPublicModel, user who collaborated on the dmp\n" + - "4.15. description: string, description of dmp\n" + - "4.16. publishedAt: date, publication date\n" + - "4.17. doi: string, if dmp has been published to zenodo so it has doi\n"; + " 4.1. id: string, id of dmp returned\n" + + " 4.2. label: string, label of dmp\n" + + " 4.3. profile: string, profile of dmp\n" + + " 4.4. grant: GrantPublicOverviewModel, grant of dmp\n" + + " 4.5. createdAt: date, creation time of dmp\n" + + " 4.6. modifiedAt: date, modification time of dmp\n" + + " 4.7. finalizedAt: date, finalization date of dmp\n" + + " 4.8. organisations: list of OrganizationPublicModel, organizations in which dmp belongs\n" + + " 4.9. version: integer, version of dmp\n" + + " 4.10. groupId: uuid, group id in which dmp belongs\n" + + " 4.11. datasets: list of DatasetPublicModel, contained datasets\n" + + " 4.12. associatedProfiles: list of AssociatedProfilePublicModel, associated profiles of dmp\n" + + " 4.13. researchers: list of ResearcherPublicModel, researchers involved in dmp\n" + + " 4.14. users: list of UserInfoPublicModel, user who collaborated on the dmp\n" + + " 4.15. description: string, description of dmp\n" + + " 4.16. publishedAt: date, publication date\n" + + " 4.17. doi: string, if dmp has been published to zenodo so it has doi\n"; private static final String getOverviewSinglePublicResponseExample = "{\n" + " \"statusCode\": 0,\n" + " \"responseType\": 0,\n" + @@ -243,37 +245,35 @@ public class PublicDmpsDocumentation extends BaseController { this.dataManagementPlanManager = dataManagementPlanManager; } - @ApiOperation(value = "This method is used to get a listing of public dmps.", notes = getPagedNotes) - @ApiResponses(value = {@ApiResponse( - code = 200, - message = "The following example is generated using:\n" + + @Operation(summary = "This method is used to get a listing of public dmps.", description = getPagedNotes) + @io.swagger.v3.oas.annotations.responses.ApiResponses(value = {@ApiResponse( + responseCode = "200", + description = "The following example is generated using:\n" + "a) body: *{\"criteria\": {},\"length\": 2,\"offset\": 0,\"orderings\": {\"fields\": []} }*\n" + "b) fieldsGroup: listing", - examples = @Example({@ExampleProperty( - value = getPagedResponseExample, - mediaType = APPLICATION_JSON_VALUE + content = @Content(mediaType = APPLICATION_JSON_VALUE, examples = {@ExampleObject( + value = getPagedResponseExample )}) )}) @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity>> getPaged(@Valid @RequestBody @ApiParam(value = getPagedRequestBodyDescription) DataManagmentPlanPublicTableRequest dmpTableRequest, - @RequestParam @ApiParam(value = getPagedRequestParamDescription, example = "listing") String fieldsGroup) throws Exception { + ResponseEntity>> getPaged(@Valid @RequestBody @Parameter(description = getPagedRequestBodyDescription) DataManagmentPlanPublicTableRequest dmpTableRequest, + @RequestParam @Parameter(description = getPagedRequestParamDescription, example = "listing") String fieldsGroup) throws Exception { DataTableData dataTable = this.dataManagementPlanManager.getPublicPaged(dmpTableRequest, fieldsGroup); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); } - @ApiOperation(value = "This method is used to get the overview of a public dmp.", notes = getOverviewSinglePublicNotes) - @ApiResponses(value = {@ApiResponse( - code = 200, - message = "The following example is generated using id: *e9a73d77-adfa-4546-974f-4a4a623b53a8*", - examples = @Example({@ExampleProperty( - value = getOverviewSinglePublicResponseExample, - mediaType = APPLICATION_JSON_VALUE + @Operation(summary = "This method is used to get the overview of a public dmp.", description = getOverviewSinglePublicNotes) + @io.swagger.v3.oas.annotations.responses.ApiResponses(value = {@ApiResponse( + responseCode = "200", + description = "The following example is generated using id: *e9a73d77-adfa-4546-974f-4a4a623b53a8*", + content = @Content(mediaType = APPLICATION_JSON_VALUE, examples = {@ExampleObject( + value = getOverviewSinglePublicResponseExample )}) )}) @RequestMapping(method = RequestMethod.GET, value = {"/{id}"}, produces = "application/json") public @ResponseBody - ResponseEntity> getOverviewSinglePublic(@PathVariable @ApiParam(value = "fetch the dmp with the given id", example = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") String id) throws Exception { + ResponseEntity> getOverviewSinglePublic(@PathVariable @Parameter(description = "fetch the dmp with the given id", example = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") String id) throws Exception { // try { DataManagementPlanPublicModel dataManagementPlan = this.dataManagementPlanManager.getOverviewSinglePublic(id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); diff --git a/dmp-backend/web/src/main/resources/config/application.yml b/dmp-backend/web/src/main/resources/config/application.yml index e4637e137..f3f73ef73 100644 --- a/dmp-backend/web/src/main/resources/config/application.yml +++ b/dmp-backend/web/src/main/resources/config/application.yml @@ -12,4 +12,5 @@ spring: optional:classpath:config/email.yml[.yml], optional:classpath:config/email-${spring.profiles.active}.yml[.yml], optional:file:../config/email-${spring.profiles.active}.yml[.yml], optional:classpath:config/elasticsearch.yml[.yml], optional:classpath:config/elasticsearch-${spring.profiles.active}.yml[.yml], optional:file:../config/elasticsearch-${spring.profiles.active}.yml[.yml], optional:classpath:config/file-path.yml[.yml], optional:classpath:config/file-path-${spring.profiles.active}.yml[.yml], optional:file:../config/file-path-${spring.profiles.active}.yml[.yml], - optional:classpath:config/external.yml[.yml], optional:classpath:config/external-${spring.profiles.active}.yml[.yml], optional:file:../config/external-${spring.profiles.active}.yml[.yml] \ No newline at end of file + optional:classpath:config/external.yml[.yml], optional:classpath:config/external-${spring.profiles.active}.yml[.yml], optional:file:../config/external-${spring.profiles.active}.yml[.yml], + optional:classpath:config/swagger.yml[.yml], optional:classpath:config/swagger-${spring.profiles.active}.yml[.yml], optional:file:../config/swagger-${spring.profiles.active}.yml[.yml] \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/config/swagger.yml b/dmp-backend/web/src/main/resources/config/swagger.yml new file mode 100644 index 000000000..ed221dcea --- /dev/null +++ b/dmp-backend/web/src/main/resources/config/swagger.yml @@ -0,0 +1,3 @@ +springdoc: + packagesToScan: eu.eudat.publicapi.controllers + pathsToScan: "/api/public/(dmps|datasets)/?.*" \ No newline at end of file