diff --git a/backend/web/src/main/java/org/opencdmp/controllers/DmpBlueprintController.java b/backend/web/src/main/java/org/opencdmp/controllers/DmpBlueprintController.java index 1785db11d..c58fc4b0a 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/DmpBlueprintController.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/DmpBlueprintController.java @@ -12,11 +12,24 @@ import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.validation.ValidationFilterAnnotation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.transaction.Transactional; import jakarta.xml.bind.JAXBException; import org.opencdmp.audit.AuditableAction; import org.opencdmp.authorization.AuthorizationFlags; +import org.opencdmp.controllers.swagger.SwaggerHelpers; +import org.opencdmp.controllers.swagger.annotation.OperationWithTenantHeader; +import org.opencdmp.controllers.swagger.annotation.Swagger400; +import org.opencdmp.controllers.swagger.annotation.Swagger404; +import org.opencdmp.controllers.swagger.annotation.SwaggerCommonErrorResponses; import org.opencdmp.data.DmpBlueprintEntity; +import org.opencdmp.model.DescriptionTemplateType; import org.opencdmp.model.builder.dmpblueprint.DmpBlueprintBuilder; import org.opencdmp.model.censorship.dmpblueprint.DmpBlueprintCensor; import org.opencdmp.model.dmpblueprint.DmpBlueprint; @@ -45,6 +58,8 @@ import java.util.UUID; @RestController @RequestMapping(path = "api/dmp-blueprint") +@Tag(name = "Plan Blueprints", description = "Manage plan blueprints") +@SwaggerCommonErrorResponses public class DmpBlueprintController { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpBlueprintController.class)); @@ -77,6 +92,25 @@ public class DmpBlueprintController { } @PostMapping("query") + @OperationWithTenantHeader(summary = "Query all plan blueprints", description = SwaggerHelpers.DmpBlueprint.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.DmpBlueprint.endpoint_query_request_body, content = @Content( + examples = { + @ExampleObject( + name = "Pagination and projection", + description = "Simple paginated request using a property projection list and pagination info", + value = SwaggerHelpers.DmpBlueprint.endpoint_query_request_body_example + ) + } + )), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content( + array = @ArraySchema( + schema = @Schema( + implementation = DmpBlueprint.class + ) + ), + examples = @ExampleObject( + name = "First page", + description = "Example with the first page of paginated results", + value = SwaggerHelpers.DmpBlueprint.endpoint_query_response_example + )))) public QueryResult query(@RequestBody DmpBlueprintLookup lookup) throws MyApplicationException, MyForbiddenException { logger.debug("querying {}", DmpBlueprint.class.getSimpleName()); @@ -93,7 +127,12 @@ public class DmpBlueprintController { } @GetMapping("{id}") - public DmpBlueprint get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + @OperationWithTenantHeader(summary = "Fetch a specific plan blueprint by id") + @Swagger404 + public DmpBlueprint get( + @Parameter(name = "id", description = "The id of a plan blueprint to fetch", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id, + @Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet + ) throws MyApplicationException, MyForbiddenException, MyNotFoundException { logger.debug(new MapLogEntry("retrieving" + DmpBlueprint.class.getSimpleName()).And("id", id).And("fields", fieldSet)); this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null); @@ -112,9 +151,15 @@ public class DmpBlueprintController { } @PostMapping("persist") + @OperationWithTenantHeader(summary = "Create a new or update an existing plan blueprint") + @Swagger400 + @Swagger404 @Transactional @ValidationFilterAnnotation(validator = DmpBlueprintPersist.DmpBlueprintPersistValidator.ValidatorName, argumentName = "model") - public DmpBlueprint persist(@RequestBody DmpBlueprintPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException { + public DmpBlueprint persist( + @RequestBody DmpBlueprintPersist model, + @Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet + ) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException { logger.debug(new MapLogEntry("persisting" + DmpBlueprint.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null); @@ -129,8 +174,12 @@ public class DmpBlueprintController { } @DeleteMapping("{id}") + @OperationWithTenantHeader(summary = "Delete a plan blueprint by id") + @Swagger404 @Transactional - public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException { + public void delete( + @Parameter(name = "id", description = "The id of a plan blueprint to delete", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id + ) throws MyForbiddenException, InvalidApplicationException { logger.debug(new MapLogEntry("retrieving" + DmpBlueprint.class.getSimpleName()).And("id", id)); this.dmpBlueprintService.deleteAndSave(id); @@ -139,7 +188,12 @@ public class DmpBlueprintController { } @GetMapping("clone/{id}") - public DmpBlueprint buildClone(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + @OperationWithTenantHeader(summary = "Clone a plan blueprint by id") + @Swagger404 + public DmpBlueprint buildClone( + @Parameter(name = "id", description = "The id of a plan blueprint to clone", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id, + @Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet + ) throws MyApplicationException, MyForbiddenException, MyNotFoundException { logger.debug(new MapLogEntry("clone" + DmpBlueprint.class.getSimpleName()).And("id", id).And("fields", fieldSet)); this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null); @@ -155,9 +209,15 @@ public class DmpBlueprintController { } @PostMapping("new-version") + @OperationWithTenantHeader(summary = "Create a new version of an existing plan blueprint") + @Swagger400 + @Swagger404 @Transactional @ValidationFilterAnnotation(validator = NewVersionDmpBlueprintPersist.NewVersionDmpBlueprintPersistValidator.ValidatorName, argumentName = "model") - public DmpBlueprint createNewVersion(@RequestBody NewVersionDmpBlueprintPersist model, FieldSet fieldSet) throws JAXBException, InvalidApplicationException, ParserConfigurationException, JsonProcessingException, TransformerException { + public DmpBlueprint createNewVersion( + @RequestBody NewVersionDmpBlueprintPersist model, + @Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet + ) throws JAXBException, InvalidApplicationException, ParserConfigurationException, JsonProcessingException, TransformerException { logger.debug(new MapLogEntry("persisting" + NewVersionDmpBlueprintPersist.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); DmpBlueprint persisted = this.dmpBlueprintService.createNewVersion(model, fieldSet); @@ -170,7 +230,11 @@ public class DmpBlueprintController { } @RequestMapping(method = RequestMethod.GET, value = "/xml/export/{id}", produces = "application/xml") - public @ResponseBody ResponseEntity getXml(@PathVariable UUID id) throws JAXBException, ParserConfigurationException, IOException, TransformerException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException { + @OperationWithTenantHeader(summary = "Export a plan blueprint in xml format by id") + @Swagger404 + public @ResponseBody ResponseEntity getXml( + @Parameter(name = "id", description = "The id of a plan blueprint to export", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable UUID id + ) throws JAXBException, ParserConfigurationException, IOException, TransformerException, InstantiationException, IllegalAccessException, SAXException, InvalidApplicationException { logger.debug(new MapLogEntry("export" + DmpBlueprint.class.getSimpleName()).And("id", id)); ResponseEntity response = this.dmpBlueprintService.exportXml(id); @@ -182,8 +246,13 @@ public class DmpBlueprintController { } @RequestMapping(method = RequestMethod.POST, value = {"/xml/import/{groupId}", "/xml/import"}) + @OperationWithTenantHeader(summary = "Import a plan blueprint from an xml file") @Transactional - public DmpBlueprint importXml(@RequestParam("file") MultipartFile file, @PathVariable(value = "groupId", required = false) UUID groupId, FieldSet fieldSet) throws IOException, JAXBException, InvalidApplicationException, ParserConfigurationException, TransformerException, InstantiationException, IllegalAccessException, SAXException { + public DmpBlueprint importXml( + @RequestParam("file") MultipartFile file, + @Parameter(name = "groupId", description = "The group id of a plan blueprint to import. This is optional.", example = "c0c163dc-2965-45a5-9608-f76030578609") @PathVariable(value = "groupId", required = false) UUID groupId, + @Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet + ) throws IOException, JAXBException, InvalidApplicationException, ParserConfigurationException, TransformerException, InstantiationException, IllegalAccessException, SAXException { logger.debug(new MapLogEntry("clone" + DmpBlueprint.class.getSimpleName()).And("file", file)); this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null); diff --git a/backend/web/src/main/java/org/opencdmp/controllers/EntityDoiController.java b/backend/web/src/main/java/org/opencdmp/controllers/EntityDoiController.java index 616e473c6..9a7760fae 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/EntityDoiController.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/EntityDoiController.java @@ -11,13 +11,25 @@ import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.validation.ValidationFilterAnnotation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; import org.opencdmp.audit.AuditableAction; import org.opencdmp.authorization.AuthorizationFlags; +import org.opencdmp.controllers.swagger.SwaggerHelpers; +import org.opencdmp.controllers.swagger.annotation.OperationWithTenantHeader; +import org.opencdmp.controllers.swagger.annotation.Swagger400; +import org.opencdmp.controllers.swagger.annotation.Swagger404; import org.opencdmp.data.EntityDoiEntity; import org.opencdmp.model.DescriptionTemplateType; import org.opencdmp.model.EntityDoi; import org.opencdmp.model.builder.EntityDoiBuilder; import org.opencdmp.model.censorship.EntityDoiCensor; +import org.opencdmp.model.dmpblueprint.DmpBlueprint; import org.opencdmp.model.persist.EntityDoiPersist; import org.opencdmp.model.result.QueryResult; import org.opencdmp.query.EntityDoiQuery; @@ -34,6 +46,7 @@ import java.util.*; @RestController @RequestMapping(path = "api/entity-doi") +@Tag(name = "Entity DOIs", description = "Manage entity dois") public class EntityDoiController { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(EntityDoiController.class)); @@ -65,6 +78,25 @@ public class EntityDoiController { } @PostMapping("query") + @OperationWithTenantHeader(summary = "Query all entity dois", description = SwaggerHelpers.EntityDoi.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.EntityDoi.endpoint_query_request_body, content = @Content( + examples = { + @ExampleObject( + name = "Pagination and projection", + description = "Simple paginated request using a property projection list and pagination info", + value = SwaggerHelpers.EntityDoi.endpoint_query_request_body_example + ) + } + )), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content( + array = @ArraySchema( + schema = @Schema( + implementation = EntityDoi.class + ) + ), + examples = @ExampleObject( + name = "First page", + description = "Example with the first page of paginated results", + value = SwaggerHelpers.EntityDoi.endpoint_query_response_example + )))) public QueryResult query(@RequestBody EntityDoiLookup lookup) throws MyApplicationException, MyForbiddenException { logger.debug("querying {}", EntityDoi.class.getSimpleName()); @@ -82,7 +114,13 @@ public class EntityDoiController { } @GetMapping("{id}") - public EntityDoi get(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + @OperationWithTenantHeader(summary = "Fetch a specific entity doi by id") + @Swagger404 + public EntityDoi get( + @Parameter(name = "id", description = "The id of an entity doi to fetch", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id, + @Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet, + Locale locale + ) throws MyApplicationException, MyForbiddenException, MyNotFoundException { logger.debug(new MapLogEntry("retrieving" + EntityDoi.class.getSimpleName()).And("id", id).And("fields", fieldSet)); this.censorFactory.censor(EntityDoiCensor.class).censor(fieldSet, null); @@ -101,9 +139,15 @@ public class EntityDoiController { } @PostMapping("persist") + @OperationWithTenantHeader(summary = "Create a new or update an existing entity doi") + @Swagger400 + @Swagger404 @Transactional @ValidationFilterAnnotation(validator = EntityDoiPersist.EntityDoiPersistValidator.ValidatorName, argumentName = "model") - public EntityDoi persist(@RequestBody EntityDoiPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { + public EntityDoi persist( + @RequestBody EntityDoiPersist model, + @Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet + ) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { logger.debug(new MapLogEntry("persisting" + DescriptionTemplateType.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); EntityDoi persisted = this.entityDoiService.persist(model, false, fieldSet); @@ -116,8 +160,12 @@ public class EntityDoiController { } @DeleteMapping("{id}") + @OperationWithTenantHeader(summary = "Delete an entity doi by id") + @Swagger404 @Transactional - public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException { + public void delete( + @Parameter(name = "id", description = "The id of an entity doi to delete", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id + ) throws MyForbiddenException, InvalidApplicationException { logger.debug(new MapLogEntry("retrieving" + EntityDoi.class.getSimpleName()).And("id", id)); this.entityDoiService.deleteAndSave(id); diff --git a/backend/web/src/main/java/org/opencdmp/controllers/swagger/SwaggerHelpers.java b/backend/web/src/main/java/org/opencdmp/controllers/swagger/SwaggerHelpers.java index b08e7c428..c7114e0fa 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/swagger/SwaggerHelpers.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/swagger/SwaggerHelpers.java @@ -2309,6 +2309,243 @@ public class SwaggerHelpers { public static class DmpBlueprint { + public static final String endpoint_query = + """ + This endpoint is used to fetch all the available blueprints for the plans.
+ It also allows to restrict the results using a query object passed in the request body.
+ """; + + public static final String endpoint_query_request_body = + """ + Let's explore the options this object gives us. + + ### General query parameters: + +
    +
  • page: + This is an object controlling the pagination of the results. It contains two properties. +
  • +
      +
    • offset: + How many records to omit. +
    • +
    • size: + How many records to include in each page. +
    • +
    +
+ + For example, if we want the third page, and our pages to contain 15 elements, we would pass the following object: + + ```JSON + { + "offset": 30, + "size": 15 + } + ``` + +
    +
  • order: + This is an object controlling the ordering of the results. + It contains a list of strings called items with the names of the properties to use. +
    If the name of the property is prefixed with a '-', the ordering direction is DESC. Otherwise, it is ASC. +
  • +
+ + For example, if we wanted to order based on the field 'createdAt' in descending order, we would pass the following object: + + ```JSON + { + "items": [ + "-createdAt" + ], + } + ``` + +
    +
  • metadata: + This is an object containing metadata for the request. There is only one available option. +
      +
    • countAll: + If this is set to true, the count property included in the response will account for all the records regardless the pagination, + with all the rest of filtering options applied of course. + Otherwise, if it is set to false or not present, only the returned results will be counted. +
      The first option is useful for the UI clients to calculate how many result pages are available. +
    • +
    +
  • +
  • project: + This is an object controlling the data projection of the results. + It contains a list of strings called fields with the names of the properties to project. +
    You can also include properties that are deeper in the object tree by prefixing them with dots. +
  • +
+ + ### Plan blueprint specific query parameters: + +
    +
  • like: + If there is a like parameter present in the query, only the blueprint entities that include the contents of the parameter in their labels will be in the response. +
  • +
  • ids: + This is a list and contains the ids we want to include in the response.
    If empty, every record is included. +
  • +
  • excludedIds: + This is a list and contains the ids we want to exclude from the response.
    If empty, no record gets excluded. +
  • +
  • groupIds: + This is a list and contains the group ids we want the blueprints to have. Every blueprint and all its versions, have the same groupId.
    If empty, every record is included. +
  • +
  • isActives: + This is a list and determines which records we want to include in the response, based on if they are deleted or not. + This filter works like this. If we want to view only the active records we pass [1] and for only the deleted records we pass [0]. +
    If not present or if we pass [0,1], every record is included. +
  • +
  • statuses: + This is a list and determines which records we want to include in the response, based on their status. + The status can be Draft or Finalized. We add 0 or 1 to the list respectively. +
    If not present, every record is included. +
  • +
  • versionStatuses: + This is a list and determines which records we want to include in the response, based on their version status. + The status can be Current, Previous or NotFinalized. We add 0, 1 or 2 to the list respectively. +
    If not present, every record is included. +
  • +
+ """; + + public static final String endpoint_query_request_body_example = + """ + { + "project":{ + "fields":[ + "id", + "label", + "status", + "version", + "groupId", + "updatedAt", + "createdAt", + "hash", + "isActive", + "belongsToCurrentTenant" + ] + }, + "metadata":{ + "countAll":true + }, + "page":{ + "offset":0, + "size":10 + }, + "isActive":[ + 1 + ], + "order":{ + "items":[ + "-createdAt" + ] + }, + "versionStatuses":[ + 0, + 2 + ] + } + """; + + public static final String endpoint_query_response_example = + """ + { + "items":[ + { + "id":"ef8d828b-a127-4621-8a75-c607ddc441b8", + "label":"Purple blueprint cl.1v.2", + "status":1, + "groupId":"60b43495-4c45-42c6-a9e0-462180b968a5", + "version":2, + "createdAt":"2024-06-19T09:54:19.227934Z", + "updatedAt":"2024-06-19T09:54:25.208065Z", + "isActive":1, + "hash":"1718790865", + "belongsToCurrentTenant":true + }, + { + "id":"ff3d5601-45b1-4211-ab4b-012c344827d7", + "label":"Latvian_Council_of_Science_Blueprint.xml", + "status":0, + "groupId":"63b61613-d864-4f49-9d5b-76b5273d83dc", + "version":2, + "createdAt":"2024-06-19T07:14:37.558442Z", + "updatedAt":"2024-06-19T07:14:37.558442Z", + "isActive":1, + "hash":"1718781277", + "belongsToCurrentTenant":true + }, + { + "id":"4c64705f-ff8b-4135-8dd7-4ad147fb46b2", + "label":"RDA Blueprint", + "status":1, + "groupId":"3c3589e5-5ce0-405e-a754-db9e2c9af371", + "version":1, + "createdAt":"2024-06-14T09:15:27.082540Z", + "updatedAt":"2024-06-14T10:42:50.075378Z", + "isActive":1, + "hash":"1718361770", + "belongsToCurrentTenant":true + }, + { + "id":"bcbbdc41-dbb2-444f-86d3-dd33eda8e0a8", + "label":"University of Bologna", + "status":1, + "groupId":"595efece-365a-43bd-99db-cfa9141bcf94", + "version":1, + "createdAt":"2024-04-11T09:14:09Z", + "updatedAt":"2024-04-11T09:14:40Z", + "isActive":1, + "hash":"1712826880", + "belongsToCurrentTenant":true + }, + { + "id":"eb02f2ae-69fd-456d-8143-6b0a98af64c4", + "label":"Latvian Council of Science Blueprint", + "status":1, + "groupId":"63b61613-d864-4f49-9d5b-76b5273d83dc", + "version":1, + "createdAt":"2024-03-25T12:33:59Z", + "updatedAt":"2024-03-04T10:09:05Z", + "isActive":1, + "hash":"1709546945", + "belongsToCurrentTenant":true + }, + { + "id":"86635178-36a6-484f-9057-a934e4eeecd5", + "label":"Dmp Default Blueprint", + "status":1, + "groupId":"20da24e2-575d-40e5-aea4-0986c982fd9c", + "version":1, + "createdAt":"2024-02-15T10:26:49.804431Z", + "updatedAt":"2024-02-15T10:26:49.804431Z", + "isActive":1, + "hash":"1707992809", + "belongsToCurrentTenant":true + }, + { + "id":"37701076-e0ff-4e4f-95aa-9f3d6a23083a", + "label":"CHIST-ERA", + "status":1, + "groupId":"b7eb5ba1-4cc6-4f74-9eb6-b47a6153cba5", + "version":1, + "createdAt":"2023-10-03T09:00:48Z", + "updatedAt":"2023-10-03T09:01:00Z", + "isActive":1, + "hash":"1696323660", + "belongsToCurrentTenant":true + } + ], + "count":7 + } + """; + } public static class FileTransformer { @@ -2317,6 +2554,267 @@ public class SwaggerHelpers { public static class EntityDoi { + public static final String endpoint_query = + """ + This endpoint is used to fetch all the available entity dois.
+ It also allows to restrict the results using a query object passed in the request body.
+ """; + + public static final String endpoint_query_request_body = + """ + Let's explore the options this object gives us. + + ### General query parameters: + +
    +
  • page: + This is an object controlling the pagination of the results. It contains two properties. +
  • +
      +
    • offset: + How many records to omit. +
    • +
    • size: + How many records to include in each page. +
    • +
    +
+ + For example, if we want the third page, and our pages to contain 15 elements, we would pass the following object: + + ```JSON + { + "offset": 30, + "size": 15 + } + ``` + +
    +
  • order: + This is an object controlling the ordering of the results. + It contains a list of strings called items with the names of the properties to use. +
    If the name of the property is prefixed with a '-', the ordering direction is DESC. Otherwise, it is ASC. +
  • +
+ + For example, if we wanted to order based on the field 'createdAt' in descending order, we would pass the following object: + + ```JSON + { + "items": [ + "-createdAt" + ], + } + ``` + +
    +
  • metadata: + This is an object containing metadata for the request. There is only one available option. +
      +
    • countAll: + If this is set to true, the count property included in the response will account for all the records regardless the pagination, + with all the rest of filtering options applied of course. + Otherwise, if it is set to false or not present, only the returned results will be counted. +
      The first option is useful for the UI clients to calculate how many result pages are available. +
    • +
    +
  • +
  • project: + This is an object controlling the data projection of the results. + It contains a list of strings called fields with the names of the properties to project. +
    You can also include properties that are deeper in the object tree by prefixing them with dots. +
  • +
+ + ### Entity doi specific query parameters: + +
    +
  • ids: + This is a list and contains the ids we want to include in the response.
    If empty, every record is included. +
  • +
  • excludedIds: + This is a list and contains the ids we want to exclude from the response.
    If empty, no record gets excluded. +
  • +
  • isActive: + This is a list and determines which records we want to include in the response, based on if they are deleted or not. + This filter works like this. If we want to view only the active records we pass [1] and for only the deleted records we pass [0]. +
    If not present or if we pass [0,1], every record is included. +
  • +
  • types: + This is a list and determines which records we want to include in the response, based on their type. + The type can only be DMP currently. We add 0 to the list respectively. +
    If not present, every record is included. +
  • +
  • dois: + This is a list and determines which records we want to include in the response, based on their doi string. +
    If not present, every record is included. +
  • +
+ """; + + public static final String endpoint_query_request_body_example = + """ + { + "project":{ + "fields":[ + "id", + "doi", + "entityId", + "entityType", + "repositoryId", + "updatedAt", + "createdAt", + "hash", + "isActive", + "belongsToCurrentTenant" + ] + }, + "metadata":{ + "countAll":true + }, + "page":{ + "offset":0, + "size":10 + }, + "isActive":[ + 1 + ], + "order":{ + "items":[ + "-createdAt" + ] + } + } + """; + + public static final String endpoint_query_response_example = + """ + { + "items":[ + { + "id":"d6a8d517-e7a8-406c-9d47-66189e58236f", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11174908", + "createdAt":"2024-05-10T13:21:26Z", + "updatedAt":"2024-05-10T13:21:26Z", + "isActive":1, + "entityId":"139f4197-1145-4440-ad5a-4f00398da12e", + "hash":"1715347286", + "belongsToCurrentTenant":true + }, + { + "id":"0c486d94-a37f-4042-81a2-7698971cf30a", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11174466", + "createdAt":"2024-05-10T11:43:46Z", + "updatedAt":"2024-05-10T11:43:46Z", + "isActive":1, + "entityId":"4a8a6642-5de6-4de5-b257-5c119109607a", + "hash":"1715341426", + "belongsToCurrentTenant":true + }, + { + "id":"ad850e47-ce75-465f-ad29-d394dda531b1", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11161991", + "createdAt":"2024-05-09T10:39:10Z", + "updatedAt":"2024-05-09T10:39:10Z", + "isActive":1, + "entityId":"5089fa85-76e2-46e6-b7e5-82bf62f66d13", + "hash":"1715251150", + "belongsToCurrentTenant":true + }, + { + "id":"5c356559-872d-4f07-bafd-197c92df1564", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11152565", + "createdAt":"2024-05-08T18:11:24Z", + "updatedAt":"2024-05-08T18:11:24Z", + "isActive":1, + "entityId":"e36915dc-6496-4b35-b9c4-37576dc08389", + "hash":"1715191884", + "belongsToCurrentTenant":true + }, + { + "id":"05bb9602-b640-428b-a9b0-74025bece4ee", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11091371", + "createdAt":"2024-04-30T08:58:34Z", + "updatedAt":"2024-04-30T08:58:34Z", + "isActive":1, + "entityId":"8d1f813b-ad96-4449-a197-7dc828a6598d", + "hash":"1714467514", + "belongsToCurrentTenant":true + }, + { + "id":"9402523a-1836-4464-a9b2-4ac1c61493cc", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11082522", + "createdAt":"2024-04-29T07:53:04Z", + "updatedAt":"2024-04-29T07:53:04Z", + "isActive":1, + "entityId":"a092bbca-1dbe-4095-a3b9-ba65c7b85e13", + "hash":"1714377184", + "belongsToCurrentTenant":true + }, + { + "id":"85c58f3b-5063-4ddf-a1ab-426268c55565", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11082395", + "createdAt":"2024-04-29T07:28:04Z", + "updatedAt":"2024-04-29T07:28:04Z", + "isActive":1, + "entityId":"c0df9b41-5166-44a6-bdd9-12e0f7b6d5c7", + "hash":"1714375684", + "belongsToCurrentTenant":true + }, + { + "id":"72284e9e-cdf4-4d57-ac8d-59e3ed5bef9a", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11082383", + "createdAt":"2024-04-29T07:25:07Z", + "updatedAt":"2024-04-29T07:25:07Z", + "isActive":1, + "entityId":"e8e93ea4-e983-4299-a1ea-fd3a75c95ef5", + "hash":"1714375507", + "belongsToCurrentTenant":true + }, + { + "id":"ecf6fb11-58f0-42d5-a127-d263703dcd92", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11082161", + "createdAt":"2024-04-29T06:51:43Z", + "updatedAt":"2024-04-29T06:51:43Z", + "isActive":1, + "entityId":"6a4b7b4f-7507-4c52-9356-1f652f2cc430", + "hash":"1714373503", + "belongsToCurrentTenant":true + }, + { + "id":"4ce9b1e6-1e58-48c3-ae80-2ef09f1ef2d0", + "entityType":0, + "repositoryId":"Zenodo", + "doi":"10.5281/zenodo.11081970", + "createdAt":"2024-04-29T05:42:35Z", + "updatedAt":"2024-04-29T05:42:35Z", + "isActive":1, + "entityId":"15e2c0ce-e65a-4c4b-9dfc-1393f042081c", + "hash":"1714369355", + "belongsToCurrentTenant":true + } + ], + "count":118 + } + """; } public static class Deposit { diff --git a/backend/web/src/main/resources/config/swagger.yml b/backend/web/src/main/resources/config/swagger.yml index ac2bd06c4..0310255b0 100644 --- a/backend/web/src/main/resources/config/swagger.yml +++ b/backend/web/src/main/resources/config/swagger.yml @@ -11,7 +11,7 @@ springdoc: displayName: Current packagesToScan: org.opencdmp.controllers packagesToExclude: org.opencdmp.controllers.publicapi - pathsToMatch: "/api/dmp/**, /api/description/**, /api/description-template/**, /api/description-template-type/**" + pathsToMatch: "/api/dmp/**, /api/description/**, /api/description-template/**, /api/description-template-type/**, /api/dmp-blueprint/**, /api/entity-doi/**" swaggerUi: enabled: true useRootPath: true