diff options
21 files changed, 678 insertions, 87 deletions
diff --git a/workflow-bdd/features/ArchiveWorkflow.feature b/workflow-bdd/features/ArchiveWorkflow.feature new file mode 100644 index 00000000..e63227df --- /dev/null +++ b/workflow-bdd/features/ArchiveWorkflow.feature @@ -0,0 +1,68 @@ +# Copyright © 2018 European Support Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Feature: Archive Workflow + + Scenario: Archive workflow + Given I want to create a Workflow + When I want to create input data + And I want to update the input property "status" with value "ARCHIVED" + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + Then I want to get path "/workflows/{item.id}" + And I want to check property "status" for value "ARCHIVED" + When I want to get path "/workflows?limit=2000&statusFilter=ARCHIVED" + Then I want to check in the list "items" property "id" with value "{item.id}" exists + When I want to get path "/workflows?limit=2000&" + Then I want to check in the list "items" property "id" with value "{item.id}" does not exist + + + Scenario: Archive and then Restore workflow + Given I want to create a Workflow + When I want to create input data + And I want to update the input property "status" with value "ARCHIVED" + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + Then I want to get path "/workflows/{item.id}" + And I want to check property "status" for value "ARCHIVED" + When I want to get path "/workflows?limit=2000&statusFilter=ARCHIVED" + Then I want to check in the list "items" property "id" with value "{item.id}" exists + When I want to get path "/workflows?limit=2000&" + Then I want to check in the list "items" property "id" with value "{item.id}" does not exist + And I want to update the input property "status" with value "ACTIVE" + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + Then I want to get path "/workflows/{item.id}" + And I want to check property "status" for value "ACTIVE" + When I want to get path "/workflows?limit=2000&statusFilter=ARCHIVED" + Then I want to check in the list "items" property "id" with value "{item.id}" does not exist + When I want to get path "/workflows?limit=2000&" + Then I want to check in the list "items" property "id" with value "{item.id}" exists + + Scenario: Archive already archived workflow + Given I want to create a Workflow + When I want to create input data + And I want to update the input property "status" with value "ARCHIVED" + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + When I want to create input data + And I want to update the input property "status" with value "ARCHIVED" + Then I want the following to fail with response status code 422 + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + + Scenario: Restore already active workflow + Given I want to create a Workflow + When I want to create input data + And I want to update the input property "status" with value "ACTIVE" + Then I want the following to fail with response status code 422 + And I want to create for path "/workflows/{item.id}/archiving" with the input data from the context + + + diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ExceptionsHandler.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ExceptionsHandler.java index 642c3438..083206c8 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ExceptionsHandler.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ExceptionsHandler.java @@ -32,7 +32,10 @@ import org.onap.sdc.workflow.services.exceptions.UniqueValueViolationException; import org.onap.sdc.workflow.services.exceptions.VersionCreationException; import org.onap.sdc.workflow.services.exceptions.VersionModificationException; import org.onap.sdc.workflow.services.exceptions.VersionStateModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationMissingArtifactException; import org.onap.sdc.workflow.services.exceptions.VersionStatusModificationException; +import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException; +import org.onap.sdc.workflow.services.exceptions.WorkflowStatusModificationException; import org.openecomp.sdc.logging.api.Logger; import org.openecomp.sdc.logging.api.LoggerFactory; import org.springframework.context.support.DefaultMessageSourceResolvable; @@ -90,8 +93,11 @@ public class ExceptionsHandler extends ResponseEntityExceptionHandler { @ExceptionHandler( {InvalidArtifactException.class, VersionCreationException.class, VersionModificationException.class, - VersionStateModificationException.class, VersionStatusModificationException.class, - UniqueValueViolationException.class}) + VersionStateModificationException.class, + VersionStateModificationMissingArtifactException.class, + VersionStatusModificationException.class, + UniqueValueViolationException.class, WorkflowStatusModificationException.class, + WorkflowModificationException.class}) public final ResponseEntity<ErrorResponse> handleUnprocessableEntityException(Exception exception) { LOG.debug(LOG_MSG, UNPROCESSABLE_ENTITY, exception); return new ResponseEntity<>(new ErrorResponse(exception.getMessage()), UNPROCESSABLE_ENTITY); diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java index 9010fea4..8eb22390 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java @@ -27,9 +27,11 @@ import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; +import javax.validation.Valid; import org.onap.sdc.workflow.api.types.Paging; import org.onap.sdc.workflow.api.types.Sorting; import org.onap.sdc.workflow.api.types.VersionStatesFormatter; +import org.onap.sdc.workflow.api.types.WorkflowStatusDto; import org.onap.sdc.workflow.services.WorkflowManager; import org.onap.sdc.workflow.services.WorkflowVersionManager; import org.onap.sdc.workflow.services.annotations.UserId; @@ -38,6 +40,7 @@ import org.onap.sdc.workflow.services.types.PagingRequest; import org.onap.sdc.workflow.services.types.RequestSpec; import org.onap.sdc.workflow.services.types.SortingRequest; import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.WorkflowStatus; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; @@ -81,11 +84,13 @@ public class WorkflowController { value = "Sorting criteria in the format: property:(asc|desc). Default sort order is ascending.", allowableValues = "name:asc,name:desc"), @ApiImplicitParam(name = "searchNameFilter", dataType = "string", paramType = "query", - value = "Filter by workflow name")}) - public Page<Workflow> list(@ApiIgnore String searchNameFilter, + value = "Filter by workflow name"), + @ApiImplicitParam(name = "archiving", dataType = "string", paramType = "query", + allowableValues = "ACTIVE,ARCHIVED", value = "Filter by workflow status")}) + public Page<Workflow> list(@ApiIgnore String archiving, @ApiIgnore String searchNameFilter, @ApiIgnore VersionStatesFormatter versionStateFilter, @ApiIgnore Paging paging, @ApiIgnore Sorting sorting, @UserId String user) { - return workflowManager.list(searchNameFilter, versionStateFilter.getVersionStates(), initRequestSpec(paging, sorting)); + return workflowManager.list(archiving, searchNameFilter, versionStateFilter.getVersionStates(), initRequestSpec(paging, sorting)); } @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @@ -117,6 +122,14 @@ public class WorkflowController { return workflow; } + @PostMapping(path = "/{workflowId}/archiving", consumes = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Update workflow status") + public ResponseEntity updateStatus(@RequestBody @Valid WorkflowStatusDto request, @PathVariable("workflowId") String workflowId, + @UserId String user) { + workflowManager.updateStatus(workflowId,WorkflowStatus.valueOf(request.getStatus())); + return new ResponseEntity(HttpStatus.OK); + } + private RequestSpec initRequestSpec(Paging paging, Sorting sorting) { return new RequestSpec(new PagingRequest(paging.getOffset() == null ? DEFAULT_OFFSET : paging.getOffset(), paging.getLimit() == null ? DEFAULT_LIMIT : paging.getLimit()), diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowStatusDto.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowStatusDto.java new file mode 100644 index 00000000..6e5ab1cf --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowStatusDto.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import lombok.Data; +import org.onap.sdc.workflow.api.validation.ValidStatus; + +@Data +public class WorkflowStatusDto { + @ValidStatus(message = "Invalid status. Allowable values are: ARCHIVED,ACTIVE.") + private String status; +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidStatus.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidStatus.java new file mode 100644 index 00000000..96325919 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidStatus.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.validation.Constraint; +import javax.validation.Payload; + +@Target({ElementType.TYPE, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = {WorkflowStatusValidator.class}) +public @interface ValidStatus { + + String message(); + + Class<?>[] groups() default {}; + + Class<? extends Payload>[] payload() default {}; +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/WorkflowStatusValidator.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/WorkflowStatusValidator.java new file mode 100644 index 00000000..b99b424a --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/WorkflowStatusValidator.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import org.onap.sdc.workflow.services.types.WorkflowStatus; + +public class WorkflowStatusValidator implements ConstraintValidator<ValidStatus, String> { + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (value == null) { + return false; + } else { + try { + Enum.valueOf(WorkflowStatus.class, value); + return true; + } catch (IllegalArgumentException var3) { + return false; + } + } + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java index 5190da14..0f8f27e2 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java @@ -20,15 +20,18 @@ import java.util.Set; import org.onap.sdc.workflow.services.types.Page; import org.onap.sdc.workflow.services.types.RequestSpec; import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.WorkflowStatus; import org.onap.sdc.workflow.services.types.WorkflowVersionState; public interface WorkflowManager { - Page<Workflow> list(String searchNameFilter, Set<WorkflowVersionState> versionStatesFilter, RequestSpec requestSpec); + Page<Workflow> list(String statusFilter, String searchNameFilter, Set<WorkflowVersionState> versionStatesFilter, RequestSpec requestSpec); Workflow get(Workflow workflow); Workflow create(Workflow workflow); void update(Workflow workflow); + + void updateStatus(String workflowId, WorkflowStatus status); } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationException.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationException.java index 379d8e2e..43360bd6 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationException.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationException.java @@ -21,12 +21,12 @@ import org.onap.sdc.workflow.services.types.WorkflowVersionState; public class VersionStateModificationException extends RuntimeException { public VersionStateModificationException(String workflowId, String versionId, WorkflowVersionState sourceState, - WorkflowVersionState targetState) { + WorkflowVersionState targetState) { this(workflowId, versionId, sourceState, targetState, null); } public VersionStateModificationException(String workflowId, String versionId, WorkflowVersionState sourceState, - WorkflowVersionState targetState, Exception submitException) { + WorkflowVersionState targetState, Exception submitException) { super(String.format("Workflow %s, version %s: state can not be changed from %s to %s", workflowId, versionId, sourceState.name(), targetState.name()), submitException); } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationMissingArtifactException.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationMissingArtifactException.java new file mode 100644 index 00000000..48aaa5c7 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationMissingArtifactException.java @@ -0,0 +1,16 @@ +package org.onap.sdc.workflow.services.exceptions; + +import org.onap.sdc.workflow.services.types.WorkflowVersionState; + +public class VersionStateModificationMissingArtifactException extends RuntimeException { + + public static final String WORKFLOW_MODIFICATION_STATE_MISSING_ARTIFACT_TEMPLATE = + "Workflow %s, version %s: state can not be changed from %s to %s. Missing artifact"; + + public VersionStateModificationMissingArtifactException(String workflowId, String versionId, + WorkflowVersionState sourceState, + WorkflowVersionState targetState) { + super(String.format(WORKFLOW_MODIFICATION_STATE_MISSING_ARTIFACT_TEMPLATE, workflowId, versionId, + sourceState.name(), targetState.name())); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowModificationException.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowModificationException.java new file mode 100644 index 00000000..7aa5ac0b --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowModificationException.java @@ -0,0 +1,25 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +public class WorkflowModificationException extends RuntimeException { + + public WorkflowModificationException(String workflowId) { + super(String.format( + "Error while trying to modify workflow %s: Workflow is ARCHIVED and can not be edited", workflowId)); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowStatusModificationException.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowStatusModificationException.java new file mode 100644 index 00000000..380b1405 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowStatusModificationException.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +import org.openecomp.sdc.common.errors.CoreException; + +public class WorkflowStatusModificationException extends RuntimeException { + + public WorkflowStatusModificationException(CoreException ex) { + super(ex.getMessage()); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java index 9dd33132..27257b49 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java @@ -30,6 +30,8 @@ import java.util.stream.Collectors; import org.onap.sdc.workflow.services.UniqueValueService; import org.onap.sdc.workflow.services.WorkflowManager; import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException; +import org.onap.sdc.workflow.services.exceptions.WorkflowStatusModificationException; import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; import org.onap.sdc.workflow.services.impl.mappers.WorkflowMapper; import org.onap.sdc.workflow.services.types.Page; @@ -38,7 +40,9 @@ import org.onap.sdc.workflow.services.types.RequestSpec; import org.onap.sdc.workflow.services.types.Sort; import org.onap.sdc.workflow.services.types.SortingRequest; import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.WorkflowStatus; import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.logging.api.Logger; import org.openecomp.sdc.logging.api.LoggerFactory; import org.openecomp.sdc.versioning.ItemManager; @@ -54,7 +58,7 @@ public class WorkflowManagerImpl implements WorkflowManager { private static final String WORKFLOW_NOT_FOUND_ERROR_MSG = "Workflow with id '%s' does not exist"; private static final String WORKFLOW_NAME_UNIQUE_TYPE = "WORKFLOW_NAME"; - private static final Predicate<Item> WORKFLOW_ITEM_FILTER = item -> WORKFLOW.name().equals(item.getType()); + private static final Predicate<Item> WORKFLOW_ITEM_TYPE_FILTER = item -> WORKFLOW.name().equals(item.getType()); private static final String WORKSPACES_SORT_PROPERTY = "name"; private static final RequestSpec WORKSPACES_DEFAULT_REQUEST_SPEC = new RequestSpec(new PagingRequest(DEFAULT_OFFSET, DEFAULT_LIMIT), @@ -78,17 +82,12 @@ public class WorkflowManagerImpl implements WorkflowManager { } @Override - public Page<Workflow> list(String searchNameFilter, Set<WorkflowVersionState> versionStatesFilter, - RequestSpec requestSpec) { + public Page<Workflow> list(String statusFilter, String searchNameFilter, + Set<WorkflowVersionState> versionStatesFilter, RequestSpec requestSpec) { requestSpec = getRequestSpec(requestSpec); - Set<VersionStatus> versionStatusesFilter = - versionStatesFilter == null ? null : - versionStatesFilter.stream().map(versionStateMapper::workflowVersionStateToVersionStatus) - .collect(Collectors.toSet()); - - Predicate<Item> filter = addSearchNameFilter(WORKFLOW_ITEM_FILTER, searchNameFilter); - Collection<Item> workflowItems = itemManager.list(addVersionStatusFilter(filter, versionStatusesFilter)); + Collection<Item> workflowItems = + itemManager.list(createFilter(statusFilter, searchNameFilter, versionStatesFilter)); List<Workflow> workflowsSlice = workflowItems.stream().map(workflowMapper::itemToWorkflow) .sorted(getWorkflowComparator(requestSpec.getSorting())) @@ -128,6 +127,10 @@ public class WorkflowManagerImpl implements WorkflowManager { throw new EntityNotFoundException(String.format(WORKFLOW_NOT_FOUND_ERROR_MSG, workflow.getId())); } + if (ItemStatus.ARCHIVED.equals(retrievedItem.getStatus())) { + throw new WorkflowModificationException(workflow.getId()); + } + uniqueValueService.updateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, retrievedItem.getName(), workflow.getName()); Item item = workflowMapper.workflowToItem(workflow); @@ -137,7 +140,25 @@ public class WorkflowManagerImpl implements WorkflowManager { itemManager.update(item); } - private static RequestSpec getRequestSpec(RequestSpec requestSpec) { + @Override + public void updateStatus(String workflowId, WorkflowStatus status) { + Item item = itemManager.get(workflowId); + if (item == null) { + LOGGER.error(String.format("Workflow with id %s was not found",workflowId)); + throw new EntityNotFoundException(String.format(WORKFLOW_NOT_FOUND_ERROR_MSG, workflowId)); + } + try { + if (WorkflowStatus.ARCHIVED.equals(status)) { + itemManager.archive(item); + } else if (WorkflowStatus.ACTIVE.equals(status)) { + itemManager.restore(item); + } + } catch (CoreException ex) { + throw new WorkflowStatusModificationException(ex); + } + } + + private static RequestSpec getRequestSpec(RequestSpec requestSpec) { if (requestSpec == null) { return WORKSPACES_DEFAULT_REQUEST_SPEC; } @@ -172,15 +193,42 @@ public class WorkflowManagerImpl implements WorkflowManager { return byNameAscending ? byName : byName.reversed(); } + private Predicate<Item> createFilter(String itemStatusFilter, String searchNameFilter, + Set<WorkflowVersionState> versionStatesFilter) { + + Set<VersionStatus> versionStatusesFilter = + versionStatesFilter == null ? null : + versionStatesFilter.stream().map(versionStateMapper::workflowVersionStateToVersionStatus) + .collect(Collectors.toSet()); + + Predicate<Item> filter = addSearchNameFilter(WORKFLOW_ITEM_TYPE_FILTER, searchNameFilter); + + filter = addVersionStatusFilter(filter, versionStatusesFilter); + + return addItemStatusFilter(filter, itemStatusFilter); + + } + private static Predicate<Item> addSearchNameFilter(Predicate<Item> filter, String searchNameFilter) { - return filter - .and(item -> searchNameFilter == null || - item.getName().toLowerCase().contains(searchNameFilter.toLowerCase())); + return filter.and(item -> searchNameFilter == null + || item.getName().toLowerCase().contains(searchNameFilter.toLowerCase())); } private static Predicate<Item> addVersionStatusFilter(Predicate<Item> filter, Set<VersionStatus> versionStatuses) { - return filter - .and(item -> versionStatuses == null || item.getVersionStatusCounters().keySet().stream() - .anyMatch(versionStatuses::contains)); + return filter.and(item -> versionStatuses == null + || item.getVersionStatusCounters().keySet().stream().anyMatch(versionStatuses::contains)); + } + + private static Predicate<Item> addItemStatusFilter(Predicate<Item> filter, String itemStatusFilter) { + if (itemStatusFilter != null) { + try { + ItemStatus.valueOf(itemStatusFilter.toUpperCase()); + } catch (IllegalArgumentException e) { + LOGGER.debug(String.format("Illegal Workflow status filter: %s. Ignoring filter", itemStatusFilter)); + return filter; + } + return filter.and(item -> item.getStatus().equals(ItemStatus.valueOf(itemStatusFilter.toUpperCase()))); + } + return filter; } } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java index f2f8c276..5eba8d4a 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java @@ -29,6 +29,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; + import org.onap.sdc.workflow.persistence.ArtifactRepository; import org.onap.sdc.workflow.persistence.ParameterRepository; import org.onap.sdc.workflow.persistence.types.ArtifactEntity; @@ -40,15 +41,20 @@ import org.onap.sdc.workflow.services.exceptions.InvalidArtifactException; import org.onap.sdc.workflow.services.exceptions.VersionCreationException; import org.onap.sdc.workflow.services.exceptions.VersionModificationException; import org.onap.sdc.workflow.services.exceptions.VersionStateModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationMissingArtifactException; +import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException; import org.onap.sdc.workflow.services.impl.mappers.VersionMapper; import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; import org.onap.sdc.workflow.services.types.WorkflowVersion; import org.onap.sdc.workflow.services.types.WorkflowVersionState; 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.VersioningManager; import org.openecomp.sdc.versioning.dao.types.Version; import org.openecomp.sdc.versioning.dao.types.VersionStatus; +import org.openecomp.sdc.versioning.types.Item; +import org.openecomp.sdc.versioning.types.ItemStatus; import org.openecomp.sdc.versioning.types.VersionCreationMethod; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -60,6 +66,7 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { private static final String VERSION_NOT_EXIST_MSG = "version with id '%s' does not exist for workflow with id '%s'"; private final VersioningManager versioningManager; + private final ItemManager itemManager; private final ArtifactRepository artifactRepository; private final ParameterRepository parameterRepository; private final VersionMapper versionMapper; @@ -68,8 +75,9 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { @Autowired public WorkflowVersionManagerImpl(VersioningManager versioningManager, ArtifactRepository artifactRepository, - VersionMapper versionMapper, VersionStateMapper versionStateMapper, + VersionMapper versionMapper, VersionStateMapper versionStateMapper, ItemManager itemManager, ParameterRepository parameterRepository) { + this.itemManager = itemManager; this.versioningManager = versioningManager; this.artifactRepository = artifactRepository; this.parameterRepository = parameterRepository; @@ -103,6 +111,7 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { @Override public WorkflowVersion create(String workflowId, String baseVersionId, WorkflowVersion workflowVersion) { + validateWorkflowStatus(workflowId); List<Version> versions = versioningManager.list(workflowId); if (baseVersionId != null) { @@ -131,6 +140,7 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { @Override public void update(String workflowId, WorkflowVersion workflowVersion) { + validateWorkflowStatus(workflowId); Version retrievedVersion = getVersion(workflowId, workflowVersion.getId()); if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) { throw new VersionModificationException(workflowId, workflowVersion.getId()); @@ -157,23 +167,28 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { } @Override - public void updateState(String workflowId, String versionId, WorkflowVersionState state) { - WorkflowVersionState retrievedState = getState(workflowId, versionId); - if (state == CERTIFIED) { + public void updateState(String workflowId, String versionId, WorkflowVersionState newState) { + WorkflowVersionState currentState = getState(workflowId, versionId); + if (newState == CERTIFIED) { + if(!artifactRepository.isExist(workflowId,versionId)){ + throw new VersionStateModificationMissingArtifactException(workflowId, versionId, currentState, + newState); + } try { versioningManager.submit(workflowId, new Version(versionId), - String.format("Update version state to %s", state.name())); + String.format("Update version state to %s", newState.name())); } catch (Exception submitException) { - throw new VersionStateModificationException(workflowId, versionId, retrievedState, - state, submitException); + throw new VersionStateModificationException(workflowId, versionId, currentState, newState, + submitException); } } else { - throw new VersionStateModificationException(workflowId, versionId, retrievedState, state); + throw new VersionStateModificationException(workflowId, versionId, currentState, newState); } } @Override public void uploadArtifact(String workflowId, String versionId, MultipartFile artifact) { + validateWorkflowStatus(workflowId); Version retrievedVersion = getVersion(workflowId, versionId); if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) { throw new VersionModificationException(workflowId, versionId); @@ -210,6 +225,7 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { @Override public void deleteArtifact(String workflowId, String versionId) { + validateWorkflowStatus(workflowId); WorkflowVersion retrievedVersion = get(workflowId, versionId); if (CERTIFIED.equals(retrievedVersion.getState())) { LOGGER.error(String.format( @@ -286,4 +302,11 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { return versions.stream().filter(version -> versionId.equals(version.getId())).findFirst(); } + protected void validateWorkflowStatus(String workflowId) { + Item workflowItem = itemManager.get(workflowId); + if (ItemStatus.ARCHIVED.equals(workflowItem.getStatus())) { + throw new WorkflowModificationException(workflowId); + } + } + }
\ No newline at end of file diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Workflow.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Workflow.java index 3d8e4c77..0c0179e2 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Workflow.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Workflow.java @@ -39,4 +39,5 @@ public class Workflow { private String description; private Set<WorkflowVersionState> versionStates; private Collection<WorkflowVersion> versions; + private WorkflowStatus status; } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowStatus.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowStatus.java new file mode 100644 index 00000000..6df7ff30 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowStatus.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +public enum WorkflowStatus { + ARCHIVED, + ACTIVE +} diff --git a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java index 6c825f9d..9821d510 100644 --- a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java +++ b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java @@ -12,6 +12,7 @@ public class RestPath { private static final String WORKFLOWS_URL = "/wf/workflows"; private static final String WORKFLOW_URL_FORMATTER = WORKFLOWS_URL + "/%s"; + private static final String ARCHIVE_URL_FORMATTER = WORKFLOWS_URL + "/%s/archiving"; private static final String VERSIONS_URL_FORMATTER = WORKFLOWS_URL + "/%s/versions"; private static final String VERSION_URL_FORMATTER = WORKFLOWS_URL + "/%s/versions/%s"; private static final String SORT_QUERY_STRING_FORMATTER = SORT + "=%s"; @@ -25,15 +26,15 @@ public class RestPath { private static final String WORKFLOW_URL_FORMATTER_QUERY_PARAMS_NO_SORT_AND_OFFSET = WORKFLOWS_URL + "?" + LIMIT_QUERY_STRING_FORMATTER; - public static String getWorkflowsPathAllQueryParams(String sort, String limit, String offset){ + public static String getWorkflowsPathAllQueryParams(String sort, String limit, String offset) { return String.format(WORKFLOW_URL_FORMATTER_QUERY_PARAMS_ALL, sort, limit, offset); } - public static String getWorkflowsPathNoSortAndLimit(String offset){ + public static String getWorkflowsPathNoSortAndLimit(String offset) { return String.format(WORKFLOW_URL_FORMATTER_QUERY_PARAMS_NO_SORT_AND_LIMIT, offset); } - public static String getWorkflowsPathNoSortAndOffset(String limit){ + public static String getWorkflowsPathNoSortAndOffset(String limit) { return String.format(WORKFLOW_URL_FORMATTER_QUERY_PARAMS_NO_SORT_AND_OFFSET, limit); } @@ -45,6 +46,10 @@ public class RestPath { return String.format(WORKFLOW_URL_FORMATTER, workflowId); } + public static String getArchiveWorkflowPath(String workflowId) { + return String.format(ARCHIVE_URL_FORMATTER, workflowId); + } + public static String getWorkflowVersions(String workflowId) { return String.format(VERSIONS_URL_FORMATTER, workflowId); } diff --git a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ExceptionsHandlerTest.java b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ExceptionsHandlerTest.java index e4008bb0..fc35c4a6 100644 --- a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ExceptionsHandlerTest.java +++ b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ExceptionsHandlerTest.java @@ -14,6 +14,8 @@ import org.onap.sdc.workflow.api.types.ErrorResponse; import org.onap.sdc.workflow.api.types.UnexpectedErrorResponse; import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; import org.onap.sdc.workflow.services.exceptions.VersionModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationMissingArtifactException; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -42,6 +44,17 @@ public class ExceptionsHandlerTest { } @Test + public void handleUnprocessableEntityVersionStateModificationMissingArtifactException() { + VersionStateModificationMissingArtifactException exception = + new VersionStateModificationMissingArtifactException("WF_ID", "Version_id", + WorkflowVersionState.DRAFT, WorkflowVersionState.CERTIFIED); + ResponseEntity<ErrorResponse> response = exceptionsHandler.handleUnprocessableEntityException(exception); + + assertEquals(UNPROCESSABLE_ENTITY, response.getStatusCode()); + assertEquals(exception.getMessage(), response.getBody().getMessage()); + } + + @Test public void handleUnexpectedException() { Exception exception = new Exception("message"); ResponseEntity<UnexpectedErrorResponse> response = exceptionsHandler.handleUnexpectedException(exception); diff --git a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java index 9c481282..0c48fd64 100644 --- a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java +++ b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java @@ -40,6 +40,7 @@ import org.onap.sdc.workflow.services.types.PagingRequest; import org.onap.sdc.workflow.services.types.RequestSpec; import org.onap.sdc.workflow.services.types.Sort; import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.WorkflowStatus; import org.onap.sdc.workflow.services.utilities.JsonUtil; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.test.web.servlet.MockMvc; @@ -95,6 +96,22 @@ public class WorkflowControllerTest { } @Test + public void shouldReturnOkWhenArchivingWorkflow() throws Exception { + Workflow workflowMock = createWorkflow(1, true); + mockMvc.perform(post(RestPath.getArchiveWorkflowPath(workflowMock.getId())).header(USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON).content("{\"status\": \"ARCHIVED\"}")).andExpect(status().isOk()); + verify(workflowManagerMock).updateStatus(workflowMock.getId(),WorkflowStatus.ARCHIVED); + } + + @Test + public void shouldReturnOkWhenRestoringWorkflow() throws Exception { + Workflow workflowMock = createWorkflow(1, true); + mockMvc.perform(post(RestPath.getArchiveWorkflowPath(workflowMock.getId())).header(USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON).content("{\"status\": \"ACTIVE\"}")).andExpect(status().isOk()); + verify(workflowManagerMock).updateStatus(workflowMock.getId(),WorkflowStatus.ACTIVE); + } + + @Test public void listWhenExist() throws Exception { mockManagerList3(); ResultActions result = mockMvc.perform( @@ -105,7 +122,7 @@ public class WorkflowControllerTest { result.andExpect(jsonPath(String.format("$.items[%s].id", i), is(String.valueOf(i + 1)))); } - verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture()); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, DEFAULT_LIMIT, Collections.emptyList()); } @@ -115,7 +132,7 @@ public class WorkflowControllerTest { mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "1")) .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); - verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture()); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); assertRequestSpec(requestSpecArg.getValue(), 1, 2, Collections.singletonList(new Sort("name", true))); } @@ -125,7 +142,7 @@ public class WorkflowControllerTest { mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "-2", "1")) .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); - verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture()); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); assertRequestSpec(requestSpecArg.getValue(), 1, DEFAULT_LIMIT, Collections.singletonList(new Sort("name", true))); } @@ -136,7 +153,7 @@ public class WorkflowControllerTest { mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "-1")) .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); - verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture()); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 2, Collections.singletonList(new Sort("name", true))); } @@ -147,7 +164,7 @@ public class WorkflowControllerTest { mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "abc", "0")) .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); - verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture()); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); assertRequestSpec(requestSpecArg.getValue(), 0, DEFAULT_LIMIT, Collections.singletonList(new Sort("name", true))); } @@ -158,7 +175,7 @@ public class WorkflowControllerTest { mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "abc")) .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) .andExpect(jsonPath("$.items", hasSize(3))); - verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture()); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 2, Collections.singletonList(new Sort("name", true))); } @@ -169,7 +186,7 @@ public class WorkflowControllerTest { mockMvc.perform(get(RestPath.getWorkflowsPathNoSortAndLimit("1")).header(USER_ID_HEADER, USER_ID) .contentType(APPLICATION_JSON)) .andExpect(jsonPath("$.items", hasSize(3))); - verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture()); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); assertRequestSpec(requestSpecArg.getValue(), 1, DEFAULT_LIMIT, Collections.emptyList()); } @@ -179,7 +196,7 @@ public class WorkflowControllerTest { mockMvc.perform(get(RestPath.getWorkflowsPathNoSortAndOffset("1")).header(USER_ID_HEADER, USER_ID) .contentType(APPLICATION_JSON)) .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); - verify(workflowManagerMock).list(any(), any(), requestSpecArg.capture()); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 1, Collections.emptyList()); } @@ -258,7 +275,7 @@ public class WorkflowControllerTest { doReturn(new Page<>(Arrays.asList(createWorkflow(1, true), createWorkflow(2, true), createWorkflow(3, true)), new PagingRequest(DEFAULT_OFFSET, DEFAULT_LIMIT), 3)).when(workflowManagerMock) - .list(any(), any(), any()); + .list(any(), any(), any(), any()); } private static void assertRequestSpec(RequestSpec actual, int expectedOffset, int expectedLimit, diff --git a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/WorkflowStatusVelidatorTest.java b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/WorkflowStatusVelidatorTest.java new file mode 100644 index 00000000..289c9353 --- /dev/null +++ b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/WorkflowStatusVelidatorTest.java @@ -0,0 +1,91 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import javax.validation.ConstraintValidatorContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class WorkflowStatusVelidatorTest { + + class AnnotationWrapper { + + @ValidName(message = "test message") + public String status; + } + + @Mock + private ConstraintValidatorContext context; + @Mock + private ConstraintValidatorContext.ConstraintViolationBuilder constraintViolationBuilder; + @Mock + private ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext nodeBuilderCustomizableContext; + + private WorkflowStatusValidator validator; + + @Before + public void setup() throws NoSuchFieldException { + MockitoAnnotations.initMocks(this); + when(context.buildConstraintViolationWithTemplate(anyString())).thenReturn(constraintViolationBuilder); + when(constraintViolationBuilder.addPropertyNode(anyString())).thenReturn(nodeBuilderCustomizableContext); + validator = initializeValidator(WorkflowStatusVelidatorTest.AnnotationWrapper.class); + } + + @Test + public void shouldFailIfValueIsNull() { + assertFalse(validator.isValid(null, context)); + } + + @Test + public void shouldFailIfValueInvalid() { + assertFalse(validator.isValid("blahblah", context)); + } + + @Test + public void shouldPassIfValueIsActive() { + assertTrue(validator.isValid("ACTIVE", context)); + } + + @Test + public void shouldPassIfValueIsArchived() { + assertTrue(validator.isValid("ARCHIVED", context)); + } + + + + + private WorkflowStatusValidator initializeValidator(Class<?> classWithAnnotation) + throws NoSuchFieldException { + ValidStatus constraint = classWithAnnotation.getField("status").getAnnotation(ValidStatus.class); + WorkflowStatusValidator validator = new WorkflowStatusValidator(); + validator.initialize(constraint); + return validator; + } + + +} diff --git a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java index e2df4ec0..702da4c8 100644 --- a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java +++ b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java @@ -4,6 +4,7 @@ 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.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.onap.sdc.workflow.TestUtil.createItem; @@ -27,6 +28,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.onap.sdc.workflow.services.UniqueValueService; import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.WorkflowStatusModificationException; import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; import org.onap.sdc.workflow.services.impl.mappers.WorkflowMapper; import org.onap.sdc.workflow.services.types.Page; @@ -36,7 +38,11 @@ import org.onap.sdc.workflow.services.types.RequestSpec; import org.onap.sdc.workflow.services.types.Sort; import org.onap.sdc.workflow.services.types.SortingRequest; import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.WorkflowStatus; import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.openecomp.sdc.common.errors.CoreException; +import org.openecomp.sdc.common.errors.ErrorCategory; +import org.openecomp.sdc.common.errors.ErrorCode; import org.openecomp.sdc.versioning.ItemManager; import org.openecomp.sdc.versioning.types.Item; import org.openecomp.sdc.versioning.types.ItemStatus; @@ -80,7 +86,7 @@ public class WorkflowManagerImplTest { doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); RequestSpec requestSpec = createRequestSpec(0, 20, true); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); Map<String, Workflow> workflowById = workflows.getItems().stream().collect(Collectors.toMap(Workflow::getId, Function.identity())); @@ -102,7 +108,7 @@ public class WorkflowManagerImplTest { RequestSpec requestSpec = createRequestSpec(0, 20, true); Page<Workflow> workflows = - workflowManager.list(null,Collections.singleton(WorkflowVersionState.CERTIFIED), requestSpec); + workflowManager.list(null,null,Collections.singleton(WorkflowVersionState.CERTIFIED), requestSpec); Map<String, Workflow> workflowById = workflows.getItems().stream().collect(Collectors.toMap(Workflow::getId, Function.identity())); @@ -114,6 +120,42 @@ public class WorkflowManagerImplTest { } @Test(expected = EntityNotFoundException.class) + public void shouldThrowExceptionWhenWorkflowDontExistTryingToUpdateStatus() { + doReturn(null).when(itemManagerMock).get(ITEM1_ID); + workflowManager.updateStatus(ITEM1_ID,WorkflowStatus.ARCHIVED); + } + + @Test(expected = WorkflowStatusModificationException.class) + public void shouldThrowExceptionWhenFailingToUpdateStatus() { + Item mockItem = new Item(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + doThrow(new CoreException(new ErrorCode.ErrorCodeBuilder().build())).when(itemManagerMock).archive(mockItem); + workflowManager.updateStatus(ITEM1_ID,WorkflowStatus.ARCHIVED); + } + + @Test + public void shouldArchiveWorkflow() { + Item mockItem = new Item(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ACTIVE); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + workflowManager.updateStatus(ITEM1_ID,WorkflowStatus.ARCHIVED); + verify(itemManagerMock).archive(mockItem); + } + + @Test + public void shouldRestoreWorkflow() { + Item mockItem = new Item(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + workflowManager.updateStatus(ITEM1_ID,WorkflowStatus.ACTIVE); + verify(itemManagerMock).restore(mockItem); + } + + @Test(expected = EntityNotFoundException.class) public void shouldThrowExceptionWhenWorkflowDontExist() { Workflow nonExistingWorkflow = new Workflow(); nonExistingWorkflow.setId(ITEM1_ID); @@ -172,7 +214,7 @@ public class WorkflowManagerImplTest { public void listWhenRequestSpecIsNull() { doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, null); + Page<Workflow> workflows = workflowManager.list(null,null,null, null); assertEquals(ITEMS.size(), workflows.getItems().size()); assertPaging(workflows.getPaging(), DEFAULT_OFFSET, DEFAULT_LIMIT, ITEMS.size()); @@ -187,7 +229,7 @@ public class WorkflowManagerImplTest { public void listWhenPagingIsNull() { doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, new RequestSpec(null, + Page<Workflow> workflows = workflowManager.list(null,null,null, new RequestSpec(null, SortingRequest.builder().sort(new Sort(SORT_FIELD_NAME, true)).build())); assertEquals(ITEMS.size(), workflows.getItems().size()); @@ -200,7 +242,7 @@ public class WorkflowManagerImplTest { mockItemToWorkflowMaps(); RequestSpec requestSpec = new RequestSpec(new PagingRequest(-2, -8), SortingRequest.builder().sort(new Sort(SORT_FIELD_NAME, true)).build()); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(ITEMS.size(), workflows.getItems().size()); assertPaging(workflows.getPaging(), DEFAULT_OFFSET, DEFAULT_LIMIT, ITEMS.size()); @@ -211,7 +253,7 @@ public class WorkflowManagerImplTest { doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); RequestSpec requestSpec = new RequestSpec(new PagingRequest(2, 8), null); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(3, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), @@ -228,7 +270,7 @@ public class WorkflowManagerImplTest { doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); RequestSpec requestSpec = new RequestSpec(new PagingRequest(2, 8), SortingRequest.builder().build()); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(3, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), @@ -245,7 +287,7 @@ public class WorkflowManagerImplTest { RequestSpec requestSpec = createRequestSpec(0, 5, true); doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(5, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), @@ -257,7 +299,7 @@ public class WorkflowManagerImplTest { RequestSpec requestSpec = createRequestSpec(0, 3, true); doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(3, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), ITEMS.size()); @@ -269,7 +311,7 @@ public class WorkflowManagerImplTest { RequestSpec requestSpec = createRequestSpec(3, 1, true); doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(1, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), ITEMS.size()); @@ -280,7 +322,7 @@ public class WorkflowManagerImplTest { RequestSpec requestSpec = createRequestSpec(0, 10, true); doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(5, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), ITEMS.size()); @@ -291,7 +333,7 @@ public class WorkflowManagerImplTest { RequestSpec requestSpec = createRequestSpec(6, 3, true); doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(0, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), ITEMS.size()); @@ -302,7 +344,7 @@ public class WorkflowManagerImplTest { doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); RequestSpec requestSpec = createRequestSpec(0, 5555, true); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(ITEMS.size(), workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), MAX_LIMIT, ITEMS.size()); @@ -313,7 +355,7 @@ public class WorkflowManagerImplTest { RequestSpec requestSpec = createRequestSpec(10, 10, true); doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(0, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), ITEMS.size()); @@ -324,7 +366,7 @@ public class WorkflowManagerImplTest { RequestSpec requestSpec = createRequestSpec(2, 1, false); doReturn(ITEMS).when(itemManagerMock).list(any()); mockItemToWorkflowMaps(); - Page<Workflow> workflows = workflowManager.list(null,null, requestSpec); + Page<Workflow> workflows = workflowManager.list(null,null,null, requestSpec); assertEquals(1, workflows.getItems().size()); assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), ITEMS.size()); diff --git a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java index 8b09e15d..640d3e8b 100644 --- a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java +++ b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java @@ -1,11 +1,11 @@ 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.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; @@ -15,15 +15,16 @@ import static org.onap.sdc.workflow.services.types.WorkflowVersionState.DRAFT; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.Set; + import org.apache.commons.io.IOUtils; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; @@ -39,16 +40,20 @@ import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; import org.onap.sdc.workflow.services.exceptions.VersionCreationException; import org.onap.sdc.workflow.services.exceptions.VersionModificationException; import org.onap.sdc.workflow.services.exceptions.VersionStateModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationMissingArtifactException; +import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException; import org.onap.sdc.workflow.services.impl.mappers.VersionMapper; import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; import org.onap.sdc.workflow.services.types.WorkflowVersion; import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.openecomp.sdc.versioning.ItemManager; import org.openecomp.sdc.versioning.VersioningManager; import org.openecomp.sdc.versioning.dao.types.Version; import org.openecomp.sdc.versioning.dao.types.VersionState; import org.openecomp.sdc.versioning.dao.types.VersionStatus; +import org.openecomp.sdc.versioning.types.Item; +import org.openecomp.sdc.versioning.types.ItemStatus; import org.openecomp.sdc.versioning.types.VersionCreationMethod; -import org.springframework.boot.test.autoconfigure.web.client.RestClientTest; import org.springframework.mock.web.MockMultipartFile; @RunWith(MockitoJUnitRunner.class) @@ -59,6 +64,8 @@ public class WorkflowVersionManagerImplTest { private static final String VERSION2_ID = "version_id_2"; @Mock + private ItemManager itemManagerMock; + @Mock private VersioningManager versioningManagerMock; @Mock private ParameterRepository parameterRepositoryMock; @@ -68,6 +75,8 @@ public class WorkflowVersionManagerImplTest { private VersionMapper versionMapperMock; @Mock private VersionStateMapper versionStateMapperMock; + @Rule + public ExpectedException exceptionRule = ExpectedException.none(); @Spy @InjectMocks private WorkflowVersionManagerImpl workflowVersionManager; @@ -79,6 +88,43 @@ public class WorkflowVersionManagerImplTest { workflowVersionManager.get(ITEM1_ID, VERSION1_ID); } + @Test(expected = WorkflowModificationException.class) + public void shouldThrowExceptionWhenCreatingVersionForArchivedWorkflow() { + Item mockItem = new Item(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + workflowVersionManager.create(ITEM1_ID, null, new WorkflowVersion(VERSION1_ID)); + } + + @Test(expected = WorkflowModificationException.class) + public void shouldThrowExceptionWhenUpdatingVersionForArchivedWorkflow() { + Item mockItem = new Item(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + workflowVersionManager.update(ITEM1_ID, new WorkflowVersion(VERSION1_ID)); + } + + @Test(expected = WorkflowModificationException.class) + public void shouldThrowExceptionWhenUploadingArtifactForArchivedWorkflow() { + Item mockItem = new Item(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + MockMultipartFile mockFile = new MockMultipartFile("data", "filename.txt", "text/plain", "some xml".getBytes()); + workflowVersionManager.uploadArtifact(ITEM1_ID, VERSION1_ID, mockFile); + } + + @Test(expected = WorkflowModificationException.class) + public void shouldThrowExceptionWhenDeletingArtifactForArchivedWorkflow() { + Item mockItem = new Item(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); + } + @Test public void shouldReturnWorkflowVersionWhenExist() { Version version = new Version(VERSION1_ID); @@ -95,7 +141,7 @@ public class WorkflowVersionManagerImplTest { public void shouldReturnWorkflowVersionList() { Version version1 = new Version(VERSION1_ID); Version version2 = new Version(VERSION2_ID); - List<Version> versionList = Arrays.asList(version1,version2); + List<Version> versionList = Arrays.asList(version1, version2); doReturn(versionList).when(versioningManagerMock).list(ITEM1_ID); WorkflowVersion workflowVersion1 = new WorkflowVersion(); workflowVersion1.setId(VERSION1_ID); @@ -104,8 +150,10 @@ public class WorkflowVersionManagerImplTest { workflowVersion2.setId(VERSION2_ID); workflowVersion2.setName(VERSION2_ID); doReturn(workflowVersion2).when(versionMapperMock).versionToWorkflowVersion(version2); - doReturn(Collections.emptyList()).when(parameterRepositoryMock).list(eq(ITEM1_ID),anyString(),eq(ParameterRole.INPUT)); - doReturn(Collections.emptyList()).when(parameterRepositoryMock).list(eq(ITEM1_ID),anyString(),eq(ParameterRole.OUTPUT)); + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.INPUT)); + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.OUTPUT)); workflowVersionManager.list(ITEM1_ID, null); verify(versioningManagerMock).list(ITEM1_ID); verify(versionMapperMock, times(2)).versionToWorkflowVersion(any(Version.class)); @@ -127,14 +175,15 @@ public class WorkflowVersionManagerImplTest { workflowVersion2.setName(VERSION2_ID); doReturn(workflowVersion1).when(versionMapperMock).versionToWorkflowVersion(version1); doReturn(Collections.emptyList()).when(parameterRepositoryMock) - .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.INPUT)); + .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.INPUT)); doReturn(Collections.emptyList()).when(parameterRepositoryMock) - .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.OUTPUT)); + .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.OUTPUT)); doReturn(VersionStatus.Certified).when(versionStateMapperMock) - .workflowVersionStateToVersionStatus( - WorkflowVersionState.CERTIFIED); + .workflowVersionStateToVersionStatus( + WorkflowVersionState.CERTIFIED); - assertEquals(1, workflowVersionManager.list(ITEM1_ID, Collections.singleton(WorkflowVersionState.CERTIFIED)).size()); + assertEquals(1, + workflowVersionManager.list(ITEM1_ID, Collections.singleton(WorkflowVersionState.CERTIFIED)).size()); verify(versioningManagerMock).list(ITEM1_ID); verify(versionMapperMock, times(1)).versionToWorkflowVersion(any(Version.class)); @@ -142,6 +191,7 @@ public class WorkflowVersionManagerImplTest { @Test public void shouldUpdateWorkflowVersion() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); String updatedDescription = "WorkflowVersion description updated"; Version retrievedVersion = new Version(VERSION1_ID); retrievedVersion.setName("1.0"); @@ -160,11 +210,12 @@ public class WorkflowVersionManagerImplTest { inputVersion.setInputs(Collections.singleton(toBeCreated)); ParameterEntity toBeUpdated = new ParameterEntity("Output1"); inputVersion.setOutputs(Collections.singleton(toBeUpdated)); - doReturn(Collections.emptyList()).when(parameterRepositoryMock).list(ITEM1_ID,VERSION1_ID,ParameterRole.INPUT); + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT); ParameterEntity toBeDeleted = new ParameterEntity("Output2"); toBeDeleted.setId("parameter_id_1"); Collection<ParameterEntity> currentOutputs = Arrays.asList(toBeDeleted, toBeUpdated); - doReturn(currentOutputs).when(parameterRepositoryMock).list(ITEM1_ID,VERSION1_ID,ParameterRole.OUTPUT); + doReturn(currentOutputs).when(parameterRepositoryMock).list(ITEM1_ID, VERSION1_ID, ParameterRole.OUTPUT); Version mappedInputVersion = new Version(VERSION1_ID); mappedInputVersion.setName("1.0"); @@ -181,15 +232,16 @@ public class WorkflowVersionManagerImplTest { assertEquals(VersionStatus.Draft, captorVersion.getStatus()); verify(versioningManagerMock).publish(ITEM1_ID, mappedInputVersion, "Update version"); - verify(parameterRepositoryMock).delete(ITEM1_ID,VERSION1_ID,"parameter_id_1"); - verify(parameterRepositoryMock).create(ITEM1_ID,VERSION1_ID,ParameterRole.INPUT,toBeCreated); - verify(parameterRepositoryMock).update(ITEM1_ID,VERSION1_ID,ParameterRole.OUTPUT,toBeUpdated); + verify(parameterRepositoryMock).delete(ITEM1_ID, VERSION1_ID, "parameter_id_1"); + verify(parameterRepositoryMock).create(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT, toBeCreated); + verify(parameterRepositoryMock).update(ITEM1_ID, VERSION1_ID, ParameterRole.OUTPUT, toBeUpdated); } @Test public void shouldCreateWorkflowVersion() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); Version version = new Version(VERSION1_ID); version.setDescription("version desc"); doReturn(version).when(versioningManagerMock).create(ITEM1_ID, version, VersionCreationMethod.major); @@ -205,6 +257,7 @@ public class WorkflowVersionManagerImplTest { @Test(expected = VersionCreationException.class) public void shouldTrowExceptionWhenDraftVersionExists() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); WorkflowVersion versionRequestDto = new WorkflowVersion(); Version baseVersion = new Version(VERSION2_ID); @@ -217,6 +270,7 @@ public class WorkflowVersionManagerImplTest { @Test(expected = VersionCreationException.class) public void shouldTrowExceptionWhenInputsSupplied() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); WorkflowVersion versionRequestDto = new WorkflowVersion(); versionRequestDto.setInputs(Collections.singleton(new ParameterEntity())); Version baseVersion = new Version(VERSION2_ID); @@ -260,32 +314,46 @@ public class WorkflowVersionManagerImplTest { workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, DRAFT); } - @Test(expected = VersionStateModificationException.class) + @Test(expected = VersionStateModificationMissingArtifactException.class) public void updateStateWhenCertified() { Version version = new Version(VERSION1_ID); 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); } @Test - public void updateState() { + public void shouldFailUpdateStateWhenNoArtifact() { Version retrievedVersion = new Version(VERSION1_ID); retrievedVersion.setStatus(VersionStatus.Draft); doReturn(retrievedVersion).when(versioningManagerMock).get(eq(ITEM1_ID), eqVersion(VERSION1_ID)); doReturn(DRAFT).when(versionStateMapperMock).versionStatusToWorkflowVersionState(VersionStatus.Draft); + exceptionRule.expect(VersionStateModificationMissingArtifactException.class); + exceptionRule.expectMessage(String.format( + VersionStateModificationMissingArtifactException.WORKFLOW_MODIFICATION_STATE_MISSING_ARTIFACT_TEMPLATE, + ITEM1_ID, VERSION1_ID, DRAFT, CERTIFIED)); workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, CERTIFIED); verify(versioningManagerMock).submit(eq(ITEM1_ID), eqVersion(VERSION1_ID), anyString()); } @Test + public void shouldSuccessUpdateStateWhenArtifactExist() { + Version retrievedVersion = new Version(VERSION1_ID); + retrievedVersion.setStatus(VersionStatus.Draft); + doReturn(retrievedVersion).when(versioningManagerMock).get(eq(ITEM1_ID), eqVersion(VERSION1_ID)); + doReturn(DRAFT).when(versionStateMapperMock).versionStatusToWorkflowVersionState(VersionStatus.Draft); + doReturn(true).when(artifactRepositoryMock).isExist(ITEM1_ID, VERSION1_ID); + workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, CERTIFIED); + verify(versioningManagerMock).submit(eq(ITEM1_ID), eqVersion(VERSION1_ID), anyString()); + } + + @Test public void shouldUploadArtifact() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); Version version = new Version(VERSION1_ID); version.setStatus(VersionStatus.Draft); VersionState versionState = new VersionState(); @@ -321,23 +389,25 @@ public class WorkflowVersionManagerImplTest { @Test(expected = VersionModificationException.class) public void shouldThrowExceptionInDeleteArtifactWhenVersionIsCertified() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); Version version = new Version(VERSION1_ID); - doReturn(version).when(versioningManagerMock).get(ITEM1_ID,version); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, version); WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); workflowVersion.setState(WorkflowVersionState.CERTIFIED); doReturn(workflowVersion).when(versionMapperMock).versionToWorkflowVersion(version); - workflowVersionManager.deleteArtifact(ITEM1_ID,VERSION1_ID); + workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); } @Test public void shouldDeleteArtifact() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); Version version = new Version(VERSION1_ID); - doReturn(version).when(versioningManagerMock).get(ITEM1_ID,version); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, version); WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); doReturn(workflowVersion).when(versionMapperMock).versionToWorkflowVersion(version); - workflowVersionManager.deleteArtifact(ITEM1_ID,VERSION1_ID); - verify(artifactRepositoryMock).delete(ITEM1_ID,VERSION1_ID); - verify(versioningManagerMock).publish(ITEM1_ID,version,"Delete Artifact"); + workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); + verify(artifactRepositoryMock).delete(ITEM1_ID, VERSION1_ID); + verify(versioningManagerMock).publish(ITEM1_ID, version, "Delete Artifact"); } private static Version eqVersion(String versionId) { |