Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Sofia Papacharalampous 2024-06-24 17:44:42 +03:00
commit 9f9638531a
7 changed files with 759 additions and 70 deletions

View File

@ -2,7 +2,6 @@ package org.opencdmp.configurations;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

View File

@ -12,9 +12,7 @@ import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidationFilterAnnotation;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
@ -28,10 +26,10 @@ import org.opencdmp.commons.enums.DmpAccessType;
import org.opencdmp.commons.enums.DmpStatus;
import org.opencdmp.commons.enums.IsActive;
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.controllers.swagger.annotation.OperationWithTenantHeader;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.StorageFileEntity;
import org.opencdmp.model.DescriptionValidationResult;
@ -96,10 +94,15 @@ public class DescriptionController {
private final QueryFactory queryFactory;
private final MessageSource messageSource;
private final ElasticQueryHelperService elasticQueryHelperService;
private final StorageFileService storageFileService;
private final ConventionService conventionService;
private final FieldSetExpanderService fieldSetExpanderService;
public DescriptionController(
BuilderFactory builderFactory,
AuditService auditService,
@ -148,7 +151,8 @@ public class DescriptionController {
DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).disableTracking().authorize(EnumSet.of(Public)).ids(id).dmpSubQuery(this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).statuses(DmpStatus.Finalized).accessTypes(DmpAccessType.Public));
PublicDescription model = this.builderFactory.builder(PublicDescriptionBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet));
if (model == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, PublicDescription.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (model == null)
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, PublicDescription.class.getSimpleName()}, LocaleContextHolder.getLocale()));
this.auditService.track(AuditableAction.Description_PublicLookup, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", id),
@ -167,7 +171,13 @@ public class DescriptionController {
value = SwaggerHelpers.Description.endpoint_query_request_body_example
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(examples = @ExampleObject(
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = Description.class
)
),
examples = @ExampleObject(
name = "First page",
description = "Example with the first page of paginated results",
value = SwaggerHelpers.Description.endpoint_query_response_example
@ -184,7 +194,6 @@ public class DescriptionController {
return queryResult;
}
@GetMapping("{id}")
@OperationWithTenantHeader(summary = "Fetch a specific description by id")
@Swagger404
@ -350,14 +359,16 @@ public class DescriptionController {
StorageFileEntity storageFile = this.descriptionService.getFieldFile(id, fileId);
byte[] file = this.storageFileService.readAsBytesSafe(id);
if (file == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, StorageFile.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (file == null)
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, StorageFile.class.getSimpleName()}, LocaleContextHolder.getLocale()));
this.auditService.track(AuditableAction.Description_GetFieldFile, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", id)
));
String contentType = storageFile.getMimeType();
if (this.conventionService.isNullOrEmpty(contentType)) contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
if (this.conventionService.isNullOrEmpty(contentType))
contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
return ResponseEntity.ok()
.contentType(MediaType.valueOf(contentType))

View File

@ -13,9 +13,21 @@ 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.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.DescriptionTemplateEntity;
import org.opencdmp.model.builder.descriptiontemplate.DescriptionTemplateBuilder;
import org.opencdmp.model.censorship.descriptiontemplate.DescriptionTemplateCensor;
@ -49,6 +61,8 @@ import java.util.UUID;
@RestController
@RequestMapping(path = "api/description-template")
@Tag(name = "Description Templates", description = "Manage description templates")
@SwaggerCommonErrorResponses
public class DescriptionTemplateController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateController.class));
@ -64,6 +78,7 @@ public class DescriptionTemplateController {
private final QueryFactory queryFactory;
private final MessageSource messageSource;
private final FieldSetExpanderService fieldSetExpanderService;
public DescriptionTemplateController(
@ -83,6 +98,25 @@ public class DescriptionTemplateController {
}
@PostMapping("query")
@OperationWithTenantHeader(summary = "Query all description templates", description = SwaggerHelpers.DescriptionTemplate.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.DescriptionTemplate.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.DescriptionTemplate.endpoint_query_request_body_example
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = DescriptionTemplate.class
)
),
examples = @ExampleObject(
name = "First page",
description = "Example with the first page of paginated results",
value = SwaggerHelpers.DescriptionTemplate.endpoint_query_response_example
))))
public QueryResult<DescriptionTemplate> query(@RequestBody DescriptionTemplateLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", DescriptionTemplate.class.getSimpleName());
@ -100,7 +134,12 @@ public class DescriptionTemplateController {
}
@GetMapping("{id}")
public DescriptionTemplate get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
@OperationWithTenantHeader(summary = "Fetch a specific description template by id")
@Swagger404
public DescriptionTemplate get(
@Parameter(name = "id", description = "The id of a description template 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" + DescriptionTemplate.class.getSimpleName()).And("id", id).And("fields", fieldSet));
fieldSet = this.fieldSetExpanderService.expand(fieldSet);
@ -120,9 +159,15 @@ public class DescriptionTemplateController {
}
@PostMapping("persist")
@OperationWithTenantHeader(summary = "Create a new or update an existing description template")
@Swagger400
@Swagger404
@Transactional
@ValidationFilterAnnotation(validator = DescriptionTemplatePersist.DescriptionTemplatePersistValidator.ValidatorName, argumentName = "model")
public DescriptionTemplate persist(@RequestBody DescriptionTemplatePersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
public DescriptionTemplate persist(
@RequestBody DescriptionTemplatePersist 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" + DescriptionTemplate.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
fieldSet = this.fieldSetExpanderService.expand(fieldSet);
new BaseFieldSet(fieldSet.getFields()).ensure(DescriptionTemplate._id);
@ -137,8 +182,12 @@ public class DescriptionTemplateController {
}
@DeleteMapping("{id}")
@OperationWithTenantHeader(summary = "Delete a description template 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 description template to delete", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id
) throws MyForbiddenException, InvalidApplicationException {
logger.debug(new MapLogEntry("retrieving" + DescriptionTemplate.class.getSimpleName()).And("id", id));
this.descriptionTemplateTypeService.deleteAndSave(id);
@ -147,7 +196,12 @@ public class DescriptionTemplateController {
}
@GetMapping("clone/{id}")
public DescriptionTemplate buildClone(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
@OperationWithTenantHeader(summary = "Clone a description template by id")
@Swagger404
public DescriptionTemplate buildClone(
@Parameter(name = "id", description = "The id of a description template 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));
fieldSet = this.fieldSetExpanderService.expand(fieldSet);
@ -164,9 +218,15 @@ public class DescriptionTemplateController {
}
@PostMapping("new-version")
@OperationWithTenantHeader(summary = "Create a new version of a description template")
@Swagger400
@Swagger404
@Transactional
@ValidationFilterAnnotation(validator = NewVersionDescriptionTemplatePersist.NewVersionDescriptionTemplatePersistValidator.ValidatorName, argumentName = "model")
public DescriptionTemplate createNewVersion(@RequestBody NewVersionDescriptionTemplatePersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException {
public DescriptionTemplate createNewVersion(
@RequestBody NewVersionDescriptionTemplatePersist 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" + NewVersionDescriptionTemplatePersist.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
fieldSet = this.fieldSetExpanderService.expand(fieldSet);
DescriptionTemplate persisted = this.descriptionTemplateTypeService.createNewVersion(model, fieldSet);
@ -180,7 +240,11 @@ public class DescriptionTemplateController {
}
@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 description template in xml by id")
@Swagger404
public @ResponseBody ResponseEntity<byte[]> getXml(
@Parameter(name = "id", description = "The id of a description template 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" + DescriptionTemplate.class.getSimpleName()).And("id", id));
ResponseEntity<byte[]> response = this.descriptionTemplateTypeService.exportXml(id);
@ -193,8 +257,13 @@ public class DescriptionTemplateController {
}
@RequestMapping(method = RequestMethod.POST, value = {"/xml/import/{groupId}", "/xml/import"})
@OperationWithTenantHeader(summary = "Import a description template from an xml file")
@Transactional
public DescriptionTemplate importXml(@RequestParam("file") MultipartFile file, @PathVariable(value = "groupId", required = false) UUID groupId, FieldSet fieldSet) throws IOException, JAXBException, InvalidApplicationException, ParserConfigurationException, TransformerException, InstantiationException, IllegalAccessException, SAXException {
public DescriptionTemplate importXml(
@RequestParam("file") MultipartFile file,
@Parameter(name = "groupId", description = "The group id of a description template 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("import" + DescriptionTemplate.class.getSimpleName()).And("file", file).And("groupId", groupId));
fieldSet = this.fieldSetExpanderService.expand(fieldSet);

View File

@ -11,8 +11,20 @@ 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.controllers.swagger.annotation.SwaggerCommonErrorResponses;
import org.opencdmp.data.DescriptionTemplateTypeEntity;
import org.opencdmp.model.DescriptionTemplateType;
import org.opencdmp.model.builder.DescriptionTemplateTypeBuilder;
@ -33,10 +45,14 @@ import java.util.*;
@RestController
@RequestMapping(path = "api/description-template-type")
@Tag(name = "Description Template Types", description = "Manage description template types")
@SwaggerCommonErrorResponses
public class DescriptionTemplateTypeController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeController.class));
private final BuilderFactory builderFactory;
private final AuditService auditService;
private final DescriptionTemplateTypeService descriptionTemplateTypeService;
@ -63,6 +79,25 @@ public class DescriptionTemplateTypeController {
}
@PostMapping("query")
@OperationWithTenantHeader(summary = "Query all description template types", description = SwaggerHelpers.DescriptionTemplateType.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.DescriptionTemplateType.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.DescriptionTemplateType.endpoint_query_request_body_example
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = DescriptionTemplateType.class
)
),
examples = @ExampleObject(
name = "First page",
description = "Example with the first page of paginated results",
value = SwaggerHelpers.DescriptionTemplateType.endpoint_query_response_example
))))
public QueryResult<DescriptionTemplateType> Query(@RequestBody DescriptionTemplateTypeLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", DescriptionTemplateType.class.getSimpleName());
@ -81,7 +116,12 @@ public class DescriptionTemplateTypeController {
}
@GetMapping("{id}")
public DescriptionTemplateType Get(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
@OperationWithTenantHeader(summary = "Fetch a specific description template type by id")
@Swagger404
public DescriptionTemplateType Get(
@Parameter(name = "id", description = "The id of a description template type 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" + DescriptionTemplateType.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(DescriptionTemplateTypeCensor.class).censor(fieldSet, null);
@ -101,9 +141,15 @@ public class DescriptionTemplateTypeController {
}
@PostMapping("persist")
@OperationWithTenantHeader(summary = "Create a new or update an existing description template type")
@Swagger400
@Swagger404
@Transactional
@ValidationFilterAnnotation(validator = DescriptionTemplateTypePersist.DescriptionTemplateTypePersistValidator.ValidatorName, argumentName = "model")
public DescriptionTemplateType Persist(@RequestBody DescriptionTemplateTypePersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
public DescriptionTemplateType Persist(
@RequestBody DescriptionTemplateTypePersist 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));
DescriptionTemplateType persisted = this.descriptionTemplateTypeService.persist(model, fieldSet);
@ -116,8 +162,12 @@ public class DescriptionTemplateTypeController {
}
@DeleteMapping("{id}")
@OperationWithTenantHeader(summary = "Delete a description template type 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 description template type to delete", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id
) throws MyForbiddenException, InvalidApplicationException {
logger.debug(new MapLogEntry("retrieving" + DescriptionTemplateType.class.getSimpleName()).And("id", id));
this.descriptionTemplateTypeService.deleteAndSave(id);

View File

@ -11,9 +11,7 @@ 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.annotations.ApiImplicitParam;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
@ -149,11 +147,15 @@ public class DmpController {
}
@PostMapping("query")
@OperationWithTenantHeader(summary = "Query all plans", description = SwaggerHelpers.Dmp.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Dmp.endpoint_query_request_body, content = @Content(examples = @ExampleObject(
@OperationWithTenantHeader(summary = "Query all plans", description = SwaggerHelpers.Dmp.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Dmp.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.Dmp.endpoint_query_request_body_example
))), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = Dmp.class

View File

@ -903,11 +903,6 @@ public class SwaggerHelpers {
"count":2912
}
""";
public static final String endpoint_ =
"""
""";
}
public static class Description {
@ -1765,4 +1760,567 @@ public class SwaggerHelpers {
""";
}
public static class DescriptionTemplate {
public static final String endpoint_query =
"""
This endpoint is used to fetch all the available description templates.<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>Description template specific query parameters:</u>
<ul>
<li><b>like:</b>
If there is a like parameter present in the query, only the description template entities that include the contents of the parameter either in their labels or the descriptions 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 templates to have. Every template and all its versions, have the same groupId. <br/>If empty, every record is included.
</li>
<li><b>excludedGroupIds:</b>
This is a list and contains the group ids we want the templates not to have. Every template and all its versions, have the same groupId. <br/>If empty, no record gets excluded.
</li>
<li><b>typeIds:</b>
This is a list and contains the type ids we want the templates to have. Every template has a type designated by a type id. <br/>If empty, every record is included.
</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>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>
<li><b>onlyCanEdit:</b>
This is a boolean and determines whether to fetch only the templates the user can edit or every one.
<br/>If not present, every record is included.
</li>
</ul>
""";
public static final String endpoint_query_request_body_example =
"""
{
"project":{
"fields":[
"id",
"label",
"description",
"status",
"version",
"groupId",
"updatedAt",
"createdAt",
"hash",
"belongsToCurrentTenant",
"isActive",
"authorizationFlags.EditDescriptionTemplate",
"authorizationFlags.DeleteDescriptionTemplate",
"authorizationFlags.CloneDescriptionTemplate",
"authorizationFlags.CreateNewVersionDescriptionTemplate",
"authorizationFlags.ImportDescriptionTemplate",
"authorizationFlags.ExportDescriptionTemplate"
]
},
"metadata":{
"countAll":true
},
"page":{
"offset":0,
"size":10
},
"isActive":[
1
],
"order":{
"items":[
"-createdAt"
]
},
"versionStatuses":[
0,
2
],
"onlyCanEdit":true
}
""";
public static final String endpoint_query_response_example =
"""
{
"items":[
{
"id":"fbbea99b-9259-430b-9f1b-c78f3df8a07c",
"label":"url",
"description":"zxccx",
"groupId":"71d1b878-9980-4b35-b58d-98597e1f2579",
"version":1,
"createdAt":"2024-06-21T13:13:38.344835Z",
"updatedAt":"2024-06-21T13:13:43.001378Z",
"isActive":1,
"status":1,
"hash":"1718975623",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"6d2c5983-6125-4fc0-833a-3618d35d0c72",
"label":"to-delete",
"description":"test",
"groupId":"95fc6c79-ee17-4cd9-bad7-0d70ce17b9a4",
"version":1,
"createdAt":"2024-06-21T10:22:33.116729Z",
"updatedAt":"2024-06-21T10:22:52.668175Z",
"isActive":1,
"status":0,
"hash":"1718965372",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"e0cb75fe-6f3b-4770-8857-f6b3de9d5411",
"label":"Test Purple Roles",
"description":"Test Purple Roles",
"groupId":"bd3159c7-0b42-431c-8c0f-b353c1343b79",
"version":1,
"createdAt":"2024-06-19T09:53:10.567662Z",
"updatedAt":"2024-06-19T09:53:18.122353Z",
"isActive":1,
"status":1,
"hash":"1718790798",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"17eeb5ef-0f2a-40bb-b9b3-4e89a749a08a",
"label":"Purple_template_1.xml",
"description":"Desc",
"groupId":"419bbe42-91e0-4ba4-97cf-c9502063a7ef",
"version":1,
"createdAt":"2024-06-19T09:30:34.925496Z",
"updatedAt":"2024-06-19T09:31:05.429197Z",
"isActive":1,
"status":1,
"hash":"1718789465",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"9f6bd3bc-b611-4641-bceb-2e64b0bd34cd",
"label":"RDA_test_new_.xml",
"description":"RDA test",
"groupId":"3c88259f-4b16-4fc3-adf2-cee2ea4b882d",
"version":2,
"createdAt":"2024-06-19T07:14:11.748649Z",
"updatedAt":"2024-06-19T07:14:11.748649Z",
"isActive":1,
"status":0,
"hash":"1718781251",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"212342fe-ab6f-4604-b80e-ac23aca93c76",
"label":"RDA test with fix multiplicity1",
"description":"RDA test",
"groupId":"4ff3e924-8623-4b58-a61b-94740b67c4aa",
"version":1,
"createdAt":"2024-06-18T14:04:55.574099Z",
"updatedAt":"2024-06-20T10:45:35.188002Z",
"isActive":1,
"status":1,
"hash":"1718880335",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"dddf404e-da59-4097-86d9-29f085ee40da",
"label":"RDA test new ",
"description":"RDA test",
"groupId":"3c88259f-4b16-4fc3-adf2-cee2ea4b882d",
"version":1,
"createdAt":"2024-06-17T12:09:24.296094Z",
"updatedAt":"2024-06-17T12:20:40.432586Z",
"isActive":1,
"status":1,
"hash":"1718626840",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"fa67ecbf-c3b4-4e19-b531-764cf7b4d508",
"label":"test",
"description":"test",
"groupId":"bd1a655e-a47b-4edc-a9a2-214dc2971c12",
"version":1,
"createdAt":"2024-06-17T08:41:36.664047Z",
"updatedAt":"2024-06-17T08:41:36.678049Z",
"isActive":1,
"status":0,
"hash":"1718613696",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"54527748-7c8a-4045-8b8e-f7be65900302",
"label":"RDA test",
"description":"RDA test",
"groupId":"bf36f613-422a-4d4a-aee1-8a377157f265",
"version":1,
"createdAt":"2024-06-14T08:10:55.988008Z",
"updatedAt":"2024-06-14T10:42:17.438789Z",
"isActive":1,
"status":1,
"hash":"1718361737",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
},
{
"id":"d2f41a59-d369-431d-bf3a-eb29fb4423e7",
"label":"CHIST-ERA Data Management",
"description":"This is a DMP template created based on the CHIST-ERA RDM policy and DMP template.",
"groupId":"c8ef1ecc-f0a6-4f06-a62d-2769968c3d0a",
"version":3,
"createdAt":"2024-04-17T16:58:57Z",
"updatedAt":"2024-04-17T16:58:57Z",
"isActive":1,
"status":1,
"hash":"1713373137",
"authorizationFlags":[
"CreateNewVersionDescriptionTemplate",
"CloneDescriptionTemplate",
"ImportDescriptionTemplate",
"DeleteDescriptionTemplate",
"EditDescriptionTemplate",
"ExportDescriptionTemplate"
],
"belongsToCurrentTenant":true
}
],
"count":40
}
""";
}
public static class DescriptionTemplateType {
public static final String endpoint_query =
"""
This endpoint is used to fetch all the available description template types.<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>Description template type specific query parameters:</u>
<ul>
<li><b>like:</b>
If there is a like parameter present in the query, only the description template type 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>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>
</ul>
""";
public static final String endpoint_query_request_body_example =
"""
{
"project":{
"fields":[
"id",
"name",
"status",
"updatedAt",
"createdAt",
"hash",
"belongsToCurrentTenant",
"isActive"
]
},
"metadata":{
"countAll":true
},
"page":{
"offset":0,
"size":10
},
"isActive":[
1
],
"order":{
"items":[
"-createdAt"
]
}
}
""";
public static final String endpoint_query_response_example =
"""
{
"items":[
{
"id":"709a8400-10ca-11ee-be56-0242ac120002",
"name":"Dataset",
"createdAt":"2024-06-10T07:54:59.508261Z",
"updatedAt":"2024-06-10T07:54:59.508261Z",
"isActive":1,
"status":1,
"hash":"1718006099",
"belongsToCurrentTenant":true
},
{
"id":"3b15c046-a978-4b5a-9376-66525b7f1ac9",
"name":"Software",
"createdAt":"2024-06-10T07:54:59.508261Z",
"updatedAt":"2024-06-10T07:54:59.508261Z",
"isActive":1,
"status":1,
"hash":"1718006099",
"belongsToCurrentTenant":true
}
],
"count":2
}
""";
}
public static class DmpBlueprint {
}
public static class FileTransformer {
}
public static class EntityDoi {
}
public static class Deposit {
}
}

View File

@ -3,15 +3,15 @@ springdoc:
groups:
enabled: true
groupConfigs:
- group: public-api
- group: legacy-api
displayName: Legacy
packagesToScan: org.opencdmp.controllers.publicapi
pathsToMatch: "/api/public/dmps/**, /api/public/datasets/**"
- group: internal-api
- group: current-api
displayName: Current
packagesToScan: org.opencdmp.controllers
packagesToExclude: org.opencdmp.controllers.publicapi
pathsToMatch: "/api/dmp/**, /api/description/**"
pathsToMatch: "/api/dmp/**, /api/description/**, /api/description-template/**, /api/description-template-type/**"
swaggerUi:
enabled: true
useRootPath: true