Adding swagger docs for entity dois and dmp blueprints

This commit is contained in:
Thomas Georgios Giannos 2024-06-26 13:04:31 +03:00
parent 0c65df40e6
commit 4f24049582
4 changed files with 626 additions and 11 deletions

View File

@ -12,11 +12,24 @@ import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidationFilterAnnotation; 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.transaction.Transactional;
import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.JAXBException;
import org.opencdmp.audit.AuditableAction; import org.opencdmp.audit.AuditableAction;
import org.opencdmp.authorization.AuthorizationFlags; 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.data.DmpBlueprintEntity;
import org.opencdmp.model.DescriptionTemplateType;
import org.opencdmp.model.builder.dmpblueprint.DmpBlueprintBuilder; import org.opencdmp.model.builder.dmpblueprint.DmpBlueprintBuilder;
import org.opencdmp.model.censorship.dmpblueprint.DmpBlueprintCensor; import org.opencdmp.model.censorship.dmpblueprint.DmpBlueprintCensor;
import org.opencdmp.model.dmpblueprint.DmpBlueprint; import org.opencdmp.model.dmpblueprint.DmpBlueprint;
@ -45,6 +58,8 @@ import java.util.UUID;
@RestController @RestController
@RequestMapping(path = "api/dmp-blueprint") @RequestMapping(path = "api/dmp-blueprint")
@Tag(name = "Plan Blueprints", description = "Manage plan blueprints")
@SwaggerCommonErrorResponses
public class DmpBlueprintController { public class DmpBlueprintController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpBlueprintController.class)); private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpBlueprintController.class));
@ -77,6 +92,25 @@ public class DmpBlueprintController {
} }
@PostMapping("query") @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<DmpBlueprint> query(@RequestBody DmpBlueprintLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<DmpBlueprint> query(@RequestBody DmpBlueprintLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", DmpBlueprint.class.getSimpleName()); logger.debug("querying {}", DmpBlueprint.class.getSimpleName());
@ -93,7 +127,12 @@ public class DmpBlueprintController {
} }
@GetMapping("{id}") @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)); logger.debug(new MapLogEntry("retrieving" + DmpBlueprint.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null); this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null);
@ -112,9 +151,15 @@ public class DmpBlueprintController {
} }
@PostMapping("persist") @PostMapping("persist")
@OperationWithTenantHeader(summary = "Create a new or update an existing plan blueprint")
@Swagger400
@Swagger404
@Transactional @Transactional
@ValidationFilterAnnotation(validator = DmpBlueprintPersist.DmpBlueprintPersistValidator.ValidatorName, argumentName = "model") @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)); logger.debug(new MapLogEntry("persisting" + DmpBlueprint.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null); this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null);
@ -129,8 +174,12 @@ public class DmpBlueprintController {
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@OperationWithTenantHeader(summary = "Delete a plan blueprint by id")
@Swagger404
@Transactional @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)); logger.debug(new MapLogEntry("retrieving" + DmpBlueprint.class.getSimpleName()).And("id", id));
this.dmpBlueprintService.deleteAndSave(id); this.dmpBlueprintService.deleteAndSave(id);
@ -139,7 +188,12 @@ public class DmpBlueprintController {
} }
@GetMapping("clone/{id}") @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)); logger.debug(new MapLogEntry("clone" + DmpBlueprint.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null); this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null);
@ -155,9 +209,15 @@ public class DmpBlueprintController {
} }
@PostMapping("new-version") @PostMapping("new-version")
@OperationWithTenantHeader(summary = "Create a new version of an existing plan blueprint")
@Swagger400
@Swagger404
@Transactional @Transactional
@ValidationFilterAnnotation(validator = NewVersionDmpBlueprintPersist.NewVersionDmpBlueprintPersistValidator.ValidatorName, argumentName = "model") @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)); logger.debug(new MapLogEntry("persisting" + NewVersionDmpBlueprintPersist.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
DmpBlueprint persisted = this.dmpBlueprintService.createNewVersion(model, 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") @RequestMapping(method = RequestMethod.GET, value = "/xml/export/{id}", produces = "application/xml")
public @ResponseBody ResponseEntity<byte[]> 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<byte[]> 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)); logger.debug(new MapLogEntry("export" + DmpBlueprint.class.getSimpleName()).And("id", id));
ResponseEntity<byte[]> response = this.dmpBlueprintService.exportXml(id); ResponseEntity<byte[]> response = this.dmpBlueprintService.exportXml(id);
@ -182,8 +246,13 @@ public class DmpBlueprintController {
} }
@RequestMapping(method = RequestMethod.POST, value = {"/xml/import/{groupId}", "/xml/import"}) @RequestMapping(method = RequestMethod.POST, value = {"/xml/import/{groupId}", "/xml/import"})
@OperationWithTenantHeader(summary = "Import a plan blueprint from an xml file")
@Transactional @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)); logger.debug(new MapLogEntry("clone" + DmpBlueprint.class.getSimpleName()).And("file", file));
this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null); this.censorFactory.censor(DmpBlueprintCensor.class).censor(fieldSet, null);

View File

@ -11,13 +11,25 @@ import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidationFilterAnnotation; 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.audit.AuditableAction;
import org.opencdmp.authorization.AuthorizationFlags; 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.data.EntityDoiEntity;
import org.opencdmp.model.DescriptionTemplateType; import org.opencdmp.model.DescriptionTemplateType;
import org.opencdmp.model.EntityDoi; import org.opencdmp.model.EntityDoi;
import org.opencdmp.model.builder.EntityDoiBuilder; import org.opencdmp.model.builder.EntityDoiBuilder;
import org.opencdmp.model.censorship.EntityDoiCensor; import org.opencdmp.model.censorship.EntityDoiCensor;
import org.opencdmp.model.dmpblueprint.DmpBlueprint;
import org.opencdmp.model.persist.EntityDoiPersist; import org.opencdmp.model.persist.EntityDoiPersist;
import org.opencdmp.model.result.QueryResult; import org.opencdmp.model.result.QueryResult;
import org.opencdmp.query.EntityDoiQuery; import org.opencdmp.query.EntityDoiQuery;
@ -34,6 +46,7 @@ import java.util.*;
@RestController @RestController
@RequestMapping(path = "api/entity-doi") @RequestMapping(path = "api/entity-doi")
@Tag(name = "Entity DOIs", description = "Manage entity dois")
public class EntityDoiController { public class EntityDoiController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(EntityDoiController.class)); private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(EntityDoiController.class));
@ -65,6 +78,25 @@ public class EntityDoiController {
} }
@PostMapping("query") @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<EntityDoi> query(@RequestBody EntityDoiLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<EntityDoi> query(@RequestBody EntityDoiLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", EntityDoi.class.getSimpleName()); logger.debug("querying {}", EntityDoi.class.getSimpleName());
@ -82,7 +114,13 @@ public class EntityDoiController {
} }
@GetMapping("{id}") @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)); logger.debug(new MapLogEntry("retrieving" + EntityDoi.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(EntityDoiCensor.class).censor(fieldSet, null); this.censorFactory.censor(EntityDoiCensor.class).censor(fieldSet, null);
@ -101,9 +139,15 @@ public class EntityDoiController {
} }
@PostMapping("persist") @PostMapping("persist")
@OperationWithTenantHeader(summary = "Create a new or update an existing entity doi")
@Swagger400
@Swagger404
@Transactional @Transactional
@ValidationFilterAnnotation(validator = EntityDoiPersist.EntityDoiPersistValidator.ValidatorName, argumentName = "model") @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)); logger.debug(new MapLogEntry("persisting" + DescriptionTemplateType.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
EntityDoi persisted = this.entityDoiService.persist(model, false, fieldSet); EntityDoi persisted = this.entityDoiService.persist(model, false, fieldSet);
@ -116,8 +160,12 @@ public class EntityDoiController {
} }
@DeleteMapping("{id}") @DeleteMapping("{id}")
@OperationWithTenantHeader(summary = "Delete an entity doi by id")
@Swagger404
@Transactional @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)); logger.debug(new MapLogEntry("retrieving" + EntityDoi.class.getSimpleName()).And("id", id));
this.entityDoiService.deleteAndSave(id); this.entityDoiService.deleteAndSave(id);

View File

@ -2309,6 +2309,243 @@ public class SwaggerHelpers {
public static class DmpBlueprint { public static class DmpBlueprint {
public static final String endpoint_query =
"""
This endpoint is used to fetch all the available blueprints for the plans.<br/>
It also allows to restrict the results using a query object passed in the request body.<br/>
""";
public static final String endpoint_query_request_body =
"""
Let's explore the options this object gives us.
### <u>General query parameters:</u>
<ul>
<li><b>page:</b>
This is an object controlling the pagination of the results. It contains two properties.
</li>
<ul>
<li><b>offset:</b>
How many records to omit.
</li>
<li><b>size:</b>
How many records to include in each page.
</li>
</ul>
</ul>
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
}
```
<ul>
<li><b>order:</b>
This is an object controlling the ordering of the results.
It contains a list of strings called <i>items</i> with the names of the properties to use.
<br/>If the name of the property is prefixed with a <b>'-'</b>, the ordering direction is <b>DESC</b>. Otherwise, it is <b>ASC</b>.
</li>
</ul>
For example, if we wanted to order based on the field 'createdAt' in descending order, we would pass the following object:
```JSON
{
"items": [
"-createdAt"
],
}
```
<ul>
<li><b>metadata:</b>
This is an object containing metadata for the request. There is only one available option.
<ul>
<li><b>countAll:</b>
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.
<br/>The first option is useful for the UI clients to calculate how many result pages are available.
</li>
</ul>
</li>
<li><b>project:</b>
This is an object controlling the data projection of the results.
It contains a list of strings called <i>fields</i> with the names of the properties to project.
<br/>You can also include properties that are deeper in the object tree by prefixing them with dots.
</li>
</ul>
### <u>Plan blueprint specific query parameters:</u>
<ul>
<li><b>like:</b>
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.
</li>
<li><b>ids:</b>
This is a list and contains the ids we want to include in the response. <br/>If empty, every record is included.
</li>
<li><b>excludedIds:</b>
This is a list and contains the ids we want to exclude from the response. <br/>If empty, no record gets excluded.
</li>
<li><b>groupIds:</b>
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. <br/>If empty, every record is included.
</li>
<li><b>isActives:</b>
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].
<br/>If not present or if we pass [0,1], every record is included.
</li>
<li><b>statuses:</b>
This is a list and determines which records we want to include in the response, based on their status.
The status can be <i>Draft</i> or <i>Finalized</i>. We add 0 or 1 to the list respectively.
<br/>If not present, every record is included.
</li>
<li><b>versionStatuses:</b>
This is a list and determines which records we want to include in the response, based on their version status.
The status can be <i>Current</i>, <i>Previous</i> or <i>NotFinalized</i>. We add 0, 1 or 2 to the list respectively.
<br/>If not present, every record is included.
</li>
</ul>
""";
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 { public static class FileTransformer {
@ -2317,6 +2554,267 @@ public class SwaggerHelpers {
public static class EntityDoi { public static class EntityDoi {
public static final String endpoint_query =
"""
This endpoint is used to fetch all the available entity dois.<br/>
It also allows to restrict the results using a query object passed in the request body.<br/>
""";
public static final String endpoint_query_request_body =
"""
Let's explore the options this object gives us.
### <u>General query parameters:</u>
<ul>
<li><b>page:</b>
This is an object controlling the pagination of the results. It contains two properties.
</li>
<ul>
<li><b>offset:</b>
How many records to omit.
</li>
<li><b>size:</b>
How many records to include in each page.
</li>
</ul>
</ul>
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
}
```
<ul>
<li><b>order:</b>
This is an object controlling the ordering of the results.
It contains a list of strings called <i>items</i> with the names of the properties to use.
<br/>If the name of the property is prefixed with a <b>'-'</b>, the ordering direction is <b>DESC</b>. Otherwise, it is <b>ASC</b>.
</li>
</ul>
For example, if we wanted to order based on the field 'createdAt' in descending order, we would pass the following object:
```JSON
{
"items": [
"-createdAt"
],
}
```
<ul>
<li><b>metadata:</b>
This is an object containing metadata for the request. There is only one available option.
<ul>
<li><b>countAll:</b>
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.
<br/>The first option is useful for the UI clients to calculate how many result pages are available.
</li>
</ul>
</li>
<li><b>project:</b>
This is an object controlling the data projection of the results.
It contains a list of strings called <i>fields</i> with the names of the properties to project.
<br/>You can also include properties that are deeper in the object tree by prefixing them with dots.
</li>
</ul>
### <u>Entity doi specific query parameters:</u>
<ul>
<li><b>ids:</b>
This is a list and contains the ids we want to include in the response. <br/>If empty, every record is included.
</li>
<li><b>excludedIds:</b>
This is a list and contains the ids we want to exclude from the response. <br/>If empty, no record gets excluded.
</li>
<li><b>isActive:</b>
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].
<br/>If not present or if we pass [0,1], every record is included.
</li>
<li><b>types:</b>
This is a list and determines which records we want to include in the response, based on their type.
The type can only be <i>DMP</i> currently. We add 0 to the list respectively.
<br/>If not present, every record is included.
</li>
<li><b>dois:</b>
This is a list and determines which records we want to include in the response, based on their doi string.
<br/>If not present, every record is included.
</li>
</ul>
""";
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 { public static class Deposit {

View File

@ -11,7 +11,7 @@ springdoc:
displayName: Current displayName: Current
packagesToScan: org.opencdmp.controllers packagesToScan: org.opencdmp.controllers
packagesToExclude: org.opencdmp.controllers.publicapi 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: swaggerUi:
enabled: true enabled: true
useRootPath: true useRootPath: true