diff options
23 files changed, 437 insertions, 181 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java index c7f92d2184..2b23c52cd0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactResolverImpl.java @@ -54,20 +54,20 @@ public class ArtifactResolverImpl implements ArtifactsResolver { Map<String, ArtifactDefinition> deploymentArtifacts = Optional.ofNullable(component.getDeploymentArtifacts()).orElse(Collections.emptyMap()); Map<String, ArtifactDefinition> artifacts = Optional.ofNullable(component.getArtifacts()).orElse(Collections.emptyMap()); Map<String, ArtifactDefinition> interfaceArtifacts= Collections.emptyMap(); - if (componentType == ComponentTypeEnum.RESOURCE) { - Map<String, InterfaceDefinition> interfaces = ((Resource) component).getInterfaces(); - if (MapUtils.isNotEmpty(interfaces)) { - interfaceArtifacts = interfaces.values().stream() - .flatMap(inte -> inte.getOperationsMap().values().stream()) - .map(operation -> operation.getImplementationArtifact()) - .collect(Collectors.toMap(artifactDefinition -> artifactDefinition.getUniqueId(), artifactDefinition -> artifactDefinition)); - } + Map<String, InterfaceDefinition> interfaces = component.getInterfaces(); + if (MapUtils.isNotEmpty(interfaces)) { + interfaceArtifacts = interfaces.values().stream() + .flatMap(inte -> inte.getOperationsMap().values().stream()) + .map(operation -> operation.getImplementationArtifact()) + .collect(Collectors.toMap(artifactDefinition -> artifactDefinition.getUniqueId(), + artifactDefinition -> artifactDefinition)); } Map<String, ArtifactDefinition> serviceApiArtifacts = Collections.emptyMap(); if (componentType.equals(ComponentTypeEnum.SERVICE)) { serviceApiArtifacts = Optional.ofNullable(((Service) component).getServiceApiArtifacts()).orElse(Collections.emptyMap()); } + return appendAllArtifacts(deploymentArtifacts, artifacts, interfaceArtifacts, serviceApiArtifacts); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java index fc4a739614..65a87d444b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java @@ -3100,24 +3100,23 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } NodeTypeEnum convertParentType = convertParentType(componentType); // fetch the resource from storage - Either<Resource, StorageOperationStatus> resourceStorageOperationStatusEither = + Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(parentId); - if (resourceStorageOperationStatusEither.isRight()) { - StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value(); + if (componentStorageOperationStatusEither.isRight()) { + StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value(); log.debug("Failed to fetch resource information by resource id, error {}", errorStatus); return Either.right(componentsUtils .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); } - Resource storedResource = resourceStorageOperationStatusEither.left().value(); + Component storedComponent = componentStorageOperationStatusEither.left().value(); String interfaceToscaName = InterfaceUtils.createInterfaceToscaResourceName( - storedResource.getName()); + storedComponent.getName()); //fetch the interface from storage - Optional<InterfaceDefinition> interfaceDefinition = storedResource.getInterfaces().values() - .stream() - .filter(interfaceDef -> interfaceDef.getToscaResourceName() - .equals(interfaceToscaName)) - .findFirst(); + Optional<InterfaceDefinition> interfaceDefinition = + storedComponent.getInterfaces().values().stream() + .filter(interfaceDef -> interfaceDef.getToscaResourceName() + .equals(interfaceToscaName)).findFirst(); if (!interfaceDefinition.isPresent()) { log.debug("Failed to get resource interface for resource Id {}", parentId); ResponseFormat responseFormat = componentsUtils.getResponseFormat( @@ -3154,7 +3153,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { operation.setImplementation(implementationArtifact); gotInterface.setOperationsMap(operationsMap); Either<InterfaceDefinition, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = - interfaceOperation.updateInterface(storedResource.getUniqueId(), gotInterface); + interfaceOperation.updateInterface(storedComponent.getUniqueId(), gotInterface); if (interfaceDefinitionStorageOperationStatusEither.isRight()){ StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value(); ActionStatus actionStatus = @@ -3163,16 +3162,6 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } String uniqueId = implementationArtifact.getUniqueId(); - Either<Long, CassandraOperationStatus> artifactCount = artifactCassandraDao.getCountOfArtifactById(uniqueId); - if(artifactCount.isLeft()){ - CassandraOperationStatus cassandraOperationStatus = artifactCassandraDao.deleteArtifact(uniqueId); - if(cassandraOperationStatus != CassandraOperationStatus.OK){ - log.debug("Failed to persist operation {} artifact, error is {}",operation.getName(),cassandraOperationStatus); - StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(cassandraOperationStatus); - ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus); - return Either.right(componentsUtils.getResponseFormat(convertedFromStorageResponse)); - } - } artifactData.setId(uniqueId); CassandraOperationStatus cassandraOperationStatus = artifactCassandraDao.saveArtifact(artifactData); if(cassandraOperationStatus != CassandraOperationStatus.OK){ @@ -3647,23 +3636,25 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } } } - switch (component.getComponentType()) { - case RESOURCE: - Map<String, InterfaceDefinition> interfaces = ((Resource) component).getInterfaces(); - if (!found && interfaces != null) { - for (Map.Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) { - Map<String, Operation> operations = entry.getValue().getOperationsMap(); - for (Map.Entry<String, Operation> entryOp : operations.entrySet()) { - if (entryOp.getValue().getImplementation() != null && entryOp.getValue() - .getImplementation() - .getUniqueId() - .equals(artifactId)) { - found = true; - break; - } - } + + Map<String, InterfaceDefinition> interfaces = component.getInterfaces(); + if (!found && interfaces != null) { + for (Map.Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) { + Map<String, Operation> operations = entry.getValue().getOperationsMap(); + for (Map.Entry<String, Operation> entryOp : operations.entrySet()) { + if (entryOp.getValue().getImplementation() != null && entryOp.getValue() + .getImplementation() + .getUniqueId() + .equals(artifactId)) { + found = true; + break; } } + } + } + + switch (component.getComponentType()) { + case RESOURCE: break; case SERVICE: Map<String, ArtifactDefinition> apiArtifacts = ((Service) component).getServiceApiArtifacts(); @@ -5106,18 +5097,18 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } private Either<String, ResponseFormat> fetchInterfaceName(String componentId) { - Either<Resource, StorageOperationStatus> resourceStorageOperationStatusEither = + Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId); - if (resourceStorageOperationStatusEither.isRight()) { - StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value(); - log.debug("Failed to fetch resource information by resource id, error {}", errorStatus); + if (componentStorageOperationStatusEither.isRight()) { + StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value(); + log.debug("Failed to fetch component information by component id, error {}", errorStatus); return Either.right(componentsUtils .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); } - Resource storedResource = resourceStorageOperationStatusEither.left().value(); + Component storedComponent = componentStorageOperationStatusEither.left().value(); return Either.left(InterfaceUtils.createInterfaceToscaResourceName( - storedResource.getName())); + storedComponent.getName())); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java index 26e256fb00..fed2cac518 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java @@ -208,7 +208,7 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic { if (getOperationEither.isRight()){ return Either.right(getOperationEither.right().value()); } - operation.setImplementation(getOperationEither.left().value().getImplementation()); + updateExistingOperation(operation, getOperationEither.left().value().getImplementation().getArtifactUUID()); result = interfaceOperation.updateInterfaceOperation(componentId, interfaceDefinition, operation); } @@ -265,6 +265,15 @@ public class InterfaceOperationBusinessLogic extends BaseBusinessLogic { operation.setImplementation(artifactDefinition); } + private void updateExistingOperation(Operation operation, String artifactUUID){ + ArtifactDefinition artifactDefinition = new ArtifactDefinition(); + artifactDefinition.setArtifactUUID(artifactUUID); + artifactDefinition.setUniqueId(artifactUUID); + artifactDefinition.setArtifactType(ArtifactTypeEnum.WORKFLOW.getType()); + artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); + operation.setImplementation(artifactDefinition); + } + private Either<Boolean, ResponseFormat> lockComponentResult(boolean lock, org.openecomp.sdc.be.model.Component component, String action){ if (lock) { Either<Boolean, ResponseFormat> lockResult = lockComponent(component.getUniqueId(), component, action); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java index 8c90501140..7b650e4fad 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java @@ -16,6 +16,17 @@ package org.openecomp.sdc.be.components.validation; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + import fj.data.Either; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -33,17 +44,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - @Component("interfaceOperationValidation") public class InterfaceOperationValidation { @@ -279,8 +279,8 @@ public class InterfaceOperationValidation { .anyMatch(inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY)); } private Boolean isOutputParameterNameEmpty(Operation operationDataDefinition) { - return operationDataDefinition.getInputs().getListToscaDataDefinition().stream() - .anyMatch(inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY)); + return operationDataDefinition.getOutputs().getListToscaDataDefinition().stream() + .anyMatch(outputParam -> outputParam.getName() == null || outputParam.getName().trim().equals(StringUtils.EMPTY)); } private Either<Boolean, ResponseFormat> validateInputPropertyExistInComponent(Operation operation, @@ -305,7 +305,10 @@ public class InterfaceOperationValidation { private boolean validateInputExistsInComponent(OperationInputDefinition input, List<InputDefinition> inputs) { - return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId())); + return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId())) + || ((input.getInputId().contains(".") + && inputs.stream().anyMatch(inp -> inp.getUniqueId().equals( + input.getInputId().substring(0, input.getInputId().lastIndexOf(".")))))) ; } private ResponseFormatManager getResponseFormatManager() { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java index c53e343512..03c5e0fbf1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java @@ -7,9 +7,9 @@ * 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. @@ -21,6 +21,14 @@ package org.openecomp.sdc.be.externalapi.servlet; import com.jcabi.aspects.Loggable; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + import fj.data.Either; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; @@ -65,11 +73,12 @@ import javax.ws.rs.core.Response; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.EnumMap; import java.util.HashMap; import java.util.Map; /** * This Servlet serves external users operations on artifacts. - * + * * @author mshitrit * */ @@ -89,7 +98,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { private static String startLog = "Start handle request of "; @POST - @Path("/resources/{uuid}/interfaces/{operationUUID}/artifacts/{artifactUUID}") + @Path("/{assetType}/{uuid}/interfaces/{operationUUID}/artifacts/{artifactUUID}") @Produces(MediaType.APPLICATION_JSON) @ApiOperation(value = "uploads of artifact to VF operation workflow", httpMethod = "POST", notes = "uploads of artifact to VF operation workflow") @ApiResponses(value = { @@ -116,6 +125,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { @ApiParam(value = "X-ECOMP-InstanceID header", required = true) @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader, @ApiParam(value = "Determines the format of the body of the response", required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept, @ApiParam(value = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, + @ApiParam(value = "Asset type") @PathParam("assetType") String assetType, @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, @ApiParam(value = "The uuid of the operation", required = true)@PathParam("operationUUID") final String operationUUID, @ApiParam(value = "The uuid of the artifact", required = true)@PathParam("artifactUUID") final String artifactUUID, @@ -125,9 +135,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { String requestURI = request.getRequestURI(); String url = request.getMethod() + " " + requestURI; log.debug("{} {}", startLog, url); - ComponentTypeEnum componentType = ComponentTypeEnum.RESOURCE; - String componentTypeValue = componentType.getValue(); - ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(componentTypeValue); + ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(assetType); ArtifactDefinition artifactDefinition = null; if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { @@ -144,7 +152,9 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { if (responseWrapper.isEmpty()) { ServletContext context = request.getSession().getServletContext(); ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); - Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic.updateArtifactOnInterfaceOperationByResourceUUID(data, request, componentType, uuid, artifactUUID, operationUUID, + Either<ArtifactDefinition, ResponseFormat> uploadArtifactEither = artifactsLogic + .updateArtifactOnInterfaceOperationByResourceUUID(data, request, ComponentTypeEnum + .findByParamName(assetType), uuid, artifactUUID, operationUUID, resourceCommonInfo, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE)); if (uploadArtifactEither.isRight()) { log.debug(FAILED_TO_UPDATE_ARTIFACT); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java index c3628df17b..7afad74f64 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -181,9 +182,13 @@ public class InterfacesOperationsToscaUtil { for (OperationInputDefinition input : operation.getInputs().getListToscaDataDefinition()) { ToscaProperty toscaInput = new ToscaProperty(); toscaInput.setDescription(input.getDescription()); - String mappedPropertyName = getLastPartOfName(input.getInputId()); - toscaInput.setType(input.getType()); + String mappedPropertyName = null; + if (Objects.nonNull(input.getInputId())) { + mappedPropertyName = input.getInputId().substring(input.getInputId().indexOf(DOT) + 1); + } toscaInput.setDefaultp(createDefaultValue(mappedPropertyName)); + + toscaInput.setType(input.getType()); toscaInput.setRequired(input.isRequired()); toscaInputs.put(input.getName(), toscaInput); } @@ -195,13 +200,15 @@ public class InterfacesOperationsToscaUtil { Map<String, List<String>> getPropertyMap = new HashMap<>(); List<String> values = new ArrayList<>(); values.add(SELF); - values.add(propertyName); + if (Objects.nonNull(propertyName) && !propertyName.isEmpty()) { + values.addAll(Arrays.asList(propertyName.split("\\."))); + } + getPropertyMap.put(GET_PROPERTY, values); return getPropertyMap; } - private static Map<String, Object> getObjectAsMap(Object obj) { ObjectMapper objectMapper = new ObjectMapper(); if (obj instanceof ToscaInterfaceDefinition) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java index b70ae90f7c..0d772cfcab 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/OperationArtifactUtil.java @@ -33,6 +33,7 @@ import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.tosca.CsarUtils; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; @@ -53,7 +54,7 @@ public class OperationArtifactUtil { */ static String createOperationArtifactPath(Component component, OperationDataDefinition operation, boolean isAssociatedResourceComponent) { - if (!(component instanceof Resource)) { + if (!(component instanceof Resource || component instanceof Service)) { return null; } if (isAssociatedResourceComponent) { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java index e8a698fec1..4227e5d5cc 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java @@ -55,6 +55,7 @@ import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.WebAppContextWrapper; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.Resource; @@ -88,7 +89,7 @@ public class InterfaceOperationBusinessLogicTest { private final String operationId = "uniqueId1"; private Operation operation; - private static final String RESOURCE_NAME = "My-Resource_Name with space"; + private static final String RESOURCE_NAME = "Resource1"; private final ServletContext servletContext = Mockito.mock(ServletContext.class); private final TitanDao mockTitanDao = Mockito.mock(TitanDao.class); @@ -175,13 +176,6 @@ public class InterfaceOperationBusinessLogicTest { //InterfaceOperation when(operationValidator.validateInterfaceOperations(anyCollection(), anyObject(), anyBoolean())).thenReturn(Either.left(true)); - when(interfaceOperation.addInterface(anyString(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockInterfaceDefinitionToReturn(RESOURCE_NAME))); - when(interfaceOperation.updateInterface(anyString(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockInterfaceDefinitionToReturn(RESOURCE_NAME))); - when(interfaceOperation.addInterfaceOperation(anyObject(), anyObject(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); - when(interfaceOperation.updateInterfaceOperation(anyObject(), anyObject(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); - when(interfaceOperation.deleteInterfaceOperation(anyObject(), anyObject(), anyObject())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); - when(interfaceOperation.deleteInterfaceOperation(any(),any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); - when(interfaceOperation.updateInterface(any(),any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockInterfaceDefinitionToReturn(RESOURCE_NAME))); when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK); // BL object @@ -211,6 +205,8 @@ public class InterfaceOperationBusinessLogicTest { validateUserRoles(Role.ADMIN, Role.DESIGNER); when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); operation = InterfaceOperationTestUtils.createMockOperation(); + when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); + Either<Operation, ResponseFormat> interfaceOperation = bl.createInterfaceOperation(resourceId, operation, user, true); Assert.assertTrue(interfaceOperation.isLeft()); Assert.assertNotNull(interfaceOperation.left().value().getWorkflowId()); @@ -218,27 +214,96 @@ public class InterfaceOperationBusinessLogicTest { } @Test + public void createInterfaceOperationWithoutInterfaceTest() { + Resource resource = createResourceObjectCsar(true); + resource.setComponentType(ComponentTypeEnum.RESOURCE); + resource.setInterfaces(new HashMap<>()); + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + operation = InterfaceOperationTestUtils.createMockOperation(); + when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); + when(interfaceOperation.addInterface(anyString(), any())).thenReturn(Either.left(new InterfaceDefinition())); + + Either<Operation, ResponseFormat> interfaceOperation = bl.createInterfaceOperation(resourceId, operation, user, true); + Assert.assertTrue(interfaceOperation.isLeft()); + + } + + @Test + public void shouldFailCreateInterfaceOperationWhenCreateOperationFailedTest() { + Resource resource = createResourceObjectCsar(true); + resource.setInterfaces(new HashMap<>()); + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + operation = InterfaceOperationTestUtils.createMockOperation(); + when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); + when(interfaceOperation.addInterface(anyString(), any())).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + + Either<Operation, ResponseFormat> interfaceOperation = bl.createInterfaceOperation(resourceId, operation, user, true); + Assert.assertTrue(interfaceOperation.isRight()); + + } + + @Test() + public void shouldFailWhenCreateInterfaceOperationFailedTest() { + Resource resource = createResourceForInterfaceOperation(); + resource.setComponentType(ComponentTypeEnum.RESOURCE); + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + operation = InterfaceOperationTestUtils.createMockOperation(); + + when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + Assert.assertTrue(bl.createInterfaceOperation(resourceId, operation, user, true).isRight()); + } + + @Test public void updateInterfaceOperationTest() { validateUserRoles(Role.ADMIN, Role.DESIGNER); operation = InterfaceOperationTestUtils.createMockOperation(); Resource resource = createResourceForInterfaceOperation(); resource.setComponentType(ComponentTypeEnum.RESOURCE); when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + when(interfaceOperation.updateInterfaceOperation(any(), any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); + Either<Operation, ResponseFormat> interfaceOperation = bl.updateInterfaceOperation(resourceId, operation, user, true); Assert.assertTrue(interfaceOperation.isLeft()); } + @Test() + public void shouldFailWhenFailedToUpdateInterfaceOperationTest() { + validateUserRoles(Role.ADMIN, Role.DESIGNER); + operation = InterfaceOperationTestUtils.createMockOperation(); + Resource resource = createResourceForInterfaceOperation(); + resource.setComponentType(ComponentTypeEnum.RESOURCE); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + when(interfaceOperation.addInterfaceOperation(any(), any(), any())).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + Either<Operation, ResponseFormat> interfaceOperation = bl.updateInterfaceOperation(resourceId, operation, user, true); + Assert.assertTrue(interfaceOperation.isRight()); + } + @Test public void deleteInterfaceOperationTest() { Resource resource = createResourceForInterfaceOperation(); resource.setComponentType(ComponentTypeEnum.RESOURCE); validateUserRoles(Role.ADMIN, Role.DESIGNER); when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + when(interfaceOperation.deleteInterfaceOperation(any(),any(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockOperationToReturn())); when(artifactCassandraDao.deleteArtifact(any(String.class))).thenReturn(CassandraOperationStatus.OK); Either<Operation, ResponseFormat> deleteResourceResponseFormatEither = bl.deleteInterfaceOperation(resourceId, operationId, user, true); Assert.assertTrue(deleteResourceResponseFormatEither.isLeft()); } + @Test() + public void shouldFailWhenDeleteInterfaceOperationFailedTest() { + Resource resource = createResourceForInterfaceOperation(); + resource.setComponentType(ComponentTypeEnum.RESOURCE); + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + when(interfaceOperation.deleteInterfaceOperation(any(),any(), any())).thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + when(artifactCassandraDao.deleteArtifact(any(String.class))).thenReturn(CassandraOperationStatus.OK); + Assert.assertTrue(bl.deleteInterfaceOperation(resourceId, operationId, user, true).isRight()); + + } @Test public void getInterfaceOperationTest() { Resource resource = createResourceForInterfaceOperation(); @@ -249,6 +314,37 @@ public class InterfaceOperationBusinessLogicTest { Assert.assertTrue(getResourceResponseFormatEither.isLeft()); } + @Test + public void updateToscaResourceNameWhenComponentNameChanged() { + Component newComponent = new Resource(); + newComponent.setName("newComponent"); + Component oldComponent = createResourceForInterfaceOperation(); + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(interfaceOperation.updateInterface(anyString(), any())).thenReturn(Either.left(InterfaceOperationTestUtils.mockInterfaceDefinitionToReturn(RESOURCE_NAME))); + Assert.assertTrue(bl.validateComponentNameAndUpdateInterfaces(oldComponent, newComponent).isLeft()); + } + + @Test + public void shouldFailWhenComponentNameChangedButUpdateOperationFailed() { + Component newComponent = new Resource(); + newComponent.setName("newComponent"); + Component oldComponent = createResourceForInterfaceOperation(); + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(interfaceOperation.updateInterface(anyString(), anyObject())).thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); + + Assert.assertTrue(bl.validateComponentNameAndUpdateInterfaces(oldComponent, newComponent).isRight()); + } + + @Test(expected = Exception.class) + public void shouldThrowExceptionWhenComponentNameChangedButUpdateOperationFailed() { + Component newComponent = new Resource(); + newComponent.setName("newComponent"); + Component oldComponent = createResourceForInterfaceOperation(); + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(interfaceOperation.updateInterface(anyString(), anyObject())).thenThrow(new Exception()); + bl.validateComponentNameAndUpdateInterfaces(oldComponent, newComponent).isRight(); + } + private void validateUserRoles(Role... roles) { List<Role> listOfRoles = Stream.of(roles).collect(Collectors.toList()); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java index 6fe2f1308c..1a112c583b 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java @@ -66,7 +66,7 @@ public class InterfaceOperationValidationTest { } @Test - public void testValidInterfaceOperation() { + public void shouldPassOperationValidationForHappyScenario() { operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); Collection<Operation> operations = createInterfaceOperationData("op2", @@ -78,7 +78,7 @@ public class InterfaceOperationValidationTest { } @Test - public void testInterfaceOperationDescriptionLength() { + public void shouldFailWhenOperationOperationDescriptionLengthInvalid() { operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); Collection<Operation> operations = createInterfaceOperationData("op2", @@ -94,7 +94,7 @@ public class InterfaceOperationValidationTest { @Test - public void testInterfaceOperationForEmptyType() { + public void shouldFailWhenOperationNameIsEmpty() { operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); Collection<Operation> operations = createInterfaceOperationData("op2", @@ -106,19 +106,7 @@ public class InterfaceOperationValidationTest { } @Test - public void testInterfaceOperationForEmptyInputParam() { - operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); - operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); - Collection<Operation> operations = createInterfaceOperationData("op2", - "interface operation2",new ArtifactDefinition(), operationInputDefinitionList, - operationOutputDefinitionList,"input2"); - Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest - .validateInterfaceOperations(operations, component, false); - Assert.assertTrue(booleanResponseFormatEither.isRight()); - } - - @Test - public void testInterfaceOperationForNonUniqueType() { + public void shouldFailWhenOperationNamesAreNotUnique() { operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); Collection<Operation> operations = createInterfaceOperationData("op2", @@ -130,7 +118,7 @@ public class InterfaceOperationValidationTest { } @Test - public void testInterfaceOperationTypeLength() { + public void shouldFailWhenOperationNameLengthIsInvalid() { operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); Collection<Operation> operations = createInterfaceOperationData("op2", @@ -146,7 +134,7 @@ public class InterfaceOperationValidationTest { @Test - public void testInterfaceOperationUniqueInputParamNameInvalid() { + public void shouldFailWhenOperationInputParamNamesAreNotUnique() { operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label2")); @@ -162,7 +150,7 @@ public class InterfaceOperationValidationTest { } @Test - public void testInterfaceOperationUniqueInputParamNameValid() { + public void shouldPassWhenOperationInputParamNamesAreUnique() { operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label2")); operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); @@ -170,14 +158,28 @@ public class InterfaceOperationValidationTest { "interface operation2",new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList,"update"); + Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest + .validateInterfaceOperations(operations, component, false); + Assert.assertTrue(booleanResponseFormatEither.isLeft()); + } + @Test + public void shouldPassWhenOperationInputParamNamesHasSubProperty() { + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label2")); + operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); + Collection<Operation> operations = createInterfaceOperationData("op2", + "interface operation2",new ArtifactDefinition(), operationInputDefinitionList, + operationOutputDefinitionList,"update"); + operationInputDefinitionList.getListToscaDataDefinition().get(0).setInputId(operationInputDefinitionList + .getListToscaDataDefinition().get(0).getInputId().concat(".subproperty")); Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest .validateInterfaceOperations(operations, component, false); Assert.assertTrue(booleanResponseFormatEither.isLeft()); } @Test - public void testInterfaceOperationInputParamNameEmpty() { + public void shouldFailWhenOperationInputParamNameEmpty() { operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition(" ")); operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); @@ -185,6 +187,48 @@ public class InterfaceOperationValidationTest { "interface operation2",new ArtifactDefinition(), operationInputDefinitionList, operationOutputDefinitionList,"update"); + Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest + .validateInterfaceOperations(operations, component, false); + Assert.assertTrue(booleanResponseFormatEither.isRight()); + } + + @Test + public void shouldFailWhenOperationOutputParamNameEmpty() { + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("inputParam")); + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); + operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition(" ")); + Collection<Operation> operations = createInterfaceOperationData("op2", + "interface operation2",new ArtifactDefinition(), operationInputDefinitionList, + operationOutputDefinitionList,"update"); + + Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest + .validateInterfaceOperations(operations, component, false); + Assert.assertTrue(booleanResponseFormatEither.isRight()); + } + + @Test + public void shouldPassWhenInterfaceOperationOutputParamNamesUnique() { + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("label1")); + operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label1")); + operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("label2")); + Collection<Operation> operations = createInterfaceOperationData("op2", + "interface operation2",new ArtifactDefinition(), operationInputDefinitionList, + operationOutputDefinitionList,"update"); + + Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest + .validateInterfaceOperations(operations, component, false); + Assert.assertTrue(booleanResponseFormatEither.isLeft()); + } + + @Test + public void shouldFailWhenOperationOutputParamNamesAreNotUnique() { + operationInputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationInputDefinition("inputParam1")); + operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("outParam1")); + operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("outParam2")); + operationOutputDefinitionList.add(InterfaceOperationTestUtils.createMockOperationOutputDefinition("outParam2")); + Collection<Operation> operations = createInterfaceOperationData("op2", + "interface operation2",new ArtifactDefinition(), operationInputDefinitionList, + operationOutputDefinitionList,"update"); Either<Boolean, ResponseFormat> booleanResponseFormatEither = interfaceOperationValidationUtilTest .validateInterfaceOperations(operations, component, false); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtilTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtilTest.java index ac53a6d930..8f34e0e29b 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtilTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtilTest.java @@ -146,7 +146,7 @@ public class InterfacesOperationsToscaUtilTest { component.setInterfaces(new HashMap<>()); component.getInterfaces().put(interfaceType, addedInterface); ToscaNodeType nodeType = new ToscaNodeType(); - InterfacesOperationsToscaUtil.addInterfaceDefinitionElement(component, nodeType, true); + InterfacesOperationsToscaUtil.addInterfaceDefinitionElement(component, nodeType, false); ToscaExportHandler handler = new ToscaExportHandler(null,null,null,null,null,null); ToscaTemplate template = new ToscaTemplate("testService"); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java index 916a34c0f3..f9f2ce9b35 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/InterfaceOperation.java @@ -17,6 +17,7 @@ package org.openecomp.sdc.be.model.jsontitan.operations; import fj.data.Either; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -93,6 +94,17 @@ public class InterfaceOperation extends BaseOperation { Either<GraphVertex, TitanOperationStatus> getToscaElementRes; Either<GraphVertex, TitanOperationStatus> getToscaElementInt; + if(isUpdateAction && operation.getImplementationArtifact() != null){ + String artifactUUID = operation.getImplementationArtifact().getArtifactUUID(); + Either<Long, CassandraOperationStatus> artifactCount = artifactCassandraDao.getCountOfArtifactById(artifactUUID); + if(artifactCount.isLeft()){ + CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(artifactUUID); + if (cassandraStatus != CassandraOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertCassandraStatusToStorageStatus(cassandraStatus)); + } + } + } + getToscaElementRes = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); if (getToscaElementRes.isRight()) { TitanOperationStatus status = getToscaElementRes.right().value(); @@ -139,6 +151,21 @@ public class InterfaceOperation extends BaseOperation { return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getInterfaceVertex.right().value())); } + if (!interfaceDef.getOperationsMap().isEmpty()) { + Either<GraphVertex, TitanOperationStatus> getInterfaceOpVertex = + titanDao.getChildVertex(getInterfaceVertex.left().value(), EdgeLabelEnum.INTERFACE_OPERATION, + JsonParseFlagEnum.NoParse); + if (getInterfaceOpVertex.isRight()) { + List<ToscaDataDefinition> toscaDataList = new ArrayList<>(interfaceDef.getOperationsMap().values()); + StorageOperationStatus statusRes = + addToscaDataToToscaElement(getInterfaceVertex.left().value(), EdgeLabelEnum.INTERFACE_OPERATION, + VertexTypeEnum.INTERFACE_OPERATION, toscaDataList, JsonPresentationFields.UNIQUE_ID); + if (!statusRes.equals(StorageOperationStatus.OK)) { + return Either.right(statusRes); + } + } + } + Optional<Entry<String, Operation>> operationToRemove = interfaceDef.getOperationsMap().entrySet().stream() .filter(entry -> entry.getValue().getUniqueId().equals(operationToDelete)).findAny(); if (operationToRemove.isPresent()){ diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts index da9cf5f752..e19d3457b3 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts +++ b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts @@ -174,12 +174,11 @@ export class InterfaceOperationComponent { this.operationList.sort((a, b) => a.operationType.localeCompare(b.operationType)); if (response.workflowId && operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING) { - const resourceId = this.component.uuid; const operationId = response.uniqueId; const workflowId = response.workflowId; const versionId = response.workflowVersionId; const artifactId = response.artifactUUID; - this.WorkflowServiceNg2.associateWorkflowArtifact(resourceId, operationId, workflowId, versionId, artifactId).subscribe(); + this.WorkflowServiceNg2.associateWorkflowArtifact(this.component, operationId, workflowId, versionId, artifactId).subscribe(); } else if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW) { this.$state.go('workspace.plugins', { path: 'workflowDesigner' }); } @@ -193,13 +192,12 @@ export class InterfaceOperationComponent { this.operationList.splice(index, 1, newOperation); this.component.interfaceOperations = this.operationList; - if (newOperation.workflowId) { - const resourceId = this.component.uuid; + if (newOperation.workflowId && operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING) { const operationId = newOperation.uniqueId; const workflowId = newOperation.workflowId; const versionId = newOperation.workflowVersionId; const artifactId = newOperation.artifactUUID; - this.WorkflowServiceNg2.associateWorkflowArtifact(resourceId, operationId, workflowId, versionId, artifactId).subscribe(); + this.WorkflowServiceNg2.associateWorkflowArtifact(this.component, operationId, workflowId, versionId, artifactId).subscribe(); } }); } diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html index 982cbb204c..6010bca10f 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html @@ -127,11 +127,10 @@ <param-row *ngFor="let param of tableParameters" class="data-row" - [isInputParam]="currentTab == TYPE_INPUT" + [isInputParam]="currentTab === TYPE_INPUT" [isAssociateWorkflow]="isUsingExistingWF()" [param]="param" [inputProps]="inputProperties" - [propTypes]="inputPropertyTypes" [onRemoveParam]="onRemoveParam" [readonly]="readonly"> </param-row> diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts index 5d3b027493..a6c1fb1c4c 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts @@ -18,7 +18,6 @@ export interface OperationCreatorInput { isService: boolean } - @Component({ selector: 'operation-creator', templateUrl: './operation-creator.component.html', @@ -33,7 +32,7 @@ export class OperationCreatorComponent { workflows: Array<DropdownValue> = []; workflowVersions: Array<DropdownValue> = []; - inputProperties: Array<DropdownValue> = []; + inputProperties: Array<InputBEModel> = []; inputPropertyTypes: { [key: string]: string }; inputParameters: Array<OperationParameter> = []; @@ -76,19 +75,10 @@ export class OperationCreatorComponent { } ngOnInit() { - this.readonly = this.input.readonly; this.isService = this.input.isService; - this.enableWorkflowAssociation = this.input.enableWorkflowAssociation && !this.isService; - - this.inputProperties = _.map(this.input.inputProperties, - (input: InputBEModel) => new DropdownValue(input.uniqueId, input.name) - ); - - this.inputPropertyTypes = {}; - _.forEach(this.input.inputProperties, (input: InputBEModel) => { - this.inputPropertyTypes[input.uniqueId] = input.type; - }); + this.enableWorkflowAssociation = this.input.enableWorkflowAssociation; + this.inputProperties = this.input.inputProperties; const inputOperation = this.input.operation; this.operation = new OperationModel(inputOperation || {}); @@ -108,13 +98,12 @@ export class OperationCreatorComponent { } else { this.reconstructOperation(); } - } reconstructOperation = () => { const inputOperation = this.input.operation; if (inputOperation) { - if (!this.enableWorkflowAssociation || !inputOperation.workflowVersionId || this.isService) { + if (!this.enableWorkflowAssociation || !inputOperation.workflowVersionId) { this.inputParameters = this.noAssignInputParameters; this.outputParameters = this.noAssignOutputParameters; this.buildParams(); diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html index 94d2fce1ea..9a5c101e87 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.html @@ -1,5 +1,5 @@ <!-- - ~ Copyright � 2016-2018 European Support Limited + ~ Copyright � 2016-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. @@ -38,14 +38,14 @@ <div class="cell field-property" *ngIf="isInputParam"> <ui-element-dropdown - *ngIf="filteredInputProps.length > 0 || !isAssociateWorkflow" + *ngIf="filteredInputProps.length || !isAssociateWorkflow" data-tests-id="paramProperty" [values]="filteredInputProps" [(value)]="param.property" [readonly]="readonly"> </ui-element-dropdown> <span - *ngIf="filteredInputProps.length == 0 && isAssociateWorkflow" + *ngIf="!filteredInputProps.length && isAssociateWorkflow" class="no-properties-error"> No available properties of this type. </span> diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less index 28932eb90f..2c2625d778 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.less @@ -38,7 +38,7 @@ } .no-properties-error { - color: red; + color: @func_color_q; font-style: italic; } } diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts index 8844cf65bb..de795eb8f4 100644 --- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts +++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/param-row/param-row.component.ts @@ -1,6 +1,6 @@ import {Component, Input} from '@angular/core'; import {DataTypeService} from "app/ng2/services/data-type.service"; -import {OperationParameter} from 'app/models'; +import {OperationParameter, InputBEModel} from 'app/models'; import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component"; @Component({ @@ -11,8 +11,7 @@ import {DropdownValue} from "app/ng2/components/ui/form-components/dropdown/ui-e export class ParamRowComponent { @Input() param: OperationParameter; - @Input() inputProps: Array<DropdownValue>; - @Input() propTypes: { [key: string]: string }; + @Input() inputProps: Array<InputBEModel>; @Input() onRemoveParam: Function; @Input() isAssociateWorkflow: boolean; @Input() readonly: boolean; @@ -21,14 +20,61 @@ export class ParamRowComponent { propTypeEnum: Array<String> = []; filteredInputProps: Array<DropdownValue> = []; + constructor(private dataTypeService: DataTypeService) {} + ngOnInit() { - this.propTypeEnum = _.uniq(_.toArray(this.propTypes)); + this.propTypeEnum = _.uniq( + _.map( + this.getPrimitiveSubtypes(), + prop => prop.type + ) + ); + console.log(this.dataTypeService.getAllDataTypes()); this.onChangeType(); } onChangeType() { - this.filteredInputProps = _.filter(this.inputProps, prop => { - return this.propTypes[prop.value] === this.param.type; + this.filteredInputProps = _.map( + _.filter( + this.getPrimitiveSubtypes(), + prop => prop.type === this.param.type + ), + prop => new DropdownValue(prop.uniqueId, prop.name) + ); + } + + getPrimitiveSubtypes(): Array<InputBEModel> { + const flattenedProps: Array<any> = []; + const dataTypes = this.dataTypeService.getAllDataTypes(); + _.forEach(this.inputProps, prop => { + const type = _.find( + _.toArray(dataTypes), + (type: any) => type.name === prop.type + ); + if (!type.properties) { + flattenedProps.push(prop); + } else { + _.forEach(type.properties, subType => { + if (this.isTypePrimitive(subType.type)) { + flattenedProps.push({ + type: subType.type, + name: `${prop.name}.${subType.name}`, + uniqueId: `${prop.uniqueId}.${subType.name}` + }); + } + }); + } }); + + return flattenedProps; + } + + isTypePrimitive(type): boolean { + return ( + type === 'string' || + type === 'integer' || + type === 'float' || + type === 'boolean' + ); } } diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts index 3546ebd374..26b0291156 100644 --- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts +++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts @@ -128,9 +128,7 @@ export class ComponentServiceNg2 { getInterfaceOperation(component:Component, operation:OperationModel):Observable<OperationModel> { return this.http.get(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations/' + operation.uniqueId) - .map((res:Response) => { - return res.json(); - }); + .map((res:Response) => res.json()); } createInterfaceOperation(component:Component, operation:OperationModel):Observable<CreateOperationResponse> { @@ -140,9 +138,7 @@ export class ComponentServiceNg2 { } }; return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList) - .map((res:Response) => { - return res.json(); - }); + .map((res:Response) => res.json()); } updateInterfaceOperation(component:Component, operation:OperationModel):Observable<CreateOperationResponse> { @@ -152,16 +148,12 @@ export class ComponentServiceNg2 { } }; return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList) - .map((res:Response) => { - return res.json(); - }); + .map((res:Response) => res.json()); } deleteInterfaceOperation(component:Component, operation:OperationModel):Observable<OperationModel> { return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations/' + operation.uniqueId) - .map((res:Response) => { - return res.json(); - }); + .map((res:Response) => res.json()); } getCapabilitiesAndRequirements(componentType: string, componentId:string):Observable<ComponentGenericResponse> { @@ -189,7 +181,6 @@ export class ComponentServiceNg2 { deleteInput(component:Component, input:InputBEModel):Observable<InputBEModel> { - return this.http.delete(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/delete/' + input.uniqueId + '/input') .map((res:Response) => { return new InputBEModel(res.json()); @@ -197,7 +188,6 @@ export class ComponentServiceNg2 { } updateComponentInputs(component:Component, inputs:InputBEModel[]):Observable<InputBEModel[]> { - return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/update/inputs', inputs) .map((res:Response) => { return res.json().map((input) => new InputBEModel(input)); diff --git a/catalog-ui/src/app/ng2/services/workflow.service.ts b/catalog-ui/src/app/ng2/services/workflow.service.ts index ae06a39713..24ba882a96 100644 --- a/catalog-ui/src/app/ng2/services/workflow.service.ts +++ b/catalog-ui/src/app/ng2/services/workflow.service.ts @@ -3,6 +3,7 @@ import { Response } from "@angular/http"; import { Observable } from "rxjs/Observable"; import { HttpService } from "./http.service"; import { SdcConfigToken, ISdcConfig } from "../config/sdc-config.config"; +import { Component } from "app/models"; @Injectable() export class WorkflowServiceNg2 { @@ -12,11 +13,21 @@ export class WorkflowServiceNg2 { VERSION_STATE_CERTIFIED = 'CERTIFIED'; - constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig:ISdcConfig) { + constructor(private http: HttpService, @Inject(SdcConfigToken) sdcConfig: ISdcConfig) { this.baseUrl = sdcConfig.api.workflow_root; this.catalogBaseUrl = sdcConfig.api.POST_workflow_artifact; } + public associateWorkflowArtifact(component: Component, operationId: string, workflowId: string, workflowVersionId: string, artifactUuid: string): Observable<any> { + return this.http.post(this.baseUrl + '/workflows/' + workflowId + '/versions/' + workflowVersionId + '/artifact-deliveries', { + endpoint: this.catalogBaseUrl + '/' + component.getTypeUrl() + component.uuid + '/interfaces/' + operationId + '/artifacts/' + artifactUuid, + method: 'POST' + }) + .map((res:Response) => { + return res.json(); + }); + } + public getWorkflows(filterCertified: boolean = true): Observable<any> { return this.http.get(this.baseUrl + '/workflows' + (filterCertified ? '?versionState=' + this.VERSION_STATE_CERTIFIED : '')) .map((res:Response) => { @@ -38,14 +49,4 @@ export class WorkflowServiceNg2 { }); } - public associateWorkflowArtifact(resourceUuid, operationId, workflowId, workflowVersionId, artifactUuid): Observable<any> { - return this.http.post(this.baseUrl + '/workflows/' + workflowId + '/versions/' + workflowVersionId + '/artifact-deliveries', { - endpoint: this.catalogBaseUrl + '/resources/' + resourceUuid + '/interfaces/' + operationId + '/artifacts/' + artifactUuid, - method: 'POST' - }) - .map((res:Response) => { - return res.json(); - }); - } - } diff --git a/openecomp-bdd/features/InterfaceOperation/TestResourceInterfaceOperation.feature b/openecomp-bdd/features/InterfaceOperation/TestResourceInterfaceOperation.feature index 9f3cd5490f..ed09f2fb20 100644 --- a/openecomp-bdd/features/InterfaceOperation/TestResourceInterfaceOperation.feature +++ b/openecomp-bdd/features/InterfaceOperation/TestResourceInterfaceOperation.feature @@ -7,7 +7,7 @@ Feature: Interface Operation Feature #Create Operations When I want to create an Operation Then I want to check property "uniqueId" exists - And I want to create an Operation + And I want to create an Operation with workflow Then I want to check property "uniqueId" exists And I want to create an Operation Then I want to check property "uniqueId" exists diff --git a/openecomp-bdd/features/InterfaceOperation/TestServiceInterfaceOperation.feature b/openecomp-bdd/features/InterfaceOperation/TestServiceInterfaceOperation.feature index 1ad2377e1b..1ff0ba3f1b 100644 --- a/openecomp-bdd/features/InterfaceOperation/TestServiceInterfaceOperation.feature +++ b/openecomp-bdd/features/InterfaceOperation/TestServiceInterfaceOperation.feature @@ -7,7 +7,7 @@ Feature: Interface Operation Feature #Create Operations When I want to create an Operation Then I want to check property "uniqueId" exists - And I want to create an Operation + And I want to create an Operation with workflow Then I want to check property "uniqueId" exists And I want to create an Operation Then I want to check property "uniqueId" exists diff --git a/openecomp-bdd/resources/json/operation/createOperation-with-workflow.json b/openecomp-bdd/resources/json/operation/createOperation-with-workflow.json new file mode 100644 index 0000000000..e9693adf2a --- /dev/null +++ b/openecomp-bdd/resources/json/operation/createOperation-with-workflow.json @@ -0,0 +1,30 @@ +{ + "interfaceOperations": { + "operation": { + "description": "abcd description", + "inputParams": { + "listToscaDataDefinition": [ + { + "name": "inp1", + "type": "string", + "property": "97477d27-8fe2-45a1-83cb-83368ef2a402.nf_naming_code", + "mandatory": true + } + ] + }, + "outputParams": { + "listToscaDataDefinition": [ + { + "name": "op", + "mandatory": true, + "type": "String" + } + ] + }, + "operationType": "create", + "workflowAssociationType": "EXISTING", + "workflowId" : "workflowId", + "workflowVersionId" : "workflowVersionId" + } + } +}
\ No newline at end of file diff --git a/openecomp-bdd/stepDefinitions/InterfaceOperationSteps.js b/openecomp-bdd/stepDefinitions/InterfaceOperationSteps.js index f4a81d6110..408db9e9f8 100644 --- a/openecomp-bdd/stepDefinitions/InterfaceOperationSteps.js +++ b/openecomp-bdd/stepDefinitions/InterfaceOperationSteps.js @@ -26,7 +26,7 @@ When('I want to create a VF', function() { var type = "resources"; let path = '/catalog/' + type; - return util.request(this.context, 'POST', path, inputData, false, 'vf').then(result => { + return util.request(this.context, 'POST', path, inputData, false, 'catalog').then(result => { this.context.component = {uniqueId : result.data.uniqueId, type : type, id : result.data.inputs[0].uniqueId}; }); }); @@ -39,7 +39,7 @@ When('I want to create a Service', function() { var type = "services"; let path = '/catalog/' + type; - return util.request(this.context, 'POST', path, inputData, false, 'vf').then(result => { + return util.request(this.context, 'POST', path, inputData, false, 'catalog').then(result => { this.context.component = {uniqueId : result.data.uniqueId, type : type, id : result.data.inputs[0].uniqueId}; }); }); @@ -64,33 +64,48 @@ When('I want to create an Operation with input output', function() { inputData.interfaceOperations.operation.operationType = makeType(); inputData.interfaceOperations.operation.description = makeType(); - return util.request(this.context, 'POST', path, inputData, false, 'vf').then(result => { - this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; + return util.request(this.context, 'POST', path, inputData, false, 'catalog').then(result => { + this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; }); }); - When('I want to create an Operation', function() { let path = '/catalog/' + this.context.component.type + '/' + this.context.component.uniqueId + '/interfaceOperations'; - let inputData = util.getJSONFromFile('resources/json/operation/createOperation.json'); + let inputData = util.getJSONFromFile('resources/json/operation/createOperation.json'); inputData.interfaceOperations.operation.operationType = makeType(); inputData.interfaceOperations.operation.description = makeType(); - return util.request(this.context, 'POST', path, inputData, false, 'vf').then(result => { + return util.request(this.context, 'POST', path, inputData, false, 'catalog').then(result => { this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; }); }); +When('I want to create an Operation with workflow', function() { + let path = '/catalog/' + this.context.component.type + '/' + this.context.component.uniqueId + '/interfaceOperations'; + let inputData = util.getJSONFromFile('resources/json/operation/createOperation-with-workflow.json'); + + inputData.interfaceOperations.operation.inputParams.listToscaDataDefinition[0].name = util.random(); + inputData.interfaceOperations.operation.inputParams.listToscaDataDefinition[0].property = this.context.component.id; + inputData.interfaceOperations.operation.outputParams.listToscaDataDefinition[0].name = util.random(); + inputData.interfaceOperations.operation.operationType = makeType(); + inputData.interfaceOperations.operation.description = makeType(); + inputData.interfaceOperations.operation.workflowId = makeType(); + inputData.interfaceOperations.operation.workflowVersionId = makeType(); + + return util.request(this.context, 'POST', path, inputData, false, 'catalog').then(result => { + this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; +}); +}); When('I want to list Operations', function () { let path = '/catalog/'+ this.context.component.type + '/' + this.context.component.uniqueId + '/filteredDataByParams?include=interfaces'; - return util.request(this.context, 'GET', path, null, false, 'vf').then((result)=> { + return util.request(this.context, 'GET', path, null, false, 'catalog').then((result)=> { }); }); When('I want to get an Operation by Id', function () { let path = '/catalog/'+ this.context.component.type + '/' + this.context.component.uniqueId + '/interfaceOperations/' + this.context.operation.uniqueId; - return util.request(this.context, 'GET', path, null, false, 'vf').then((result)=> { + return util.request(this.context, 'GET', path, null, false, 'catalog').then((result)=> { this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; }); }); @@ -103,7 +118,7 @@ When('I want to update an Operation', function () { inputData.interfaceOperations.operation.inputParams.listToscaDataDefinition[0].name = util.random(); inputData.interfaceOperations.operation.inputParams.listToscaDataDefinition[0].property = this.context.component.id; inputData.interfaceOperations.operation.outputParams.listToscaDataDefinition[0].name = util.random(); - return util.request(this.context, 'PUT', path, inputData, false, 'vf').then((result)=> { + return util.request(this.context, 'PUT', path, inputData, false, 'catalog').then((result)=> { this.context.operation = {uniqueId : result.data.uniqueId, operationType : result.data.operationType}; }); }); @@ -111,14 +126,14 @@ When('I want to update an Operation', function () { When('I want to delete an Operation', function() { let path = '/catalog/'+ this.context.component.type + '/'+ this.context.component.uniqueId +'/interfaceOperations/' + this.context.operation.uniqueId; - return util.request(this.context, 'DELETE', path, null, false, 'vf'); + return util.request(this.context, 'DELETE', path, null, false, 'catalog'); }); When('I want to checkin this component', function () { let path = '/catalog/'+ this.context.component.type + '/' + this.context.component.uniqueId + '/lifecycleState/CHECKIN' ; let inputData = {userRemarks: 'checkin'}; - return util.request(this.context, 'POST', path, inputData, false, 'vf').then((result)=> { + return util.request(this.context, 'POST', path, inputData, false, 'catalog').then((result)=> { this.context.component = {uniqueId : result.data.uniqueId, type : this.context.component.type}; }); }); @@ -127,15 +142,15 @@ When('I want to checkin this component', function () { Then('I want to submit this component', function () { let path = '/catalog/'+ this.context.component.type + '/' + this.context.component.uniqueId + '/lifecycleState/certificationRequest' ; let inputData = {userRemarks: 'submit'}; - return util.request(this.context, 'POST', path, inputData, false, 'vf').then((result)=> { - this.context.vf = {uniqueId : result.data.uniqueId}; + return util.request(this.context, 'POST', path, inputData, false, 'catalog').then((result)=> { + this.context.component = {uniqueId : result.data.uniqueId}; }); }); Then('I want to certify this component', function () { let path = '/catalog/'+ this.context.component.type +'/' + this.context.component.uniqueId + '/lifecycleState/certify' ; let inputData = {userRemarks: 'certify'}; - return util.request(this.context, 'POST', path, inputData, false, 'vf').then((result)=> { + return util.request(this.context, 'POST', path, inputData, false, 'catalog').then((result)=> { this.context.component = {uniqueId : result.data.uniqueId}; }); });
\ No newline at end of file |