From 8f91bb137eac23825f2c296b1a06fdf2fabdd5c2 Mon Sep 17 00:00:00 2001 From: talig Date: Mon, 23 Jul 2018 10:15:59 +0300 Subject: Filter workflows by version state Fix update version state Change-Id: I5f11f950d75283d29273010d808c83cdf45f12a5 Issue-ID: SDC-1503 Signed-off-by: talig --- .../workflow-bdd/features/VersionState.feature | 30 +++++ .../features/Version_Create_Update.feature | 36 ++--- .../workflow-bdd/features/Version_State.feature | 30 ----- workflow/workflow-bdd/features/Workflow.feature | 11 ++ .../workflow-bdd/features/WorkflowList.feature | 64 +++++++++ .../features/Workflow_Create_Update.feature | 27 ---- workflow/workflow-bdd/pom.xml | 6 - .../resources/json/createWorkflow.json | 5 +- .../workflow-bdd/stepDefinitions/General_Steps.js | 6 +- .../stepDefinitions/InputData_steps.js | 10 ++ .../onap/sdc/workflow/api/WorkflowController.java | 47 +++++-- .../workflow/api/WorkflowVersionController.java | 59 +++++--- .../sdc/workflow/api/types/VersionRequestDto.java | 15 --- .../persistence/impl/ParameterRepositoryImpl.java | 51 ++++--- .../sdc/workflow/persistence/types/Workflow.java | 6 + .../persistence/types/WorkflowVersion.java | 7 +- .../sdc/workflow/services/WorkflowManager.java | 4 +- .../workflow/services/WorkflowVersionManager.java | 8 +- .../exceptions/VersionCreationException.java | 6 +- .../services/impl/WorkflowManagerImpl.java | 52 ++++--- .../services/impl/WorkflowVersionManagerImpl.java | 129 +++++++++--------- .../services/impl/mappers/VersionStateMapper.java | 9 ++ .../services/impl/mappers/WorkflowMapper.java | 7 +- .../test/java/org/onap/sdc/workflow/RestPath.java | 14 +- .../test/java/org/onap/sdc/workflow/TestUtil.java | 19 ++- .../sdc/workflow/api/WorkflowControllerTest.java | 42 ++++-- .../api/WorkflowVersionControllerTest.java | 9 +- .../persistence/impl/ParameterRepositoryTest.java | 28 ++-- .../services/impl/WorkflowManagerImplTest.java | 150 ++++++++++++--------- .../impl/WorkflowVersionManagerImplTest.java | 24 ++-- 30 files changed, 539 insertions(+), 372 deletions(-) create mode 100644 workflow/workflow-bdd/features/VersionState.feature delete mode 100644 workflow/workflow-bdd/features/Version_State.feature create mode 100644 workflow/workflow-bdd/features/Workflow.feature create mode 100644 workflow/workflow-bdd/features/WorkflowList.feature delete mode 100644 workflow/workflow-bdd/features/Workflow_Create_Update.feature delete mode 100644 workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionRequestDto.java diff --git a/workflow/workflow-bdd/features/VersionState.feature b/workflow/workflow-bdd/features/VersionState.feature new file mode 100644 index 00000000..8c1e13fd --- /dev/null +++ b/workflow/workflow-bdd/features/VersionState.feature @@ -0,0 +1,30 @@ +Feature: Workflow Version State + + Background: Create workflow and first version + Given I want to create a Workflow + And I want to update the input property "description" with value "workflow version description" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + Scenario: Get state after creation + When I want to get path "/workflows/{item.id}/versions/{item.versionId}/state" + Then I want to check property "name" for value "DRAFT" + And I want to check property "nextStates[0]" for value "CERTIFIED" + + Scenario: Update state to current state + Then I want the following to fail with response status code 422 + When I want to update the input property "name" with value "DRAFT" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + + Scenario: Update state - DRAFT to CERTIFIED + When I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + Then I want to get path "/workflows/{item.id}/versions/{item.versionId}/state" + And I want to check property "name" for value "CERTIFIED" + And I want to check property "nextStates" to have length 0 + + Scenario: Update state when CERTIFIED + When I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + When I want the following to fail with response status code 422 + Then I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context \ No newline at end of file diff --git a/workflow/workflow-bdd/features/Version_Create_Update.feature b/workflow/workflow-bdd/features/Version_Create_Update.feature index 2cb05804..656cdaf0 100644 --- a/workflow/workflow-bdd/features/Version_Create_Update.feature +++ b/workflow/workflow-bdd/features/Version_Create_Update.feature @@ -3,26 +3,26 @@ Feature: Workflow Versions Background: Init Given I want to create a Workflow - Scenario: Create and get version + Scenario: Create first empty version When I want to create input data - Then I want to update the input property "description" with value "workflow version description" - Then I want to create for path "/workflows/{item.id}/versions" with the input data from the context - Then I want to copy to property "versionId" from response data path "id" - Then I want to get path "/workflows/{item.id}/versions/{versionId}" - Then I want to check that property "id" in the response equals to value of saved property "versionId" - - When I want to get path "/workflows/{item.id}/versions" - Then I want to check that element in the response list with "id" equals to value of saved property "versionId" exists + And I want to update the input property "description" with value "first empty version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + Then I want to get path "/workflows/{item.id}/versions/{item.versionId}" + And I want to check that property "id" in the response equals to value of saved property "item.versionId" + And I want to get path "/workflows/{item.id}/versions" + And I want to check that element in the response list with "id" equals to value of saved property "item.versionId" exists Scenario: Update version - When I want to create input data - Then I want to update the input property "description" with value "workflow version description" - Then I want to create for path "/workflows/{item.id}/versions" with the input data from the context - Then I want to copy to property "versionId" from response data path "id" + And I want to create input data + And I want to update the input property "description" with value "workflow version description" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + + When I want to set property "updatedDesc" to value "workflow version description updated" + And I want to update the input property "description" with value of property "updatedDesc" + And I want to update for path "/workflows/{item.id}/versions/{item.versionId}" with the input data from the context - Then I want to update the input property "description" with value "workflow version description updated" - Then I want to set property "desc" to value "workflow version description updated" - Then I want to update for path "/workflows/{item.id}/versions/{versionId}" with the input data from the context - Then I want to get path "/workflows/{item.id}/versions/{versionId}" - Then I want to check that property "description" in the response equals to value of saved property "desc" \ No newline at end of file + Then I want to get path "/workflows/{item.id}/versions/{item.versionId}" + And I want to check that property "description" in the response equals to value of saved property "updatedDesc" \ No newline at end of file diff --git a/workflow/workflow-bdd/features/Version_State.feature b/workflow/workflow-bdd/features/Version_State.feature deleted file mode 100644 index 8c1e13fd..00000000 --- a/workflow/workflow-bdd/features/Version_State.feature +++ /dev/null @@ -1,30 +0,0 @@ -Feature: Workflow Version State - - Background: Create workflow and first version - Given I want to create a Workflow - And I want to update the input property "description" with value "workflow version description" - And I want to create for path "/workflows/{item.id}/versions" with the input data from the context - And I want to copy to property "item.versionId" from response data path "id" - - Scenario: Get state after creation - When I want to get path "/workflows/{item.id}/versions/{item.versionId}/state" - Then I want to check property "name" for value "DRAFT" - And I want to check property "nextStates[0]" for value "CERTIFIED" - - Scenario: Update state to current state - Then I want the following to fail with response status code 422 - When I want to update the input property "name" with value "DRAFT" - And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context - - Scenario: Update state - DRAFT to CERTIFIED - When I want to update the input property "name" with value "CERTIFIED" - And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context - Then I want to get path "/workflows/{item.id}/versions/{item.versionId}/state" - And I want to check property "name" for value "CERTIFIED" - And I want to check property "nextStates" to have length 0 - - Scenario: Update state when CERTIFIED - When I want to update the input property "name" with value "CERTIFIED" - And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context - When I want the following to fail with response status code 422 - Then I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context \ No newline at end of file diff --git a/workflow/workflow-bdd/features/Workflow.feature b/workflow/workflow-bdd/features/Workflow.feature new file mode 100644 index 00000000..992b40fa --- /dev/null +++ b/workflow/workflow-bdd/features/Workflow.feature @@ -0,0 +1,11 @@ +Feature: Workflow + + Scenario: Create valid + When I want to create a Workflow + + Scenario: Update and Get workflow + When I want to create a Workflow + Then I want to update the input property "description" with value "workflow desc updated" + Then I want to update for path "/workflows/{item.id}" with the input data from the context + Then I want to get path "/workflows/{item.id}" + Then I want to check that property "description" in the response equals to value of saved property "inputData.description" diff --git a/workflow/workflow-bdd/features/WorkflowList.feature b/workflow/workflow-bdd/features/WorkflowList.feature new file mode 100644 index 00000000..0ce680ed --- /dev/null +++ b/workflow/workflow-bdd/features/WorkflowList.feature @@ -0,0 +1,64 @@ +Feature: List Workflows + + Background: Init - create various workflows in order to test list filter + Given I want to create a Workflow + And I want to copy to property "noVersionsWorkflowId" from response data path "id" + + Given I want to create a Workflow + And I want to copy to property "draftVersionWorkflowId" from response data path "id" + And I want to update the input property "description" with value "first version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + + Given I want to create a Workflow + And I want to copy to property "certifiedVersionWorkflowId" from response data path "id" + And I want to update the input property "description" with value "first version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{responseData.id}/state" with the input data from the context + + Given I want to create a Workflow + And I want to copy to property "draftAndCertifiedVersionWorkflowId" from response data path "id" + And I want to update the input property "description" with value "first version" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + And I want to copy to property "item.versionId" from response data path "id" + And I want to update the input property "name" with value "CERTIFIED" + And I want to create for path "/workflows/{item.id}/versions/{item.versionId}/state" with the input data from the context + And I want to update the input property "description" with value "second version" + And I want to update the input property "baseVersionId" with value of property "item.versionId" + And I want to create for path "/workflows/{item.id}/versions" with the input data from the context + #And I want to print the context data + + Scenario: List all + When I want to get path "/workflows" + Then I want to check that element in the response list with "id" equals to value of saved property "noVersionsWorkflowId" exists + And I want to check that element in the response list with "id" equals to value of saved property "draftVersionWorkflowId" exists + And I want to check that element in the response list with "id" equals to value of saved property "certifiedVersionWorkflowId" exists + And I want to check that element in the response list with "id" equals to value of saved property "draftAndCertifiedVersionWorkflowId" exists + + Scenario: List ones with DRAFT version(s) + When I want to get path "/workflows?versionState=DRAFT" + Then I want to check that element in the response list with "id" equals to value of saved property "noVersionsWorkflowId" does not exist + Then I want to check that element in the response list with "id" equals to value of saved property "draftVersionWorkflowId" exists + Then I want to check that element in the response list with "id" equals to value of saved property "certifiedVersionWorkflowId" does not exist + Then I want to check that element in the response list with "id" equals to value of saved property "draftAndCertifiedVersionWorkflowId" exists + + Scenario: List ones with CERTIFIED version(s) + When I want to get path "/workflows?versionState=CERTIFIED" + Then I want to check that element in the response list with "id" equals to value of saved property "noVersionsWorkflowId" does not exist + Then I want to check that element in the response list with "id" equals to value of saved property "draftVersionWorkflowId" does not exist + Then I want to check that element in the response list with "id" equals to value of saved property "certifiedVersionWorkflowId" exists + Then I want to check that element in the response list with "id" equals to value of saved property "draftAndCertifiedVersionWorkflowId" exists + + Scenario: List ones with DRAFT/CERTIFIED version(s) + When I want to get path "/workflows?versionState=DRAFT,CERTIFIED" + Then I want to check that element in the response list with "id" equals to value of saved property "noVersionsWorkflowId" does not exist + Then I want to check that element in the response list with "id" equals to value of saved property "draftVersionWorkflowId" exists + Then I want to check that element in the response list with "id" equals to value of saved property "certifiedVersionWorkflowId" exists + Then I want to check that element in the response list with "id" equals to value of saved property "draftAndCertifiedVersionWorkflowId" exists + + Scenario: List ones with gibberish version(s) = none + When I want to get path "/workflows?versionState=gibberish" + Then I want to check that element in the response list with "id" equals to value of saved property "noVersionsWorkflowId" does not exist + Then I want to check that element in the response list with "id" equals to value of saved property "draftVersionWorkflowId" does not exist + Then I want to check that element in the response list with "id" equals to value of saved property "certifiedVersionWorkflowId" does not exist + Then I want to check that element in the response list with "id" equals to value of saved property "draftAndCertifiedVersionWorkflowId" does not exist \ No newline at end of file diff --git a/workflow/workflow-bdd/features/Workflow_Create_Update.feature b/workflow/workflow-bdd/features/Workflow_Create_Update.feature deleted file mode 100644 index 04a64bf8..00000000 --- a/workflow/workflow-bdd/features/Workflow_Create_Update.feature +++ /dev/null @@ -1,27 +0,0 @@ -Feature: Workflow Example File - - Scenario: Create and get workflow - When I want to create input data - Then I want to update the input property "name" with a random value - Then I want to update the input property "description" with value "workflow desc" - Then I want to update the input property "category" with value "workflow category" - - Then I want to create for path "/workflows" with the input data from the context - Then I want to copy to property "workflowId" from response data path "id" - When I want to get path "/workflows" - Then I want to check that element in the response list with "id" equals to value of saved property "workflowId" exists - - - Scenario: Update workflow - When I want to create input data - Then I want to update the input property "name" with a random value - Then I want to update the input property "description" with value "workflow desc" - Then I want to update the input property "category" with value "workflow category" - Then I want to create for path "/workflows" with the input data from the context - Then I want to copy to property "workflowId" from response data path "id" - - Then I want to update the input property "description" with value "workflow desc updated" - Then I want to set property "desc" to value "workflow desc updated" - Then I want to update for path "/workflows/{workflowId}" with the input data from the context - Then I want to get path "/workflows/{workflowId}" - Then I want to check that property "description" in the response equals to value of saved property "desc" diff --git a/workflow/workflow-bdd/pom.xml b/workflow/workflow-bdd/pom.xml index 3502451c..8ad0584d 100644 --- a/workflow/workflow-bdd/pom.xml +++ b/workflow/workflow-bdd/pom.xml @@ -8,12 +8,6 @@ cucumber-report 1.2.0-SNAPSHOT - - diff --git a/workflow/workflow-bdd/resources/json/createWorkflow.json b/workflow/workflow-bdd/resources/json/createWorkflow.json index 074899e9..cc200efb 100644 --- a/workflow/workflow-bdd/resources/json/createWorkflow.json +++ b/workflow/workflow-bdd/resources/json/createWorkflow.json @@ -1 +1,4 @@ -{"name":"RANDOM","description":"Workflow Description","category":"category"} \ No newline at end of file +{ + "name": "RANDOM", + "description": "Workflow Description" +} \ No newline at end of file diff --git a/workflow/workflow-bdd/stepDefinitions/General_Steps.js b/workflow/workflow-bdd/stepDefinitions/General_Steps.js index 0550e415..2e74c6ee 100644 --- a/workflow/workflow-bdd/stepDefinitions/General_Steps.js +++ b/workflow/workflow-bdd/stepDefinitions/General_Steps.js @@ -151,7 +151,7 @@ Then('I want to check property {string} does not exist', function(string) { * @module ContextData * @description Use during development to see what is on the context * @exampleFile Example_ResponseData_CheckAndManipulation.feature -* @step I want to print context data +* @step I want to print the context data **/ Then('I want to print the context data', function() { console.log('------------ context ---------------'); @@ -268,13 +268,13 @@ Then('I want to check that element in the response list with {string} equals to **/ Then('I want to check that element in the response list with {string} equals to value of saved property {string} exists', function(propertyPath, valueProperty) { const results = this.context.responseData.results; - assert.notEqual(results.find(result => this.context[valueProperty] === _.get(result, propertyPath)), undefined); + assert.notEqual(results.find(result => _.get(this.context, valueProperty) === _.get(result, propertyPath)), undefined); }); Then('I want to check that property {string} in the response equals to value of saved property {string}', function(propertyPath, valueProperty) { const results = this.context.responseData; - assert.equal(results[propertyPath],this.context[valueProperty]); + assert.equal(results[propertyPath], _.get(this.context, valueProperty)); }); /** diff --git a/workflow/workflow-bdd/stepDefinitions/InputData_steps.js b/workflow/workflow-bdd/stepDefinitions/InputData_steps.js index 73695d0e..6263bb73 100644 --- a/workflow/workflow-bdd/stepDefinitions/InputData_steps.js +++ b/workflow/workflow-bdd/stepDefinitions/InputData_steps.js @@ -62,6 +62,16 @@ Then('I want to update the input property {string} with value {string}', functio _.set(this.context.inputData, string, string2); }); +/** + * @module InputData + * @description sets the property on the input data to the value of the given property + * @exampleFile WorkflowList.feature + * @step I want to update the input property {string} with value of property {string} + **/ +Then('I want to update the input property {string} with value of property {string}', function(string, string2) { + _.set(this.context.inputData, string, _.get(this.context, string2)); +}); + /** * @module InputData * @description removes a property from the input data object diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java index b0ae7cc1..0a06ce79 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java @@ -6,16 +6,20 @@ import static org.onap.sdc.workflow.api.RestConstants.SORT_PARAM; import static org.onap.sdc.workflow.api.RestConstants.USER_ID_HEADER_PARAM; import com.google.common.collect.ImmutableSet; - -import java.util.Arrays; -import java.util.Set; - import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; import org.onap.sdc.workflow.api.types.CollectionWrapper; import org.onap.sdc.workflow.persistence.types.Workflow; +import org.onap.sdc.workflow.persistence.types.WorkflowVersionState; import org.onap.sdc.workflow.services.WorkflowManager; import org.onap.sdc.workflow.services.exceptions.InvalidPaginationParameterException; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.PageRequest; @@ -26,6 +30,7 @@ import org.springframework.data.web.SortDefault; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -33,6 +38,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RequestMapping("/workflows") @@ -40,6 +46,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController("workflowController") public class WorkflowController { + private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowController.class); private final WorkflowManager workflowManager; @Autowired @@ -49,27 +56,39 @@ public class WorkflowController { @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("List workflows") - public CollectionWrapper list(@RequestHeader(USER_ID_HEADER_PARAM) String user, - @PageableDefault(size = SIZE_DEFAULT) - @SortDefault.SortDefaults({ - @SortDefault(sort = SORT_FIELD_NAME, direction = Sort.Direction.ASC) - }) Pageable pageable) { + public CollectionWrapper 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); + + Set filter; + try { + filter = versionStateFilter == null ? null : + Arrays.stream(versionStateFilter.split(",")).map(WorkflowVersionState::valueOf) + .collect(Collectors.toSet()); + } catch (Exception e) { + LOGGER.info("Invalid versionState filter value - return empty list of workflows"); + return new CollectionWrapper<>(Collections.emptyList()); + } + return new CollectionWrapper<>(pageRequest.getPageSize(), pageRequest.getPageNumber(), - workflowManager.list(pageRequest)); + workflowManager.list(filter, pageRequest)); } @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @ApiOperation("Create workflow") - public ResponseEntity create(@RequestBody Workflow workflow, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { + public ResponseEntity create(@Validated @RequestBody Workflow workflow, + @RequestHeader(USER_ID_HEADER_PARAM) String user) { return new ResponseEntity<>(workflowManager.create(workflow), HttpStatus.CREATED); } @GetMapping(path = "/{workflowId}") @ApiOperation("Get workflow") public Workflow get(@PathVariable("workflowId") String workflowId, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @RequestHeader(USER_ID_HEADER_PARAM) String user) { Workflow workflow = new Workflow(); workflow.setId(workflowId); return workflowManager.get(workflow); @@ -78,7 +97,7 @@ 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_PARAM) String user) { workflow.setId(workflowId); workflowManager.update(workflow); return workflow; diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java index 6ae8e34d..e7ee7571 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java @@ -4,12 +4,19 @@ import static org.onap.sdc.workflow.api.RestConstants.USER_ID_HEADER_PARAM; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; import org.onap.sdc.workflow.api.types.CollectionWrapper; -import org.onap.sdc.workflow.api.types.VersionRequestDto; import org.onap.sdc.workflow.api.types.VersionStateDto; import org.onap.sdc.workflow.persistence.types.ArtifactEntity; import org.onap.sdc.workflow.persistence.types.WorkflowVersion; +import org.onap.sdc.workflow.persistence.types.WorkflowVersionState; import org.onap.sdc.workflow.services.WorkflowVersionManager; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.io.InputStreamResource; @@ -26,6 +33,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @@ -34,41 +42,54 @@ import org.springframework.web.multipart.MultipartFile; @RestController("workflowsVersionController") public class WorkflowVersionController { + private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowVersionController.class); private final WorkflowVersionManager workflowVersionManager; @Autowired public WorkflowVersionController( - @Qualifier("workflowVersionManager") WorkflowVersionManager workflowVersionManager) { + @Qualifier("workflowVersionManager") WorkflowVersionManager workflowVersionManager) { this.workflowVersionManager = workflowVersionManager; } @GetMapping @ApiOperation("List workflow versions") public CollectionWrapper list(@PathVariable("workflowId") String workflowId, - @RequestHeader(USER_ID_HEADER_PARAM) String user) { - return new CollectionWrapper<>(workflowVersionManager.list(workflowId)); + @ApiParam(value = "Filter by state", allowableValues = "DRAFT,CERTIFIED") + @RequestParam(value = "state", required = false) String stateFilter, + @RequestHeader(USER_ID_HEADER_PARAM) String user) { + Set filter; + try { + filter = stateFilter == null ? null : + Arrays.stream(stateFilter.split(",")).map(WorkflowVersionState::valueOf) + .collect(Collectors.toSet()); + } catch (Exception e) { + LOGGER.info("Invalid state filter value - return empty list of workflow versions"); + return new CollectionWrapper<>(Collections.emptyList()); + } + return new CollectionWrapper<>(workflowVersionManager.list(workflowId, filter)); } @PostMapping @ApiOperation("Create workflow version") - public ResponseEntity create(@RequestBody VersionRequestDto versionRequest, - @PathVariable("workflowId") String workflowId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { - - WorkflowVersion createdVersion = workflowVersionManager.create(workflowId, versionRequest); + public ResponseEntity create(@RequestBody WorkflowVersion version, + @PathVariable("workflowId") String workflowId, + @RequestParam(value = "baseVersionId", required = false) String baseVersionId, + @RequestHeader(USER_ID_HEADER_PARAM) String user) { + WorkflowVersion createdVersion = workflowVersionManager.create(workflowId, baseVersionId, version); return new ResponseEntity<>(createdVersion, HttpStatus.CREATED); } @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_PARAM) String user) { return workflowVersionManager.get(workflowId, versionId); } @PutMapping("/{versionId}") @ApiOperation("Update workflow version") public void update(@RequestBody 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_PARAM) String user) { version.setId(versionId); workflowVersionManager.update(workflowId, version); } @@ -76,15 +97,15 @@ 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_PARAM) String user) { return new VersionStateDto(workflowVersionManager.getState(workflowId, versionId)); } @PostMapping("/{versionId}/state") @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) { + @PathVariable("workflowId") String workflowId, @PathVariable("versionId") String versionId, + @RequestHeader(USER_ID_HEADER_PARAM) String user) { workflowVersionManager.updateState(workflowId, versionId, state.getName()); return new VersionStateDto(state.getName()); } @@ -92,26 +113,26 @@ 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_PARAM) String user) { workflowVersionManager.uploadArtifact(workflowId, versionId, fileToUpload); } @GetMapping("/{versionId}/artifact") @ApiOperation("Download workflow version artifact") public ResponseEntity getArtifact(@PathVariable("workflowId") String workflowId, - @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + @PathVariable("versionId") String versionId, @RequestHeader(USER_ID_HEADER_PARAM) String user) { ArtifactEntity artifact = workflowVersionManager.getArtifact(workflowId, versionId); return ResponseEntity.ok() - .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + artifact.getFileName()) - .contentType(MediaType.APPLICATION_OCTET_STREAM) - .body(new InputStreamResource(artifact.getArtifactData())); + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + artifact.getFileName()) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(new InputStreamResource(artifact.getArtifactData())); } @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_PARAM) String user) { workflowVersionManager.deleteArtifact(workflowId, versionId); } } diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionRequestDto.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionRequestDto.java deleted file mode 100644 index bdd1c4ac..00000000 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionRequestDto.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.onap.sdc.workflow.api.types; - -import java.util.Collection; -import lombok.Data; -import org.onap.sdc.workflow.persistence.types.ParameterEntity; - -@Data -public class VersionRequestDto { - - private String description; - private String baseVersionId; - private Collection inputs; - private Collection outputs; - -} diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryImpl.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryImpl.java index 15964b3d..6c8edcea 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryImpl.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryImpl.java @@ -50,7 +50,7 @@ public class ParameterRepositoryImpl implements ParameterRepository { SessionContext context = createSessionContext(); ElementContext elementContext = new ElementContext(id, versionId); - return zusammenAdaptor.listElementsByName(context, elementContext, null, role.name()).stream() + return zusammenAdaptor.listElementsByName(context, elementContext, null, getParentElementType(role)).stream() .map(this::mapElementInfoToParameter).collect(Collectors.toList()); } @@ -61,8 +61,8 @@ public class ParameterRepositoryImpl implements ParameterRepository { SessionContext context = createSessionContext(); ElementContext elementContext = new ElementContext(id, versionId); - Optional optionalParentElement = zusammenAdaptor.getElementInfoByName(context, elementContext, null, - getParentElementType(role)); + Optional optionalParentElement = + zusammenAdaptor.getElementInfoByName(context, elementContext, null, getParentElementType(role)); if (!optionalParentElement.isPresent()) { return; @@ -81,17 +81,17 @@ public class ParameterRepositoryImpl implements ParameterRepository { SessionContext context = createSessionContext(); ElementContext elementContext = new ElementContext(id, versionId); - Optional element = zusammenAdaptor.getElementInfo(context, elementContext,new Id(parameterId)); + Optional element = zusammenAdaptor.getElementInfo(context, elementContext, new Id(parameterId)); return element.map(this::mapElementInfoToParameter).orElse(null); } @Override - public void delete(String id, String versionId, String parameterId){ + public void delete(String id, String versionId, String parameterId) { SessionContext context = createSessionContext(); ElementContext elementContext = new ElementContext(id, versionId); - ZusammenElement parameterElement = buildElement(new Id(parameterId),Action.DELETE); + ZusammenElement parameterElement = buildElement(new Id(parameterId), Action.DELETE); zusammenAdaptor.saveElement(context, elementContext, parameterElement, String.format("Delete Parameter with id %s", parameterId)); @@ -101,10 +101,8 @@ public class ParameterRepositoryImpl implements ParameterRepository { @Override public ParameterEntity create(String id, String versionId, ParameterRole role, ParameterEntity parameter) { - ZusammenElement parameterElement = - parameterToZusammenElement(parameter,role, Action.CREATE); - ZusammenElement parentElement = - buildStructuralElement(getParentElementType(role), Action.IGNORE); + ZusammenElement parameterElement = parameterToZusammenElement(parameter, role, Action.CREATE); + ZusammenElement parentElement = buildStructuralElement(getParentElementType(role), Action.IGNORE); parentElement.addSubElement(parameterElement); SessionContext context = createSessionContext(); @@ -123,20 +121,18 @@ public class ParameterRepositoryImpl implements ParameterRepository { SessionContext context = createSessionContext(); ElementContext elementContext = new ElementContext(id, versionId); - ZusammenElement parameterElement = - parameterToZusammenElement(parameter, role, Action.UPDATE); + ZusammenElement parameterElement = parameterToZusammenElement(parameter, role, Action.UPDATE); zusammenAdaptor.saveElement(context, elementContext, parameterElement, "Update WorkflowVersion Parameter"); } - private ZusammenElement parameterToZusammenElement(ParameterEntity parameter, ParameterRole role, - Action action) { + private ZusammenElement parameterToZusammenElement(ParameterEntity parameter, ParameterRole role, Action action) { ZusammenElement parameterElement = buildElement(parameter.getId() == null ? null : new Id(parameter.getId()), action); Info info = new Info(); info.setName(parameter.getName()); - info.addProperty(ElementPropertyName.elementType.name(), WorkflowElementType.valueOf(role.name())); + info.addProperty(ElementPropertyName.elementType.name(), WorkflowElementType.valueOf(role.name())); info.addProperty(ParameterPropertyName.TYPE.name(), parameter.getType()); info.addProperty(ParameterPropertyName.mandatory.name(), parameter.isMandatory()); parameterElement.setInfo(info); @@ -144,26 +140,25 @@ public class ParameterRepositoryImpl implements ParameterRepository { return parameterElement; } + private ParameterEntity mapElementInfoToParameter(ElementInfo elementInfo) { + ParameterEntity parameterEntity = new ParameterEntity(); + parameterEntity.setId(elementInfo.getId().getValue()); + parameterEntity.setName(elementInfo.getInfo().getName()); + parameterEntity + .setType(ParameterType.valueOf(elementInfo.getInfo().getProperty(ParameterPropertyName.TYPE.name()))); + parameterEntity.setMandatory(elementInfo.getInfo().getProperty(ParameterPropertyName.mandatory.name())); + return parameterEntity; + } + private static String getParentElementType(ParameterRole role) { - switch (role){ + switch (role) { case INPUT: return WorkflowElementType.INPUTS.name(); case OUTPUT: return WorkflowElementType.OUTPUTS.name(); default: - throw new RuntimeException("Wrong Element Type"); + throw new IllegalArgumentException("Wrong Element Type"); } } - private ParameterEntity mapElementInfoToParameter(ElementInfo elementInfo){ - ParameterEntity parameterEntity = new ParameterEntity(); - parameterEntity.setId(elementInfo.getId().getValue()); - parameterEntity.setName(elementInfo.getInfo().getName()); - parameterEntity.setType(ParameterType.valueOf( - elementInfo.getInfo().getProperty(ParameterPropertyName.TYPE.name()))); - parameterEntity.setMandatory(elementInfo.getInfo().getProperty( - ParameterPropertyName.mandatory.name())); - return parameterEntity; - } - } diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java index 8c66d820..ac24870d 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java @@ -1,12 +1,18 @@ package org.onap.sdc.workflow.persistence.types; +import java.util.Collection; +import java.util.Set; +import javax.validation.constraints.NotNull; import lombok.Data; @Data public class Workflow { private String id; + @NotNull private String name; private String description; + private Set versionStates; + private Collection versions; } diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowVersion.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowVersion.java index e4158b19..bef8066b 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowVersion.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowVersion.java @@ -1,6 +1,7 @@ package org.onap.sdc.workflow.persistence.types; import java.util.Collection; +import java.util.Collections; import java.util.Date; import lombok.Data; @@ -12,11 +13,11 @@ public class WorkflowVersion { private String name; private String description; private String baseId; + private WorkflowVersionState state; + private Collection inputs = Collections.emptyList(); + private Collection outputs = Collections.emptyList(); private Date creationTime; private Date modificationTime; - private WorkflowVersionState state; - private Collection inputs; - private Collection outputs; public WorkflowVersion(String id) { diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java index e2572b78..e940a851 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java @@ -1,12 +1,14 @@ package org.onap.sdc.workflow.services; 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; public interface WorkflowManager { - Collection list(Pageable pageable); + Collection list(Set versionStatesFilter, Pageable pageable); Workflow get(Workflow workflow); diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowVersionManager.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowVersionManager.java index 8b4b8949..bb18ac9a 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowVersionManager.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowVersionManager.java @@ -1,7 +1,7 @@ package org.onap.sdc.workflow.services; import java.util.Collection; -import org.onap.sdc.workflow.api.types.VersionRequestDto; +import java.util.Set; import org.onap.sdc.workflow.persistence.types.ArtifactEntity; import org.onap.sdc.workflow.persistence.types.WorkflowVersion; import org.onap.sdc.workflow.persistence.types.WorkflowVersionState; @@ -10,11 +10,11 @@ import org.springframework.web.multipart.MultipartFile; public interface WorkflowVersionManager { - Collection list(String workflowId); + Collection list(String workflowId, Set stateFilter); - WorkflowVersion create(String workflowId, VersionRequestDto versionRequest); + WorkflowVersion create(String workflowId, String baseVersionId, WorkflowVersion version); - void update(String id, WorkflowVersion version); + void update(String workflowId, WorkflowVersion version); WorkflowVersion get(String workflowId, String versionId); diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionCreationException.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionCreationException.java index af01c68f..5c2e4a89 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionCreationException.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionCreationException.java @@ -3,10 +3,10 @@ package org.onap.sdc.workflow.services.exceptions; public class VersionCreationException extends RuntimeException { private static final String MSG = "Error creating a new version for workflow with id %s"; - private static final String MSG_WITH_BASE_ID = MSG + " based on version %s"; + private static final String MSG_WITH_BASE_ID = MSG + " based on version %s: %s"; - public VersionCreationException(String workflowId, String baseVersionId) { - super(String.format(MSG_WITH_BASE_ID, workflowId, baseVersionId)); + public VersionCreationException(String workflowId, String baseVersionId, String detailedMessage) { + super(String.format(MSG_WITH_BASE_ID, workflowId, baseVersionId, detailedMessage)); } public VersionCreationException(String workflowId) { diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java index 97d81689..4ce7d9f3 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java @@ -7,17 +7,21 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; 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.openecomp.sdc.logging.api.Logger; import org.openecomp.sdc.logging.api.LoggerFactory; import org.openecomp.sdc.versioning.ItemManager; +import org.openecomp.sdc.versioning.dao.types.VersionStatus; import org.openecomp.sdc.versioning.types.Item; import org.openecomp.sdc.versioning.types.ItemStatus; import org.springframework.beans.factory.annotation.Autowired; @@ -25,6 +29,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; @Service("workflowManager") public class WorkflowManagerImpl implements WorkflowManager { @@ -32,27 +37,36 @@ public class WorkflowManagerImpl implements WorkflowManager { public static final String WORKFLOW_TYPE = "WORKFLOW"; 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"; - static final Predicate ITEM_PREDICATE = item -> WORKFLOW_TYPE.equals(item.getType()); + static final Predicate WORKFLOW_ITEM_FILTER = item -> WORKFLOW_TYPE.equals(item.getType()); + private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowManagerImpl.class); private final ItemManager itemManager; private final UniqueValueService uniqueValueService; private final WorkflowMapper workflowMapper; - private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowManagerImpl.class); + private final VersionStateMapper versionStateMapper; @Autowired public WorkflowManagerImpl(ItemManager itemManager, - @Qualifier("uniqueValueService") UniqueValueService uniqueValueService, WorkflowMapper workflowMapper) { + @Qualifier("uniqueValueService") UniqueValueService uniqueValueService, WorkflowMapper workflowMapper, + VersionStateMapper versionStateMapper) { this.itemManager = itemManager; this.uniqueValueService = uniqueValueService; this.workflowMapper = workflowMapper; + this.versionStateMapper = versionStateMapper; } @Override - public Collection list(Pageable pageRequest) { - List workflowList = itemManager.list(ITEM_PREDICATE).stream() - .map( workflowMapper::itemToWorkflow).collect(Collectors.toList()); - sortWorkflowList(workflowList, pageRequest); - return applyLimitAndOffset(workflowList, pageRequest); + public Collection list(Set versionStatesFilter, Pageable pageRequest) { + Set versionStatusesFilter = + CollectionUtils.isEmpty(versionStatesFilter) ? Collections.emptySet() : + versionStatesFilter.stream().map(versionStateMapper::workflowVersionStateToVersionStatus) + .collect(Collectors.toSet()); + + List workflows = itemManager.list(getFilter(versionStatusesFilter)).stream() + .map(workflowMapper::itemToWorkflow) + .collect(Collectors.toList()); + sortWorkflows(workflows, pageRequest); + return applyLimitAndOffset(workflows, pageRequest); } @Override @@ -71,9 +85,10 @@ public class WorkflowManagerImpl implements WorkflowManager { item.setStatus(ItemStatus.ACTIVE); uniqueValueService.validateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, new String[] {workflow.getName()}); - workflow.setId(itemManager.create(item).getId()); + Item createdItem = itemManager.create(item); uniqueValueService.createUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, new String[] {workflow.getName()}); - return workflow; + + return workflowMapper.itemToWorkflow(createdItem); } @Override @@ -114,17 +129,24 @@ public class WorkflowManagerImpl implements WorkflowManager { return selectedWorkflows; } - private void sortWorkflowList(List workflowList, Pageable pageRequest) { - Comparator comparator = getWorkflowListComparator(); + private void sortWorkflows(List workflows, Pageable pageRequest) { + Comparator comparator = getWorkflowsComparator(); if (pageRequest.getSort().getOrderFor(SORT_FIELD_NAME).getDirection() == Sort.Direction.ASC) { - workflowList.sort(comparator); + workflows.sort(comparator); } else { - workflowList.sort(Collections.reverseOrder(comparator)); + workflows.sort(Collections.reverseOrder(comparator)); } } - private Comparator getWorkflowListComparator() { + private Comparator getWorkflowsComparator() { //More comparators can be added if required based on sort field name return new WorkflowNameComparator(); } + + private static Predicate getFilter(Set versionStatuses) { + return CollectionUtils.isEmpty(versionStatuses) + ? WORKFLOW_ITEM_FILTER + : WORKFLOW_ITEM_FILTER.and(item -> item.getVersionStatusCounters().keySet().stream() + .anyMatch(versionStatuses::contains)); + } } diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java index de9c8dd3..a3e775ec 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java @@ -1,14 +1,17 @@ package org.onap.sdc.workflow.services.impl; -import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Certified; +import static org.onap.sdc.workflow.persistence.types.WorkflowVersionState.CERTIFIED; import java.io.IOException; import java.io.InputStream; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; -import org.onap.sdc.workflow.api.types.VersionRequestDto; import org.onap.sdc.workflow.persistence.ArtifactRepository; import org.onap.sdc.workflow.persistence.ParameterRepository; import org.onap.sdc.workflow.persistence.types.ArtifactEntity; @@ -57,56 +60,52 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { } @Override - public Collection list(String workflowId) { - Collection versions = - versioningManager.list(workflowId).stream().map(versionMapper::versionToWorkflowVersion) - .collect(Collectors.toList()); - versions.forEach(workflowVersion -> addVersionParameters(workflowId,workflowVersion)); - - return versions; + public Collection list(String workflowId, Set stateFilter) { + return versioningManager.list(workflowId).stream().map(versionMapper::versionToWorkflowVersion) + .filter(workflowVersion -> stateFilter.contains(workflowVersion.getState())) + .peek(workflowVersion -> loadAndAddParameters(workflowId, workflowVersion)) + .collect(Collectors.toList()); } @Override public WorkflowVersion get(String workflowId, String versionId) { WorkflowVersion workflowVersion = versionMapper.versionToWorkflowVersion(getVersion(workflowId, versionId)); - addVersionParameters(workflowId,workflowVersion); + loadAndAddParameters(workflowId, workflowVersion); return workflowVersion; - } - @Override - public WorkflowVersion create(String workflowId, VersionRequestDto versionRequest) { + public WorkflowVersion create(String workflowId, String baseVersionId, WorkflowVersion workflowVersion) { List versions = versioningManager.list(workflowId); - if (versionRequest.getBaseVersionId() != null) { - validateVersionExistAndCertified(workflowId, versions, versionRequest.getBaseVersionId()); + if (baseVersionId != null) { + if (!workflowVersion.getInputs().isEmpty() || !workflowVersion.getOutputs().isEmpty()) { + throw new VersionCreationException(workflowId, baseVersionId, "Inputs/Outputs should not be supplied"); + } + validateVersionExistAndCertified(workflowId, versions, baseVersionId); } else if (!versions.isEmpty()) { throw new VersionCreationException(workflowId); } Version version = new Version(); - version.setDescription(versionRequest.getDescription()); - version.setBaseId(versionRequest.getBaseVersionId()); + version.setDescription(workflowVersion.getDescription()); + version.setBaseId(baseVersionId); Version createdVersion = versioningManager.create(workflowId, version, VersionCreationMethod.major); if (versions.isEmpty()) { // only for first version artifactRepository.createStructure(workflowId, createdVersion.getId()); parameterRepository.createStructure(workflowId, createdVersion.getId()); - versioningManager.publish(workflowId, createdVersion, "Add workflow structure"); + updateParameters(workflowId, createdVersion.getId(), workflowVersion.getInputs(), workflowVersion.getOutputs()); + versioningManager.publish(workflowId, createdVersion, "Add initial data"); } - updateVersionParameters(workflowId, createdVersion.getId(), ParameterRole.INPUT, versionRequest.getInputs()); - updateVersionParameters(workflowId, createdVersion.getId(), ParameterRole.OUTPUT, versionRequest.getOutputs()); - return get(workflowId, createdVersion.getId()); } @Override public void update(String workflowId, WorkflowVersion workflowVersion) { Version retrievedVersion = getVersion(workflowId, workflowVersion.getId()); - if (WorkflowVersionState.CERTIFIED - .equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) { + if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) { throw new VersionModificationException(workflowId, workflowVersion.getId()); } @@ -114,8 +113,7 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { version.setName(retrievedVersion.getName()); version.setStatus(retrievedVersion.getStatus()); - updateVersionParameters(workflowId, version.getId(), ParameterRole.INPUT, workflowVersion.getInputs()); - updateVersionParameters(workflowId, version.getId(), ParameterRole.OUTPUT, workflowVersion.getOutputs()); + updateParameters(workflowId, version.getId(), workflowVersion.getInputs(), workflowVersion.getOutputs()); versioningManager.updateVersion(workflowId, version); versioningManager.publish(workflowId, version, "Update version"); @@ -128,35 +126,31 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { @Override public void updateState(String workflowId, String versionId, WorkflowVersionState state) { - Version retrievedVersion = getVersion(workflowId, versionId); WorkflowVersionState retrievedState = - versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()); - if (WorkflowVersionState.CERTIFIED.equals(retrievedState) || retrievedState.equals(state)) { - LOGGER.error(String.format( - "Workflow Version is certified and can not be edited.Workflow id %s and version id %s", workflowId, - versionId)); + versionStateMapper.versionStatusToWorkflowVersionState(getVersion(workflowId, versionId).getStatus()); + + if (state == CERTIFIED) { + try { + versioningManager.submit(workflowId, new Version(versionId), + String.format("Update version state to %s", state.name())); + } catch (Exception e) { + throw new VersionStateModificationException(workflowId, versionId, retrievedState, state); + } + } else { throw new VersionStateModificationException(workflowId, versionId, retrievedState, state); } - - retrievedVersion.setStatus(versionStateMapper.workflowVersionStateToVersionStatus(state)); - versioningManager.updateVersion(workflowId, retrievedVersion); - versioningManager.publish(workflowId, retrievedVersion, - String.format("Update version state from %s to %s", retrievedState.name(), state.name())); } @Override public void uploadArtifact(String workflowId, String versionId, MultipartFile artifact) { Version retrievedVersion = getVersion(workflowId, versionId); - if (WorkflowVersionState.CERTIFIED - .equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) { - LOGGER.error(String.format("Workflow Version Artifact was not found for workflow id %s and version id %s", - workflowId, versionId)); + if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) { throw new VersionModificationException(workflowId, versionId); } try (InputStream artifactData = artifact.getInputStream()) { ArtifactEntity artifactEntity = - new ArtifactEntity(StringUtils.cleanPath(artifact.getOriginalFilename()), artifactData); + new ArtifactEntity(StringUtils.cleanPath(artifact.getOriginalFilename()), artifactData); artifactRepository.update(workflowId, versionId, artifactEntity); versioningManager.publish(workflowId, new Version(versionId), "Update Artifact"); @@ -183,7 +177,7 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { @Override public void deleteArtifact(String workflowId, String versionId) { WorkflowVersion retrievedVersion = get(workflowId, versionId); - if (WorkflowVersionState.CERTIFIED.equals(retrievedVersion.getState())) { + if (CERTIFIED.equals(retrievedVersion.getState())) { LOGGER.error(String.format( "Workflow Version is certified and can not be edited.Workflow id %s and version id %s", workflowId, versionId)); @@ -196,14 +190,13 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { private void validateVersionExistAndCertified(String workflowId, List versions, String versionId) { Version baseVersion = findVersion(versions, versionId).orElseThrow( - () -> new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId))); + () -> new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId))); - if (!Certified.equals(baseVersion.getStatus())) { - throw new VersionCreationException(workflowId, versionId); + if (CERTIFIED != versionStateMapper.versionStatusToWorkflowVersionState(baseVersion.getStatus())) { + throw new VersionCreationException(workflowId, versionId, "base version must be CERTIFIED"); } } - private Version getVersion(String workflowId, String versionId) { try { Version version = versioningManager.get(workflowId, new Version(versionId)); @@ -219,34 +212,42 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { } } + private void updateParameters(String workflowId, String versionId, Collection inputs, + Collection outputs) { + updateVersionParameters(workflowId, versionId, ParameterRole.INPUT, inputs); + updateVersionParameters(workflowId, versionId, ParameterRole.OUTPUT, outputs); + } + private void updateVersionParameters(String workflowId, String versionId, ParameterRole role, Collection parameters) { - Collection retrievedParameters = parameterRepository.list(workflowId, versionId, role); + Collection retrievedParams = parameterRepository.list(workflowId, versionId, role); + Map retrievedParamsByName = + retrievedParams.stream().collect(Collectors.toMap(ParameterEntity::getName, Function.identity())); - parameters.forEach(parameterEntity -> { - if (retrievedParameters.stream().anyMatch( - parameterEntity1 -> parameterEntity.getName().equals(parameterEntity1.getName()))) { - parameterRepository.update(workflowId, versionId, role, parameterEntity); + Set namesOfParamsToKeep = new HashSet<>(); + for (ParameterEntity parameter : parameters) { + + ParameterEntity retrievedParam = retrievedParamsByName.get(parameter.getName()); + if (retrievedParam == null) { + parameterRepository.create(workflowId, versionId, role, parameter); } else { - parameterRepository.create(workflowId, versionId, role, parameterEntity); + parameterRepository.update(workflowId, versionId, role, parameter); + namesOfParamsToKeep.add(parameter.getName()); } - }); + } - retrievedParameters.forEach(parameterEntity -> { - if (parameters.stream().noneMatch( - parameterEntity1 -> parameterEntity.getName().equals(parameterEntity1.getName()))) { - parameterRepository.delete(workflowId, versionId, parameterEntity.getId()); - } - }); + retrievedParams.stream().filter(retrievedParam -> !namesOfParamsToKeep.contains(retrievedParam.getName())) + .forEach(retrievedParam -> parameterRepository + .delete(workflowId, versionId, retrievedParam.getId())); } - private static Optional findVersion(List versions, String versionId) { - return versions.stream().filter(version -> versionId.equals(version.getId())).findFirst(); - } - - private void addVersionParameters(String workflowId, WorkflowVersion workflowVersion) { + private void loadAndAddParameters(String workflowId, WorkflowVersion workflowVersion) { workflowVersion.setInputs(parameterRepository.list(workflowId, workflowVersion.getId(), ParameterRole.INPUT)); workflowVersion.setOutputs(parameterRepository.list(workflowId, workflowVersion.getId(), ParameterRole.OUTPUT)); } + + private static Optional findVersion(List versions, String versionId) { + return versions.stream().filter(version -> versionId.equals(version.getId())).findFirst(); + } } \ No newline at end of file diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapper.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapper.java index 0c2f5391..0afc9b11 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapper.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapper.java @@ -1,5 +1,8 @@ package org.onap.sdc.workflow.services.impl.mappers; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; import org.mapstruct.ValueMapping; @@ -18,5 +21,11 @@ public interface VersionStateMapper { @InheritInverseConfiguration VersionStatus workflowVersionStateToVersionStatus(WorkflowVersionState status); + default Set versionStatusCountersToWorkflowVersionStates( + Map versionStatusCounters) { + return versionStatusCounters.keySet().stream().map(this::versionStatusToWorkflowVersionState) + .collect(Collectors.toSet()); + } + } diff --git a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapper.java b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapper.java index 34327ce7..c1e7e776 100644 --- a/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapper.java +++ b/workflow/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapper.java @@ -3,17 +3,20 @@ package org.onap.sdc.workflow.services.impl.mappers; import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.Mappings; import org.onap.sdc.workflow.persistence.types.Workflow; import org.onap.sdc.workflow.services.impl.WorkflowManagerImpl; import org.openecomp.sdc.versioning.types.Item; -@Mapper(componentModel = "spring", imports = WorkflowManagerImpl.class) +@Mapper(componentModel = "spring", imports = WorkflowManagerImpl.class, uses = VersionStateMapper.class) public interface WorkflowMapper { + @Mapping(source = "versionStatusCounters", target = "versionStates") Workflow itemToWorkflow(Item item); @InheritInverseConfiguration - @Mapping(expression = "java(WorkflowManagerImpl.WORKFLOW_TYPE)", target = "type") + @Mappings({@Mapping(expression = "java(WorkflowManagerImpl.WORKFLOW_TYPE)", target = "type"), + @Mapping(target = "versionStatusCounters", ignore = true)}) Item workflowToItem(Workflow workflow); } diff --git a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java index 06d55479..7a7e715e 100644 --- a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java +++ b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java @@ -5,11 +5,13 @@ import static org.onap.sdc.workflow.api.RestConstants.PAGE_PARAM; import static org.onap.sdc.workflow.api.RestConstants.SORT_PARAM; public class RestPath { + private RestPath() { //Hiding implicit constructor } private static final String WORKFLOWS_URL = "/workflows"; + public static final String WORKFLOWS_WITH_VERSION_STATE_FILTER_URL = WORKFLOWS_URL + "?versionState=%s"; private static final String WORKFLOW_URL_FORMATTER = WORKFLOWS_URL + "/%s"; private static final String VERSIONS_URL_FORMATTER = WORKFLOWS_URL + "/%s/versions"; private static final String VERSION_URL_FORMATTER = WORKFLOWS_URL + "/%s/versions/%s"; @@ -42,19 +44,23 @@ public class RestPath { return String.format(WORKFLOW_URL_FORMATTER_QUERY_PARAMS_NO_SORT_AND_OFFSET, size); } - public static String getWorkflowsPath(){ + public static String getWorkflowsPath() { return WORKFLOWS_URL; } - public static String getWorkflowPath(String workflowId){ + public static String getWorkflowsWithVersionStateFilterPath(String versionState) { + return String.format(WORKFLOWS_WITH_VERSION_STATE_FILTER_URL, versionState); + } + + public static String getWorkflowPath(String workflowId) { return String.format(WORKFLOW_URL_FORMATTER, workflowId); } - public static String getWorkflowVersions(String workflowId){ + public static String getWorkflowVersions(String workflowId) { return String.format(VERSIONS_URL_FORMATTER, workflowId); } - public static String getWorkflowVersion(String workflowId, String versionId){ + public static String getWorkflowVersion(String workflowId, String versionId) { return String.format(VERSION_URL_FORMATTER, workflowId, versionId); } } diff --git a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/TestUtil.java b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/TestUtil.java index 47ce060b..e2a566aa 100644 --- a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/TestUtil.java +++ b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/TestUtil.java @@ -7,32 +7,29 @@ public class TestUtil { private static final String WORKFLOW_TYPE = "WORKFLOW"; - public static Workflow createWorkflow(int workflowPropertySuffix, boolean createId) { + public static Workflow createWorkflow(int workflowNum, boolean createId) { Workflow workflow = new Workflow(); if (createId) { - workflow.setId("workflowId" + workflowPropertySuffix); + workflow.setId(String.valueOf(workflowNum)); } - workflow.setName("workflowName" + workflowPropertySuffix); - workflow.setDescription("workflowDesc" + workflowPropertySuffix); + workflow.setName("Workflow_" + workflowNum); + workflow.setDescription("Description_" + workflowNum); return workflow; } - public static Item createItem(int itemNum,boolean setType, boolean setId){ + public static Item createItem(int itemNum, boolean setType, boolean setId) { Item item = new Item(); - if(setId) { - item.setId("workflowId" + itemNum); + if (setId) { + item.setId(String.valueOf(itemNum)); } - item.addProperty("category","category_" + itemNum); item.setName("Workflow_" + itemNum); item.setDescription("Description_" + itemNum); - if(setType) { + if (setType) { item.setType(WORKFLOW_TYPE); } - return item; } - } diff --git a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java index b73427e8..5e7df483 100644 --- a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java +++ b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java @@ -4,8 +4,8 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.onap.sdc.workflow.TestUtil.createWorkflow; import static org.onap.sdc.workflow.api.RestConstants.PAGE_DEFAULT; @@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableSet; import com.google.gson.Gson; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; import org.junit.Before; @@ -38,12 +39,11 @@ import org.onap.sdc.workflow.RestPath; import org.onap.sdc.workflow.api.exceptionshandlers.CustomizedResponseEntityExceptionHandler; import org.onap.sdc.workflow.api.types.CollectionWrapper; import org.onap.sdc.workflow.persistence.types.Workflow; +import org.onap.sdc.workflow.persistence.types.WorkflowVersionState; import org.onap.sdc.workflow.services.WorkflowManager; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; -import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @RunWith(MockitoJUnitRunner.class) @@ -70,7 +70,6 @@ public class WorkflowControllerTest { @Before public void setUp() { - mockMvc = MockMvcBuilders.standaloneSetup(workflowController).build(); mockMvc = MockMvcBuilders.standaloneSetup(workflowController) .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()) .setControllerAdvice(new CustomizedResponseEntityExceptionHandler()).build(); @@ -110,16 +109,37 @@ public class WorkflowControllerTest { public void shouldReturn5WorkflowWhen5WorkflowsExists() throws Exception { int numOfWorkflows = 5; List workflowMocks = createWorkflows(numOfWorkflows); - doReturn(workflowMocks).when(workflowManagerMock).list(any()); + doReturn(workflowMocks).when(workflowManagerMock).list(any(), any()); mockMvc.perform( get(RestPath.getWorkflowsPath()).header(USER_ID_HEADER_PARAM, USER_ID).contentType(APPLICATION_JSON)) .andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("$.results", hasSize(numOfWorkflows))); } + @Test + public void listWithValidVersionStateFilter() throws Exception { + int numOfWorkflows = 3; + List workflows = createWorkflows(numOfWorkflows); + doReturn(workflows).when(workflowManagerMock) + .list(eq(Collections.singleton(WorkflowVersionState.CERTIFIED)), any()); + mockMvc.perform( + get(RestPath.getWorkflowsWithVersionStateFilterPath("CERTIFIED")).header(USER_ID_HEADER_PARAM, USER_ID) + .contentType(APPLICATION_JSON)) + .andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("$.total", is(numOfWorkflows))) + .andExpect(jsonPath("$.results", hasSize(numOfWorkflows))); + } + + @Test + public void listWithInvalidVersionStateFilter() throws Exception { + mockMvc.perform( + get(RestPath.getWorkflowsWithVersionStateFilterPath("hasdhf")).header(USER_ID_HEADER_PARAM, USER_ID) + .contentType(APPLICATION_JSON)) + .andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("$.total", is(0))); + } + @Test public void shouldReturnSortedSizeOffsetAppliedWorkflows() throws Exception { List workflowMocks = createSize2AndOffset1For5WorkflowList(); - doReturn(workflowMocks).when(workflowManagerMock).list(any()); + doReturn(workflowMocks).when(workflowManagerMock).list(any(), any()); mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "1")) .header(RestConstants.USER_ID_HEADER_PARAM, USER_ID).contentType(APPLICATION_JSON)) .andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("$.results", hasSize(2))); @@ -128,7 +148,7 @@ public class WorkflowControllerTest { @Test public void shouldReturnResultsWithDefaultWhenSizeIsNegative() throws Exception { List workflowMocks = createSize2AndOffset1For5WorkflowList(); - doReturn(workflowMocks).when(workflowManagerMock).list(any()); + doReturn(workflowMocks).when(workflowManagerMock).list(any(), any()); MockHttpServletResponse response = mockMvc.perform( get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "-2", "1")) .header(RestConstants.USER_ID_HEADER_PARAM, USER_ID).contentType(APPLICATION_JSON)) @@ -198,7 +218,7 @@ public class WorkflowControllerTest { @Test public void shouldReturnAscSortedSizeOffsetAppliedWorkflowsWhenSortIsNotSpecified() throws Exception { List workflowMocks = createSize2AndOffset1For5WorkflowList(); - doReturn(workflowMocks).when(workflowManagerMock).list(any()); + doReturn(workflowMocks).when(workflowManagerMock).list(any(), any()); mockMvc.perform( get(RestPath.getWorkflowsPathNoSort("2", "1")).header(RestConstants.USER_ID_HEADER_PARAM, USER_ID) .contentType(APPLICATION_JSON)).andDo(print()) @@ -208,7 +228,7 @@ public class WorkflowControllerTest { @Test public void shouldReturnDefaultSizeOffsetAppliedWorkflowsWhenSizeIsNotSpecified() throws Exception { List workflowMocks = createSize2AndOffset1For5WorkflowList(); - doReturn(workflowMocks).when(workflowManagerMock).list(any()); + doReturn(workflowMocks).when(workflowManagerMock).list(any(), any()); mockMvc.perform( get(RestPath.getWorkflowsPathNoSortAndSize("1")).header(RestConstants.USER_ID_HEADER_PARAM, USER_ID) .contentType(APPLICATION_JSON)).andDo(print()) @@ -218,7 +238,7 @@ public class WorkflowControllerTest { @Test public void shouldReturnDefaultOffsetAppliedWorkflowsWhenOffsetIsNotSpecified() throws Exception { List workflowMocks = createSize1WorkflowList(); - doReturn(workflowMocks).when(workflowManagerMock).list(any()); + doReturn(workflowMocks).when(workflowManagerMock).list(any(), any()); mockMvc.perform( get(RestPath.getWorkflowsPathNoSortAndOffset("1")).header(RestConstants.USER_ID_HEADER_PARAM, USER_ID) .contentType(APPLICATION_JSON)).andDo(print()) @@ -234,7 +254,7 @@ public class WorkflowControllerTest { post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER_PARAM, USER_ID).contentType(APPLICATION_JSON) .content(GSON.toJson(reqWorkflow))).andDo(print()) .andExpect(status().isCreated()); - verify(workflowManagerMock, times(1)).create(reqWorkflow); + verify(workflowManagerMock).create(reqWorkflow); } private List createWorkflows(int numOfWorkflows) { diff --git a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowVersionControllerTest.java b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowVersionControllerTest.java index 75b132ad..ee9a56c8 100644 --- a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowVersionControllerTest.java +++ b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowVersionControllerTest.java @@ -25,7 +25,6 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.onap.sdc.workflow.RestPath; -import org.onap.sdc.workflow.api.types.VersionRequestDto; import org.onap.sdc.workflow.persistence.types.WorkflowVersion; import org.onap.sdc.workflow.services.WorkflowVersionManager; import org.openecomp.sdc.versioning.dao.types.Version; @@ -62,28 +61,28 @@ public class WorkflowVersionControllerTest { @Test public void shouldReturnWorkflowVersionListWhenCallingVersionGetREST() throws Exception { - doReturn(versionList).when(workflowVersionManagerMock).list(ITEM1_ID); + doReturn(versionList).when(workflowVersionManagerMock).list(ITEM1_ID, null); mockMvc.perform(get(RestPath.getWorkflowVersions(ITEM1_ID)).header(RestConstants.USER_ID_HEADER_PARAM, USER_ID) .contentType(APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(jsonPath("$.results", hasSize(2))) .andExpect(jsonPath("$.results[0].id", equalTo(VERSION1_ID))) .andExpect(jsonPath("$.results[1].id", equalTo(VERSION2_ID))); - verify(workflowVersionManagerMock, times(1)).list(ITEM1_ID); + verify(workflowVersionManagerMock, times(1)).list(ITEM1_ID, null); } @Test public void shouldCreateWorkflowVersionWhenCallingVersionsPostREST() throws Exception { - VersionRequestDto version = new VersionRequestDto(); + WorkflowVersion version = new WorkflowVersion(); version.setDescription("VersionDescription"); mockMvc.perform(post(RestPath.getWorkflowVersions(ITEM1_ID)).header(RestConstants.USER_ID_HEADER_PARAM, USER_ID) .contentType(APPLICATION_JSON) .content(GSON.toJson(version))) .andExpect(status().isCreated()); - verify(workflowVersionManagerMock, times(1)).create(ITEM1_ID, version); + verify(workflowVersionManagerMock, times(1)).create(ITEM1_ID, null, version); } diff --git a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryTest.java b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryTest.java index 63d2e560..07a42658 100644 --- a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryTest.java +++ b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryTest.java @@ -6,7 +6,6 @@ import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo; @@ -62,8 +61,8 @@ public class ParameterRepositoryTest { element.setId(new Id(PARAMETER1_ID)); Info info = new Info(); info.setName("testInput"); - info.addProperty(ParameterPropertyName.TYPE.name(),ParameterType.FLOAT.name()); - info.addProperty(ParameterPropertyName.mandatory.name(),true); + info.addProperty(ParameterPropertyName.TYPE.name(), ParameterType.FLOAT.name()); + info.addProperty(ParameterPropertyName.mandatory.name(), true); element.setInfo(info); doReturn(Optional.of(element)).when(zusammenAdaptorMock) .getElementInfo(any(SessionContext.class), any(ElementContext.class), @@ -92,8 +91,8 @@ public class ParameterRepositoryTest { } @Test - public void shouldCreateParameterStructure(){ - parameterRepository.createStructure(ITEM1_ID,VERSION1_ID); + public void shouldCreateParameterStructure() { + parameterRepository.createStructure(ITEM1_ID, VERSION1_ID); verify(zusammenAdaptorMock) .saveElement(any(SessionContext.class), any(ElementContext.class), any(ZusammenElement.class), eq("Create WorkflowVersion INPUTS Element")); @@ -118,23 +117,24 @@ public class ParameterRepositoryTest { parameter1.setId(new Id(PARAMETER1_ID)); Info info1 = new Info(); info1.setName("input1"); - info1.addProperty(ParameterPropertyName.TYPE.name(),"INTEGER"); - info1.addProperty(ParameterPropertyName.mandatory.name(),true); + info1.addProperty(ParameterPropertyName.TYPE.name(), "INTEGER"); + info1.addProperty(ParameterPropertyName.mandatory.name(), true); parameter1.setInfo(info1); ElementInfo parameter2 = new ElementInfo(); parameter2.setId(new Id(PARAMETER2_ID)); Info info2 = new Info(); info2.setName("input2"); - info2.addProperty(ParameterPropertyName.TYPE.name(),"STRING"); - info2.addProperty(ParameterPropertyName.mandatory.name(),false); + info2.addProperty(ParameterPropertyName.TYPE.name(), "STRING"); + info2.addProperty(ParameterPropertyName.mandatory.name(), false); parameter2.setInfo(info2); Collection parameters = Collections.asSet(parameter1, parameter2); doReturn(parameters).when(zusammenAdaptorMock) - .listElementsByName(any(SessionContext.class), any(ElementContext.class),isNull(Id.class),eq(ParameterRole.INPUT.name())); + .listElementsByName(any(SessionContext.class), any(ElementContext.class), isNull(), + eq(WorkflowElementType.INPUTS.name())); Collection results = parameterRepository.list(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT); - verify(zusammenAdaptorMock).listElementsByName(any(SessionContext.class), any(ElementContext.class), isNull(Id.class), - eq(WorkflowElementType.INPUT.name())); + verify(zusammenAdaptorMock).listElementsByName(any(SessionContext.class), any(ElementContext.class), isNull(), + eq(WorkflowElementType.INPUTS.name())); assertTrue(results.stream().anyMatch(parameterEntity -> parameterEntity.getId().equals(PARAMETER1_ID))); assertTrue(results.stream().anyMatch(parameterEntity -> parameterEntity.getId().equals(PARAMETER2_ID))); } @@ -154,8 +154,8 @@ public class ParameterRepositoryTest { Optional elementOptional = Optional.of(parameterParentElement); doReturn(elementOptional).when(zusammenAdaptorMock) - .getElementInfoByName(any(SessionContext.class), any(ElementContext.class), - isNull(Id.class), eq(WorkflowElementType.INPUTS.name())); + .getElementInfoByName(any(SessionContext.class), any(ElementContext.class), isNull(), + eq(WorkflowElementType.INPUTS.name())); parameterRepository.deleteAll(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT); verify(zusammenAdaptorMock) diff --git a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java index 500011b4..fc91dc71 100644 --- a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java +++ b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java @@ -1,5 +1,7 @@ package org.onap.sdc.workflow.services.impl; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; @@ -7,21 +9,28 @@ import static org.mockito.Mockito.verify; import static org.onap.sdc.workflow.TestUtil.createItem; import static org.onap.sdc.workflow.TestUtil.createWorkflow; import static org.onap.sdc.workflow.api.RestConstants.SORT_FIELD_NAME; +import static org.onap.sdc.workflow.services.impl.WorkflowManagerImpl.WORKFLOW_ITEM_FILTER; +import static org.openecomp.sdc.versioning.dao.types.VersionStatus.Certified; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.List; - +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; 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.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; import org.onap.sdc.workflow.services.impl.mappers.WorkflowMapper; import org.openecomp.sdc.versioning.ItemManager; import org.openecomp.sdc.versioning.types.Item; @@ -33,43 +42,67 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) public class WorkflowManagerImplTest { - private static final String ITEM1_ID = "workflowId1"; + private static final String ITEM1_ID = "1"; private static final String WORKFLOW_TYPE = "WORKFLOW"; private static final String WORKFLOW_NAME_UNIQUE_TYPE = "WORKFLOW_NAME"; - private List itemList; - private List workflowList; - - @Mock - private WorkflowMapper workflowMapperMock; + private static final List ITEMS; + private static final List MAPPED_WORKFLOWS; + + static { + List items = new ArrayList<>(); + List mappedWorkflows = new ArrayList<>(); + for (int i = 1; i < 6; i++) { + items.add(createItem(i, true, true)); + mappedWorkflows.add(createWorkflow(i, true)); + } + ITEMS = Collections.unmodifiableList(items); + MAPPED_WORKFLOWS = Collections.unmodifiableList(mappedWorkflows); + } @Mock private ItemManager itemManagerMock; - @Mock private UniqueValueService uniqueValueServiceMock; - + @Mock + private WorkflowMapper workflowMapperMock; + @Mock + private VersionStateMapper versionStateMapperMock; @InjectMocks private WorkflowManagerImpl workflowManager; - - @Before - public void setUp() { - itemList = Arrays.asList(createItem(1, true, true), createItem(2, true, true), createItem(3, true, true), - createItem(4, true, true), createItem(5, true, true)); - workflowList = Arrays.asList(createWorkflow(1, true), createWorkflow(2, true), createWorkflow(3, true), - createWorkflow(4, true), createWorkflow(5, true)); - } - - @Test public void shouldReturnWorkflowVersionList() { - PageRequest pageRequest = createPageRequest(2, 1, Sort.Direction.DESC, SORT_FIELD_NAME); - doReturn(itemList).when(itemManagerMock).list(WorkflowManagerImpl.ITEM_PREDICATE); - for (int i=0; i workflows = + workflowManager.list(null, createPageRequest(20, 0, Sort.Direction.ASC, SORT_FIELD_NAME)); + + Map workflowById = + workflows.stream().collect(Collectors.toMap(Workflow::getId, Function.identity())); + assertEquals(ITEMS.size(), workflows.size()); + for (int i = 1; i < ITEMS.size() + 1; i++) { + assertTrue(workflowById.containsKey(String.valueOf(i))); } - workflowManager.list(pageRequest); - verify(itemManagerMock).list(WorkflowManagerImpl.ITEM_PREDICATE); + } + + @Test + public void listWithVersionStateFilter() { + doReturn(Certified).when(versionStateMapperMock) + .workflowVersionStateToVersionStatus(WorkflowVersionState.CERTIFIED); + doReturn(Arrays.asList(ITEMS.get(0), ITEMS.get(2))).when(itemManagerMock).list(any()); + doReturn(MAPPED_WORKFLOWS.get(0)).when(workflowMapperMock).itemToWorkflow(ITEMS.get(0)); + doReturn(MAPPED_WORKFLOWS.get(2)).when(workflowMapperMock).itemToWorkflow(ITEMS.get(2)); + + Collection workflows = + workflowManager.list(Collections.singleton(WorkflowVersionState.CERTIFIED), createPageRequest(20, 0, Sort.Direction.ASC, SORT_FIELD_NAME)); + + Map workflowById = + workflows.stream().collect(Collectors.toMap(Workflow::getId, Function.identity())); + assertEquals(2, workflows.size()); + assertTrue(workflowById.containsKey("1")); + assertTrue(workflowById.containsKey("3")); } @Test(expected = EntityNotFoundException.class) @@ -89,8 +122,6 @@ public class WorkflowManagerImplTest { workflowManager.get(workflow); verify(itemManagerMock).get(ITEM1_ID); verify(workflowMapperMock).itemToWorkflow(retrievedItem); - - } @Test @@ -132,79 +163,78 @@ public class WorkflowManagerImplTest { @Test public void shouldListAllWorkflowsWhenLimitAndOffsetAreValid() { PageRequest pageRequest = createPageRequest(5, 0, Sort.Direction.ASC, SORT_FIELD_NAME); - doReturn(itemList).when(itemManagerMock).list(WorkflowManagerImpl.ITEM_PREDICATE); - for (int i=0; i workflows = workflowManager.list(pageRequest); + Collection workflows = workflowManager.list(null, pageRequest); Assert.assertEquals(2, workflows.size()); Iterator workflowIterator = workflows.iterator(); - Assert.assertEquals("workflowName3", workflowIterator.next().getName()); - Assert.assertEquals("workflowName2", workflowIterator.next().getName()); + Assert.assertEquals("Workflow_3", workflowIterator.next().getName()); + Assert.assertEquals("Workflow_2", workflowIterator.next().getName()); } - private PageRequest createPageRequest(int limit, int offset, - Sort.Direction sortOrder, String sortField) { + private PageRequest createPageRequest(int limit, int offset, Sort.Direction sortOrder, String sortField) { return PageRequest.of(offset, limit, sortOrder, sortField); } diff --git a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java index 4c511de0..7dee5245 100644 --- a/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java +++ b/workflow/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java @@ -1,9 +1,10 @@ package org.onap.sdc.workflow.services.impl; import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; @@ -27,7 +28,6 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; -import org.onap.sdc.workflow.api.types.VersionRequestDto; import org.onap.sdc.workflow.persistence.ArtifactRepository; import org.onap.sdc.workflow.persistence.ParameterRepository; import org.onap.sdc.workflow.persistence.types.ArtifactEntity; @@ -89,7 +89,7 @@ public class WorkflowVersionManagerImplTest { List versionList = Arrays.asList(new Version(VERSION1_ID), new Version(VERSION2_ID)); doReturn(versionList).when(versioningManagerMock).list(ITEM1_ID); doReturn(new WorkflowVersion()).when(versionMapperMock).versionToWorkflowVersion(any(Version.class)); - workflowVersionManager.list(ITEM1_ID); + workflowVersionManager.list(ITEM1_ID, null); verify(versioningManagerMock).list(ITEM1_ID); verify(versionMapperMock, times(2)).versionToWorkflowVersion(any(Version.class)); } @@ -132,27 +132,26 @@ public class WorkflowVersionManagerImplTest { Version version = new Version(VERSION1_ID); version.setDescription("version desc"); doReturn(version).when(versioningManagerMock).create(ITEM1_ID,version, VersionCreationMethod.major); - VersionRequestDto versionRequest = new VersionRequestDto(); + WorkflowVersion versionRequest = new WorkflowVersion(); versionRequest.setDescription("version desc"); versionRequest.setInputs(new ArrayList<>()); versionRequest.setOutputs(new ArrayList<>()); WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); doReturn(workflowVersion).when(workflowVersionManager).get(ITEM1_ID,VERSION1_ID); - workflowVersionManager.create(ITEM1_ID,versionRequest); + workflowVersionManager.create(ITEM1_ID, null, versionRequest); verify(versioningManagerMock).create(ITEM1_ID,version, VersionCreationMethod.major); } @Test(expected = VersionCreationException.class) public void shouldTrowExceptionWhenDraftVersionExists() { - VersionRequestDto versionRequestDto = new VersionRequestDto(); - versionRequestDto.setBaseVersionId(VERSION2_ID); + WorkflowVersion versionRequestDto = new WorkflowVersion(); Version baseVersion = new Version(VERSION2_ID); baseVersion.setStatus(VersionStatus.Draft); List versions = Collections.singletonList(baseVersion); doReturn(versions).when(versioningManagerMock).list(ITEM1_ID); - workflowVersionManager.create(ITEM1_ID, versionRequestDto); + workflowVersionManager.create(ITEM1_ID, VERSION2_ID, versionRequestDto); } @Test(expected = EntityNotFoundException.class) @@ -194,6 +193,8 @@ public class WorkflowVersionManagerImplTest { version.setStatus(VersionStatus.Certified); doReturn(version).when(versioningManagerMock).get(eq(ITEM1_ID), eqVersion(VERSION1_ID)); doReturn(CERTIFIED).when(versionStateMapperMock).versionStatusToWorkflowVersionState(version.getStatus()); + doThrow(new RuntimeException()).when(versioningManagerMock) + .submit(eq(ITEM1_ID), eqVersion(VERSION1_ID), anyString()); workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, CERTIFIED); } @@ -204,15 +205,10 @@ public class WorkflowVersionManagerImplTest { retrievedVersion.setStatus(VersionStatus.Draft); doReturn(retrievedVersion).when(versioningManagerMock).get(eq(ITEM1_ID), eqVersion(VERSION1_ID)); doReturn(DRAFT).when(versionStateMapperMock).versionStatusToWorkflowVersionState(VersionStatus.Draft); - doReturn(VersionStatus.Certified).when(versionStateMapperMock).workflowVersionStateToVersionStatus(CERTIFIED); - ArgumentCaptor versionArgCaptor = ArgumentCaptor.forClass(Version.class); workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, CERTIFIED); - verify(versioningManagerMock).updateVersion(eq(ITEM1_ID), versionArgCaptor.capture()); - assertEquals(VersionStatus.Certified, versionArgCaptor.getValue().getStatus()); - verify(versioningManagerMock) - .publish(eq(ITEM1_ID), eqVersion(VERSION1_ID), eq("Update version state from DRAFT to CERTIFIED")); + verify(versioningManagerMock).submit(eq(ITEM1_ID), eqVersion(VERSION1_ID), anyString()); } @Test -- cgit 1.2.3-korg