diff options
author | 2018-08-01 10:25:00 +0300 | |
---|---|---|
committer | 2018-08-01 10:25:00 +0300 | |
commit | c8f5d42556b0d8adae945571cbedba72051eadb2 (patch) | |
tree | 2cf19b46c94524ca3e45e47aacdfed9429b149b9 /workflow-designer-be/src/main/java/org | |
parent | a89ccf505badf4c5c2b834e5a0d94ada8ca5f814 (diff) |
Change paging and sorting of list workflows api
Use offset+limit instead page+size.
Issue-ID: SDC-1483
Change-Id: Ied1a05d08de82ac5474aad7ac6427afa5baf083f
Signed-off-by: talig <talig@amdocs.com>
Diffstat (limited to 'workflow-designer-be/src/main/java/org')
19 files changed, 299 insertions, 166 deletions
diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestConstants.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestParams.java index 817bebe1..c22a0c20 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestConstants.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestParams.java @@ -16,16 +16,13 @@ package org.onap.sdc.workflow.api; -public class RestConstants { +public class RestParams { - private RestConstants() { + private RestParams() { } - public static final String USER_ID_HEADER_PARAM = "USER_ID"; - public static final String SIZE_PARAM = "size"; - public static final String PAGE_PARAM = "page"; - public static final String SORT_PARAM = "sort"; - public static final String SORT_FIELD_NAME = "name"; - public static final int SIZE_DEFAULT = 20; - public static final int PAGE_DEFAULT = 0; + public static final String USER_ID_HEADER = "USER_ID"; + public static final String OFFSET = "offset"; + public static final String LIMIT = "limit"; + public static final String SORT = "sort"; } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/RestUtils.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestUtils.java index 8ba75429..d8577c1c 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/RestUtils.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onap.sdc.workflow; +package org.onap.sdc.workflow.api; import java.util.Arrays; import java.util.Collections; @@ -30,7 +30,7 @@ public class RestUtils { private static final Logger LOGGER = LoggerFactory.getLogger(RestUtils.class); - public static Set<WorkflowVersionState> mapVersionStateFilter(String versionStateFilter) { + public static Set<WorkflowVersionState> formatVersionStates(String versionStateFilter) { Set<WorkflowVersionState> filter; try { filter = versionStateFilter == null ? null : @@ -38,7 +38,7 @@ public class RestUtils { .collect(Collectors.toSet()); } catch (Exception e) { LOGGER.info( - "version state filter value is invalid and cannot be mapped to a set of version states, therefore it is set to empty set"); + "version state filter value is invalid and cannot be formatted to a set of version states, therefore it is set to empty set"); filter = Collections.emptySet(); } return filter; diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java index f8eb4bb9..77f6e6df 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java @@ -16,30 +16,30 @@ package org.onap.sdc.workflow.api; -import static org.onap.sdc.workflow.RestUtils.*; -import static org.onap.sdc.workflow.api.RestConstants.SIZE_DEFAULT; -import static org.onap.sdc.workflow.api.RestConstants.SORT_FIELD_NAME; -import static org.onap.sdc.workflow.api.RestConstants.SORT_PARAM; -import static org.onap.sdc.workflow.api.RestConstants.USER_ID_HEADER_PARAM; +import static org.onap.sdc.workflow.api.RestParams.LIMIT; +import static org.onap.sdc.workflow.api.RestParams.OFFSET; +import static org.onap.sdc.workflow.api.RestParams.SORT; +import static org.onap.sdc.workflow.api.RestParams.USER_ID_HEADER; +import static org.onap.sdc.workflow.api.RestUtils.formatVersionStates; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_LIMIT; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_OFFSET; -import com.google.common.collect.ImmutableSet; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; -import java.util.Arrays; -import java.util.Set; -import org.onap.sdc.workflow.api.types.CollectionWrapper; +import org.onap.sdc.workflow.api.types.Paging; +import org.onap.sdc.workflow.api.types.Sorting; import org.onap.sdc.workflow.persistence.types.Workflow; import org.onap.sdc.workflow.services.WorkflowManager; import org.onap.sdc.workflow.services.WorkflowVersionManager; -import org.onap.sdc.workflow.services.exceptions.InvalidPaginationParameterException; +import org.onap.sdc.workflow.services.types.Page; +import org.onap.sdc.workflow.services.types.PagingRequest; +import org.onap.sdc.workflow.services.types.RequestSpec; +import org.onap.sdc.workflow.services.types.SortingRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableDefault; -import org.springframework.data.web.SortDefault; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -58,7 +58,6 @@ import org.springframework.web.bind.annotation.RestController; @Api("Workflows") @RestController("workflowController") public class WorkflowController { - private final WorkflowManager workflowManager; private final WorkflowVersionManager workflowVersionManager; @@ -71,21 +70,26 @@ public class WorkflowController { @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("List workflows") - public CollectionWrapper<Workflow> list( - @ApiParam(value = "Filter by version state", allowableValues = "DRAFT,CERTIFIED") - @RequestParam(value = "versionState", required = false) String versionStateFilter, - @PageableDefault(size = SIZE_DEFAULT) - @SortDefault.SortDefaults({@SortDefault(sort = SORT_FIELD_NAME, direction = Sort.Direction.ASC)}) - Pageable pageable, @RequestHeader(USER_ID_HEADER_PARAM) String user) { - PageRequest pageRequest = createPageRequest(pageable); - return new CollectionWrapper<>(pageRequest.getPageSize(), pageRequest.getPageNumber(), - workflowManager.list(mapVersionStateFilter(versionStateFilter), pageRequest)); + @ApiImplicitParams({ + @ApiImplicitParam(name = OFFSET, dataType = "string", paramType = "query", defaultValue = "0", + value = "Index of the starting item"), + @ApiImplicitParam(name = LIMIT, dataType = "string", paramType = "query", defaultValue = "200", + value = "Number of returned items"), + @ApiImplicitParam(name = SORT, dataType = "string", paramType = "query", defaultValue = "name:asc", + value = "Sorting criteria in the format: property:(asc|desc). Default sort order is ascending.", + allowableValues = "name:asc,name:desc")}) + public Page<Workflow> list(@ApiParam(value = "Filter by version state", allowableValues = "DRAFT,CERTIFIED") + @RequestParam(name = "versionState", required = false) String versionStateFilter, + @ApiParam(hidden = true) Paging paging, + @ApiParam(hidden = true) Sorting sorting, + @RequestHeader(USER_ID_HEADER) String user) { + return workflowManager.list(formatVersionStates(versionStateFilter), initRequestSpec(paging, sorting)); } @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Create workflow") public ResponseEntity<Workflow> create(@Validated @RequestBody Workflow workflow, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @RequestHeader(USER_ID_HEADER) String user) { return new ResponseEntity<>(workflowManager.create(workflow), HttpStatus.CREATED); } @@ -94,7 +98,7 @@ public class WorkflowController { public Workflow get(@PathVariable("workflowId") String workflowId, @ApiParam(value = "Expand workflow data", allowableValues = "versions") @RequestParam(value = "expand", required = false) String expand, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @RequestHeader(USER_ID_HEADER) String user) { Workflow workflow = new Workflow(); workflow.setId(workflowId); Workflow retrievedWorkflow = workflowManager.get(workflow); @@ -107,23 +111,15 @@ public class WorkflowController { @PutMapping(path = "/{workflowId}", consumes = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Update workflow") public Workflow update(@RequestBody Workflow workflow, @PathVariable("workflowId") String workflowId, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @RequestHeader(USER_ID_HEADER) String user) { workflow.setId(workflowId); workflowManager.update(workflow); return workflow; } - - private PageRequest createPageRequest(Pageable pageable) { - Set<String> validSortFields = ImmutableSet.of(SORT_FIELD_NAME); - Sort sort = pageable.getSort(); - for (Sort.Order order : sort) { - String sortFieldName = order.getProperty(); - if (!sortFieldName.equalsIgnoreCase(SORT_FIELD_NAME)) { - throw new InvalidPaginationParameterException(SORT_PARAM, sortFieldName, - "is not supported. Supported values are: " + Arrays.toString(validSortFields.toArray())); - } - } - return PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), sort); + private RequestSpec initRequestSpec(Paging paging, Sorting sorting) { + return new RequestSpec(new PagingRequest(paging.getOffset() == null ? DEFAULT_OFFSET : paging.getOffset(), + paging.getLimit() == null ? DEFAULT_LIMIT : paging.getLimit()), + SortingRequest.builder().sorts(sorting.getSorts()).build()); } } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java index 34ecb898..ba15f9f7 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java @@ -16,13 +16,13 @@ package org.onap.sdc.workflow.api; -import static org.onap.sdc.workflow.RestUtils.mapVersionStateFilter; -import static org.onap.sdc.workflow.api.RestConstants.USER_ID_HEADER_PARAM; +import static org.onap.sdc.workflow.api.RestUtils.formatVersionStates; +import static org.onap.sdc.workflow.api.RestParams.USER_ID_HEADER; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; -import org.onap.sdc.workflow.api.types.CollectionWrapper; +import org.onap.sdc.workflow.api.types.CollectionResponse; import org.onap.sdc.workflow.api.types.VersionStateDto; import org.onap.sdc.workflow.persistence.types.ArtifactEntity; import org.onap.sdc.workflow.persistence.types.WorkflowVersion; @@ -65,20 +65,19 @@ public class WorkflowVersionController { } @Autowired - public WorkflowVersionController( - @Qualifier("workflowVersionManager") WorkflowVersionManager workflowVersionManager, - @Qualifier("workflowVersionValidator") Validator validator ) { + public WorkflowVersionController(@Qualifier("workflowVersionManager") WorkflowVersionManager workflowVersionManager, + @Qualifier("workflowVersionValidator") Validator validator) { this.workflowVersionManager = workflowVersionManager; this.validator = validator; } @GetMapping @ApiOperation("List workflow versions") - public CollectionWrapper<WorkflowVersion> list(@PathVariable("workflowId") String workflowId, + public CollectionResponse<WorkflowVersion> list(@PathVariable("workflowId") String workflowId, @ApiParam(value = "Filter by state", allowableValues = "DRAFT,CERTIFIED") @RequestParam(value = "state", required = false) String stateFilter, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { - return new CollectionWrapper<>(workflowVersionManager.list(workflowId, mapVersionStateFilter(stateFilter))); + @RequestHeader(USER_ID_HEADER) String user) { + return new CollectionResponse<>(workflowVersionManager.list(workflowId, formatVersionStates(stateFilter))); } @PostMapping @@ -86,7 +85,7 @@ public class WorkflowVersionController { public ResponseEntity<WorkflowVersion> create(@RequestBody @Validated WorkflowVersion version, @PathVariable("workflowId") String workflowId, @RequestParam(value = "baseVersionId", required = false) String baseVersionId, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @RequestHeader(USER_ID_HEADER) String user) { WorkflowVersion createdVersion = workflowVersionManager.create(workflowId, baseVersionId, version); return new ResponseEntity<>(createdVersion, HttpStatus.CREATED); } @@ -94,14 +93,14 @@ public class WorkflowVersionController { @GetMapping("/{versionId}") @ApiOperation("Get workflow version") public WorkflowVersion get(@PathVariable("workflowId") String workflowId, - @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER) String user) { return workflowVersionManager.get(workflowId, versionId); } @PutMapping("/{versionId}") @ApiOperation("Update workflow version") public void update(@RequestBody @Validated WorkflowVersion version, @PathVariable("workflowId") String workflowId, - @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER) String user) { version.setId(versionId); workflowVersionManager.update(workflowId, version); } @@ -109,7 +108,7 @@ public class WorkflowVersionController { @GetMapping("/{versionId}/state") @ApiOperation("Get workflow version state") public VersionStateDto getState(@PathVariable("workflowId") String workflowId, - @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER) String user) { return new VersionStateDto(workflowVersionManager.getState(workflowId, versionId)); } @@ -117,7 +116,7 @@ public class WorkflowVersionController { @ApiOperation("Update workflow version state") public VersionStateDto updateState(@RequestBody VersionStateDto state, @PathVariable("workflowId") String workflowId, @PathVariable("versionId") String versionId, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @RequestHeader(USER_ID_HEADER) String user) { workflowVersionManager.updateState(workflowId, versionId, state.getName()); return new VersionStateDto(state.getName()); } @@ -125,14 +124,14 @@ public class WorkflowVersionController { @PutMapping("/{versionId}/artifact") @ApiOperation("Create/update artifact of a version") public void uploadArtifact(@RequestBody MultipartFile fileToUpload, @PathVariable("workflowId") String workflowId, - @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER) String user) { workflowVersionManager.uploadArtifact(workflowId, versionId, fileToUpload); } @GetMapping("/{versionId}/artifact") @ApiOperation("Download workflow version artifact") public ResponseEntity<Resource> getArtifact(@PathVariable("workflowId") String workflowId, - @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER) String user) { ArtifactEntity artifact = workflowVersionManager.getArtifact(workflowId, versionId); return ResponseEntity.ok() @@ -144,7 +143,7 @@ public class WorkflowVersionController { @DeleteMapping("/{versionId}/artifact") @ApiOperation("Delete workflow version artifact") public void deleteArtifact(@PathVariable("workflowId") String workflowId, - @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER) String user) { workflowVersionManager.deleteArtifact(workflowId, versionId); } } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionResponse.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionResponse.java new file mode 100644 index 00000000..831ccc34 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionResponse.java @@ -0,0 +1,16 @@ +package org.onap.sdc.workflow.api.types; + +import java.util.Collection; +import lombok.Data; + +@Data +public class CollectionResponse<T> { + + private int total; + private Collection<T> items; + + public CollectionResponse(Collection<T> items) { + this.items = items; + this.total = items.size(); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionWrapper.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionWrapper.java deleted file mode 100644 index 1e11bc90..00000000 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionWrapper.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright © 2018 European Support Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onap.sdc.workflow.api.types; - -import java.util.Collection; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@NoArgsConstructor -public class CollectionWrapper<T> { - - private int total; - private int size; - private int page; - private Collection<T> results; - - public CollectionWrapper(int size, int page, Collection<T> results) { - this.results = results; - this.size = size; - this.page = page; - this.total = results.size(); - } - - public CollectionWrapper(Collection<T> results) { - this.results = results; - this.total = results.size(); - } -} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Paging.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Paging.java new file mode 100644 index 00000000..3d91c8e0 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Paging.java @@ -0,0 +1,32 @@ +package org.onap.sdc.workflow.api.types; + +import static org.onap.sdc.workflow.services.types.PagingConstants.MAX_LIMIT; + +import java.util.Optional; +import lombok.Getter; + +@Getter +public class Paging { + + private Integer offset; + private Integer limit; + + public void setOffset(String offset) { + getIntValue(offset).ifPresent(integer -> this.offset = integer); + } + + public void setLimit(String limit) { + getIntValue(limit).map(integer -> integer > MAX_LIMIT ? MAX_LIMIT : integer) + .ifPresent(integer -> this.limit = integer); + } + + private Optional<Integer> getIntValue(String value) { + int intValue; + try { + intValue = Integer.parseInt(value); + return intValue < 0 ? Optional.empty() : Optional.of(intValue); + } catch (NumberFormatException e) { + return Optional.empty(); + } + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Sorting.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Sorting.java new file mode 100644 index 00000000..7bb43d0b --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Sorting.java @@ -0,0 +1,33 @@ +package org.onap.sdc.workflow.api.types; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import lombok.Getter; +import org.onap.sdc.workflow.services.types.Sort; + +@Getter +public class Sorting { + + private static final String SORTS_DELIMITER = ","; + private static final String DIRECTION_DELIMITER = ":"; + private static final String ASCENDING_ORDER = "asc"; + + private List<Sort> sorts = Collections.emptyList(); + + public void setSort(String sortString) { + this.sorts = Arrays.stream(sortString.split(SORTS_DELIMITER)).map(this::formatSort).filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + private Sort formatSort(String sort) { + String[] tokens = sort.split(DIRECTION_DELIMITER); + try { + return new Sort(tokens[0], ASCENDING_ORDER.equalsIgnoreCase(tokens[1])); + } catch (Exception e) { + return null; + } + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java index 07d8eee7..28838327 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java @@ -1,7 +1,5 @@ package org.onap.sdc.workflow.server.filters; -import static org.onap.sdc.workflow.api.RestConstants.USER_ID_HEADER_PARAM; - import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java index ca079d42..fcae232a 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java @@ -20,11 +20,12 @@ import java.util.Collection; import java.util.Set; import org.onap.sdc.workflow.persistence.types.Workflow; import org.onap.sdc.workflow.persistence.types.WorkflowVersionState; -import org.springframework.data.domain.Pageable; +import org.onap.sdc.workflow.services.types.Page; +import org.onap.sdc.workflow.services.types.RequestSpec; public interface WorkflowManager { - Collection<Workflow> list(Set<WorkflowVersionState> versionStatesFilter, Pageable pageable); + Page<Workflow> list(Set<WorkflowVersionState> versionStatesFilter, RequestSpec requestSpec); Workflow get(Workflow workflow); diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java index 52dd8f17..23979a5d 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.onap.sdc.workflow.services.impl; -import static org.onap.sdc.workflow.api.RestConstants.SORT_FIELD_NAME; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_LIMIT; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_OFFSET; +import static org.onap.sdc.workflow.services.types.PagingConstants.MAX_LIMIT; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -29,10 +30,14 @@ import org.onap.sdc.workflow.persistence.types.Workflow; import org.onap.sdc.workflow.persistence.types.WorkflowVersionState; import org.onap.sdc.workflow.services.UniqueValueService; import org.onap.sdc.workflow.services.WorkflowManager; -import org.onap.sdc.workflow.services.WorkflowNameComparator; import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; import org.onap.sdc.workflow.services.impl.mappers.WorkflowMapper; +import org.onap.sdc.workflow.services.types.Page; +import org.onap.sdc.workflow.services.types.PagingRequest; +import org.onap.sdc.workflow.services.types.RequestSpec; +import org.onap.sdc.workflow.services.types.Sort; +import org.onap.sdc.workflow.services.types.SortingRequest; import org.openecomp.sdc.logging.api.Logger; import org.openecomp.sdc.logging.api.LoggerFactory; import org.openecomp.sdc.versioning.ItemManager; @@ -41,8 +46,6 @@ import org.openecomp.sdc.versioning.types.Item; import org.openecomp.sdc.versioning.types.ItemStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; @Service("workflowManager") @@ -52,8 +55,13 @@ public class WorkflowManagerImpl implements WorkflowManager { private static final String WORKFLOW_NOT_FOUND_ERROR_MSG = "Workflow with id '%s' does not exist"; private static final String WORKFLOW_NAME_UNIQUE_TYPE = "WORKFLOW_NAME"; private static final Predicate<Item> WORKFLOW_ITEM_FILTER = item -> WORKFLOW_TYPE.equals(item.getType()); + private static final String WORKSPACES_SORT_PROPERTY = "name"; + private static final RequestSpec WORKSPACES_DEFAULT_REQUEST_SPEC = + new RequestSpec(new PagingRequest(DEFAULT_OFFSET, DEFAULT_LIMIT), + SortingRequest.builder().sort(new Sort(WORKSPACES_SORT_PROPERTY, true)).build()); private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowManagerImpl.class); + private final ItemManager itemManager; private final UniqueValueService uniqueValueService; private final WorkflowMapper workflowMapper; @@ -70,27 +78,29 @@ public class WorkflowManagerImpl implements WorkflowManager { } @Override - public Collection<Workflow> list(Set<WorkflowVersionState> versionStatesFilter, Pageable pageRequest) { + public Page<Workflow> list(Set<WorkflowVersionState> versionStatesFilter, RequestSpec requestSpec) { + requestSpec = getRequestSpec(requestSpec); + Set<VersionStatus> versionStatusesFilter = versionStatesFilter == null ? null : versionStatesFilter.stream().map(versionStateMapper::workflowVersionStateToVersionStatus) .collect(Collectors.toSet()); + Collection<Item> workflowItems = itemManager.list(getFilter(versionStatusesFilter)); - List<Workflow> workflows = itemManager.list(getFilter(versionStatusesFilter)).stream() - .map(workflowMapper::itemToWorkflow) - .sorted(pageRequest.getSort().getOrderFor(SORT_FIELD_NAME).getDirection() - == Sort.Direction.ASC ? getWorkflowsComparator() : - Collections.reverseOrder(getWorkflowsComparator())) - .collect(Collectors.toList()); - return applyLimitAndOffset(workflows, pageRequest); + List<Workflow> workflowsSlice = workflowItems.stream().map(workflowMapper::itemToWorkflow) + .sorted(getWorkflowComparator(requestSpec.getSorting())) + .skip(requestSpec.getPaging().getOffset()) + .limit(requestSpec.getPaging().getLimit()) + .collect(Collectors.toList()); + return new Page<>(workflowsSlice, requestSpec.getPaging(), workflowItems.size()); } @Override public Workflow get(Workflow workflow) { Item retrievedItem = itemManager.get(workflow.getId()); if (retrievedItem == null) { - LOGGER.error(String.format("Workflow with id %s was not found",workflow.getId())); + LOGGER.error(String.format("Workflow with id %s was not found", workflow.getId())); throw new EntityNotFoundException(String.format(WORKFLOW_NOT_FOUND_ERROR_MSG, workflow.getId())); } return this.workflowMapper.itemToWorkflow(retrievedItem); @@ -112,7 +122,7 @@ public class WorkflowManagerImpl implements WorkflowManager { public void update(Workflow workflow) { Item retrievedItem = itemManager.get(workflow.getId()); if (retrievedItem == null) { - LOGGER.error(String.format("Workflow with id %s was not found",workflow.getId())); + LOGGER.error(String.format("Workflow with id %s was not found", workflow.getId())); throw new EntityNotFoundException(String.format(WORKFLOW_NOT_FOUND_ERROR_MSG, workflow.getId())); } @@ -125,35 +135,33 @@ public class WorkflowManagerImpl implements WorkflowManager { itemManager.update(item); } - private List<Workflow> applyLimitAndOffset(List<Workflow> workflowList, Pageable pageRequest) { - int limit = pageRequest.getPageSize(); - int offset = pageRequest.getPageNumber(); - int totalNumOfWorkflows = workflowList.size(); - List<Workflow> selectedWorkflows; - try { - if (limit > totalNumOfWorkflows) { - limit = totalNumOfWorkflows; - } - int startIndex = offset * limit; - int endIndex = startIndex + limit; - if (endIndex > totalNumOfWorkflows) { - endIndex = totalNumOfWorkflows; - } - selectedWorkflows = workflowList.subList(startIndex, endIndex); - } catch (IndexOutOfBoundsException | IllegalArgumentException ex) { - selectedWorkflows = new ArrayList<>(); + private RequestSpec getRequestSpec(RequestSpec requestSpec) { + if (requestSpec == null) { + return WORKSPACES_DEFAULT_REQUEST_SPEC; } - return selectedWorkflows; + if (requestSpec.getPaging() == null) { + requestSpec.setPaging(WORKSPACES_DEFAULT_REQUEST_SPEC.getPaging()); + } else if (requestSpec.getPaging().getLimit() > MAX_LIMIT) { + requestSpec.getPaging().setLimit(MAX_LIMIT); + } + if (requestSpec.getSorting() == null) { + requestSpec.setSorting(WORKSPACES_DEFAULT_REQUEST_SPEC.getSorting()); + } + return requestSpec; } - private Comparator<Workflow> getWorkflowsComparator() { - //More comparators can be added if required based on sort field name - return new WorkflowNameComparator(); + private Comparator<Workflow> getWorkflowComparator(SortingRequest sorting) { + Boolean byNameAscending = sorting.getSorts().stream() + .filter(sort -> WORKSPACES_SORT_PROPERTY.equalsIgnoreCase(sort.getProperty())) + .findFirst().map(Sort::isAscendingOrder).orElse(true); + Comparator<Workflow> byName = Comparator.comparing(Workflow::getName); + + return byNameAscending ? byName : byName.reversed(); } private static Predicate<Item> getFilter(Set<VersionStatus> versionStatuses) { - return WORKFLOW_ITEM_FILTER.and(item -> versionStatuses == null - || item.getVersionStatusCounters().keySet().stream() - .anyMatch(versionStatuses::contains)); + return WORKFLOW_ITEM_FILTER + .and(item -> versionStatuses == null || item.getVersionStatusCounters().keySet().stream() + .anyMatch(versionStatuses::contains)); } } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java index 0f7c993d..56ba7ac9 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java @@ -22,6 +22,7 @@ import com.amdocs.zusammen.datatypes.response.ErrorCode; import java.io.IOException; import java.io.InputStream; import java.util.Collection; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -89,6 +90,7 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { .filter(version -> versionStatusFilter == null || versionStatusFilter.contains( version.getStatus())) .map(versionMapper::versionToWorkflowVersion) + .sorted(Comparator.comparing(WorkflowVersion::getName).reversed()) .peek(workflowVersion -> loadAndAddParameters(workflowId, workflowVersion)) .collect(Collectors.toList()); } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowNameComparator.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Page.java index 1cb6cb1d..3fc9d0ba 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowNameComparator.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Page.java @@ -14,19 +14,21 @@ * limitations under the License. */ -package org.onap.sdc.workflow.services; +package org.onap.sdc.workflow.services.types; -import java.util.Comparator; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; -import org.onap.sdc.workflow.persistence.types.Workflow; +@Getter +@NoArgsConstructor +public class Page<T> { -public class WorkflowNameComparator implements Comparator<Workflow>{ + private Paging paging; + private List<T> items; - @Override - public int compare(Workflow workflow1, Workflow workflow2) { - String workflowName1 = workflow1.getName().toLowerCase(); - String workflowName2 = workflow2.getName().toLowerCase(); - //ascending order - return workflowName1.compareTo(workflowName2); + public Page(List<T> items, PagingRequest pagingRequest, int total) { + this.items = items; + this.paging = new Paging(pagingRequest, items.size(), total); } } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Paging.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Paging.java new file mode 100644 index 00000000..c1a76491 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Paging.java @@ -0,0 +1,25 @@ +package org.onap.sdc.workflow.services.types; + +import lombok.Getter; + +@Getter +public class Paging { + + private int offset; + private int limit; + private int count; + private boolean hasMore; + private int total; + + public Paging(PagingRequest pagingRequest, int count, int total) { + this.offset = pagingRequest.getOffset(); + this.limit = pagingRequest.getLimit(); + this.count = count; + setTotal(total); + } + + private void setTotal(int total) { + this.total = total; + this.hasMore = total > offset + limit; + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingConstants.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingConstants.java new file mode 100644 index 00000000..dd6eefad --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingConstants.java @@ -0,0 +1,8 @@ +package org.onap.sdc.workflow.services.types; + +public class PagingConstants { + + public static final int DEFAULT_OFFSET = 0; + public static final int DEFAULT_LIMIT = 200; + public static final int MAX_LIMIT = 2000; +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingRequest.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingRequest.java new file mode 100644 index 00000000..f06822fa --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingRequest.java @@ -0,0 +1,15 @@ +package org.onap.sdc.workflow.services.types; + +import lombok.Data; + +@Data +public class PagingRequest { + + private int offset; + private int limit; + + public PagingRequest(int offset, int limit) { + this.offset = offset; + this.limit = limit; + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/RequestSpec.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/RequestSpec.java new file mode 100644 index 00000000..cb974ee4 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/RequestSpec.java @@ -0,0 +1,15 @@ +package org.onap.sdc.workflow.services.types; + +import lombok.Data; + +@Data +public class RequestSpec { + + private PagingRequest paging; + private SortingRequest sorting; + + public RequestSpec(PagingRequest paging, SortingRequest sorting) { + this.paging = paging; + this.sorting = sorting; + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Sort.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Sort.java new file mode 100644 index 00000000..563c9ad0 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Sort.java @@ -0,0 +1,15 @@ +package org.onap.sdc.workflow.services.types; + +import lombok.Getter; + +@Getter +public class Sort { + + private String property; + private boolean ascendingOrder; + + public Sort(String property, boolean ascendingOrder) { + this.property = property; + this.ascendingOrder = ascendingOrder; + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/SortingRequest.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/SortingRequest.java new file mode 100644 index 00000000..c3b7aa49 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/SortingRequest.java @@ -0,0 +1,14 @@ +package org.onap.sdc.workflow.services.types; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@Getter +public class SortingRequest { + + @Singular + private List<Sort> sorts; +} |