Refactored swagger docs contents to reflect better the relevant parts of the docs, added query examples for dmp and description queries.
This commit is contained in:
parent
601b748388
commit
8e2dcc855a
|
@ -13,6 +13,9 @@ 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.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import org.opencdmp.audit.AuditableAction;
|
||||
|
@ -146,7 +149,24 @@ public class DescriptionController {
|
|||
}
|
||||
|
||||
@PostMapping("query")
|
||||
@Operation(summary = "Query all descriptions", description = SwaggerHelpers.endpoint_query)
|
||||
@Operation(
|
||||
summary = "Query all descriptions",
|
||||
description = SwaggerHelpers.endpoint_query,
|
||||
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||
description = SwaggerHelpers.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.endpoint_query_request_body_example
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
public QueryResult<Description> query(@RequestBody DescriptionLookup lookup) throws MyApplicationException, MyForbiddenException {
|
||||
logger.debug("querying {}", Description.class.getSimpleName());
|
||||
|
||||
|
@ -162,7 +182,10 @@ public class DescriptionController {
|
|||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "Fetch a specific description by id")
|
||||
public Description get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||
public Description get(
|
||||
@Parameter(name = "id", description = "The id of a description to fetch", example = "c0c163dc-2965-45a5-9608-f76030578609", required = true) @PathVariable("id") UUID id,
|
||||
@Parameter(name = "fieldSet", description = "This is an object containing a list of the properties you wish to include in the response, similar to the 'project' attribute on queries.", required = true) FieldSet fieldSet)
|
||||
throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||
logger.debug(new MapLogEntry("retrieving" + Description.class.getSimpleName()).And("id", id).And("fields", fieldSet));
|
||||
fieldSet = this.fieldSetExpanderService.expand(fieldSet);
|
||||
|
||||
|
@ -342,6 +365,10 @@ public class DescriptionController {
|
|||
"""
|
||||
This endpoint is used to fetch all the available descriptions.<br/>
|
||||
It also allows to restrict the results using a query object passed in the request body.<br/>
|
||||
""";
|
||||
|
||||
static final String endpoint_query_request_body =
|
||||
"""
|
||||
Let's explore the options this object gives us.
|
||||
|
||||
### <u>General query parameters:</u>
|
||||
|
@ -451,7 +478,60 @@ public class DescriptionController {
|
|||
</ul>
|
||||
""";
|
||||
|
||||
static final String endpoint_ =
|
||||
static final String endpoint_query_request_body_example =
|
||||
"""
|
||||
{
|
||||
"project":{
|
||||
"fields":[
|
||||
"id",
|
||||
"label",
|
||||
"status",
|
||||
"updatedAt",
|
||||
"belongsToCurrentTenant",
|
||||
"finalizedAt",
|
||||
"descriptionTemplate.id",
|
||||
"descriptionTemplate.label",
|
||||
"descriptionTemplate.groupId",
|
||||
"dmp.id",
|
||||
"dmp.label",
|
||||
"dmp.status",
|
||||
"dmp.accessType",
|
||||
"dmp.blueprint.id",
|
||||
"dmp.blueprint.label",
|
||||
"dmp.blueprint.definition.sections.id",
|
||||
"dmp.blueprint.definition.sections.label",
|
||||
"dmp.blueprint.definition.sections.hasTemplates",
|
||||
"dmp.dmpReferences.id",
|
||||
"dmp.dmpReferences.reference.id",
|
||||
"dmp.dmpReferences.reference.label",
|
||||
"dmp.dmpReferences.reference.type.id",
|
||||
"dmp.dmpReferences.reference.reference",
|
||||
"dmp.dmpReferences.isActive",
|
||||
"dmpDescriptionTemplate.id",
|
||||
"dmpDescriptionTemplate.dmp.id",
|
||||
"dmpDescriptionTemplate.descriptionTemplateGroupId",
|
||||
"dmpDescriptionTemplate.sectionId"
|
||||
]
|
||||
},
|
||||
"page":{
|
||||
"size":5,
|
||||
"offset":0
|
||||
},
|
||||
"order":{
|
||||
"items":[
|
||||
"-updatedAt"
|
||||
]
|
||||
},
|
||||
"metadata":{
|
||||
"countAll":true
|
||||
},
|
||||
"isActive":[
|
||||
1
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
static final String endpoint_get =
|
||||
"""
|
||||
|
||||
""";
|
||||
|
|
|
@ -12,6 +12,8 @@ import gr.cite.tools.logging.LoggerService;
|
|||
import gr.cite.tools.logging.MapLogEntry;
|
||||
import gr.cite.tools.validation.ValidationFilterAnnotation;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.xml.bind.JAXBException;
|
||||
import org.opencdmp.audit.AuditableAction;
|
||||
|
@ -75,16 +77,16 @@ public class DmpController {
|
|||
private final QueryFactory queryFactory;
|
||||
|
||||
private final MessageSource messageSource;
|
||||
|
||||
private final ElasticQueryHelperService elasticQueryHelperService;
|
||||
|
||||
|
||||
public DmpController(
|
||||
BuilderFactory builderFactory,
|
||||
AuditService auditService,
|
||||
DmpService dmpService,
|
||||
CensorFactory censorFactory,
|
||||
QueryFactory queryFactory,
|
||||
MessageSource messageSource,
|
||||
BuilderFactory builderFactory,
|
||||
AuditService auditService,
|
||||
DmpService dmpService,
|
||||
CensorFactory censorFactory,
|
||||
QueryFactory queryFactory,
|
||||
MessageSource messageSource,
|
||||
ElasticQueryHelperService elasticQueryHelperService) {
|
||||
this.builderFactory = builderFactory;
|
||||
this.auditService = auditService;
|
||||
|
@ -92,9 +94,9 @@ public class DmpController {
|
|||
this.censorFactory = censorFactory;
|
||||
this.queryFactory = queryFactory;
|
||||
this.messageSource = messageSource;
|
||||
this.elasticQueryHelperService = elasticQueryHelperService;
|
||||
}
|
||||
|
||||
this.elasticQueryHelperService = elasticQueryHelperService;
|
||||
}
|
||||
|
||||
@PostMapping("public/query")
|
||||
@Operation(summary = "Query public published plans")
|
||||
public QueryResult<PublicDmp> publicQuery(@RequestBody DmpLookup lookup) throws MyApplicationException, MyForbiddenException {
|
||||
|
@ -117,10 +119,11 @@ public class DmpController {
|
|||
|
||||
this.censorFactory.censor(PublicDmpCensor.class).censor(fieldSet);
|
||||
|
||||
DmpQuery query = this.queryFactory.query(DmpQuery.class).disableTracking().authorize(EnumSet.of(Public)).ids(id).isActive(IsActive.Active).statuses(DmpStatus.Finalized).accessTypes(DmpAccessType.Public);
|
||||
DmpQuery query = this.queryFactory.query(DmpQuery.class).disableTracking().authorize(EnumSet.of(Public)).ids(id).isActive(IsActive.Active).statuses(DmpStatus.Finalized).accessTypes(DmpAccessType.Public);
|
||||
|
||||
PublicDmp model = this.builderFactory.builder(PublicDmpBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet));
|
||||
if (model == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
if (model == null)
|
||||
throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
||||
this.auditService.track(AuditableAction.Dmp_PublicLookup, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("id", id),
|
||||
|
@ -131,7 +134,24 @@ public class DmpController {
|
|||
}
|
||||
|
||||
@PostMapping("query")
|
||||
@Operation(summary = "Query all plans")
|
||||
@Operation(
|
||||
summary = "Query all plans",
|
||||
description = SwaggerHelpers.endpoint_query,
|
||||
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||
description = SwaggerHelpers.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.endpoint_query_request_body_example
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
public QueryResult<Dmp> Query(@RequestBody DmpLookup lookup) throws MyApplicationException, MyForbiddenException {
|
||||
logger.debug("querying {}", Dmp.class.getSimpleName());
|
||||
|
||||
|
@ -401,4 +421,171 @@ public class DmpController {
|
|||
return model;
|
||||
}
|
||||
|
||||
protected static class SwaggerHelpers {
|
||||
|
||||
static final String endpoint_query =
|
||||
"""
|
||||
This endpoint is used to fetch all the available plans.<br/>
|
||||
It also allows to restrict the results using a query object passed in the request body.<br/>
|
||||
""";
|
||||
|
||||
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 specific query parameters:</u>
|
||||
|
||||
<ul>
|
||||
<li><b>like:</b>
|
||||
If there is a like parameter present in the query, only the description 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 plans to have. Every plan and all its versions, have the same groupId. <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>accessTypes:</b>
|
||||
This is a list and determines which records we want to include in the response, based on their access type.
|
||||
The access type can be <i>Public</i> or <i>Restricted</i>. We add 0 or 1 to the list respectively.
|
||||
<br/>If not present, every record is included.
|
||||
</li>
|
||||
</ul>
|
||||
""";
|
||||
|
||||
static final String endpoint_query_request_body_example =
|
||||
"""
|
||||
{
|
||||
"project":{
|
||||
"fields":[
|
||||
"id",
|
||||
"label",
|
||||
"description",
|
||||
"status",
|
||||
"accessType",
|
||||
"version",
|
||||
"versionStatus",
|
||||
"groupId",
|
||||
"updatedAt",
|
||||
"belongsToCurrentTenant",
|
||||
"finalizedAt",
|
||||
"hash",
|
||||
"descriptions.id",
|
||||
"descriptions.label",
|
||||
"descriptions.status",
|
||||
"descriptions.descriptionTemplate.groupId",
|
||||
"descriptions.isActive",
|
||||
"blueprint.id",
|
||||
"blueprint.label",
|
||||
"blueprint.definition.sections.id"
|
||||
]
|
||||
},
|
||||
"page":{
|
||||
"size":5,
|
||||
"offset":0
|
||||
},
|
||||
"order":{
|
||||
"items":[
|
||||
"-updatedAt"
|
||||
]
|
||||
},
|
||||
"metadata":{
|
||||
"countAll":true
|
||||
},
|
||||
"isActive":[
|
||||
1
|
||||
],
|
||||
"versionStatuses":[
|
||||
0,
|
||||
2
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
static final String endpoint_ =
|
||||
"""
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue