diff options
Diffstat (limited to 'catalog-be/src')
5 files changed, 189 insertions, 1 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index ce1eed1a4c..236db5fe40 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -2700,6 +2700,66 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); } } + + public Either<RequirementDefinition, ResponseFormat> updateInstanceRequirement(ComponentTypeEnum componentTypeEnum, String containerComponentId, String componentInstanceUniqueId, String capabilityType, String capabilityName, + RequirementDefinition requirementDef, String userId) { + + Either<RequirementDefinition, ResponseFormat> resultOp = null; + + validateUserExists(userId); + if (componentTypeEnum == null) { + BeEcompErrorManager.getInstance().logInvalidInputError("updateInstanceRequirement", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)); + } + Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaFullElement(containerComponentId); + + if (getResourceResult.isRight()) { + log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, containerComponentId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + Component containerComponent = getResourceResult.left().value(); + + if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) { + log.info("Restricted operation for user: {} on component {}", userId, containerComponentId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, componentInstanceUniqueId); + if (resourceInstanceStatus.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId)); + } + // lock resource + StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, componentTypeEnum.getNodeType()); + if (lockStatus != StorageOperationStatus.OK) { + log.debug("Failed to lock component {}", containerComponentId); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus))); + } + + try { + StorageOperationStatus updateRequirementStatus = toscaOperationFacade.updateComponentInstanceRequirement(containerComponentId, componentInstanceUniqueId, requirementDef); + if (updateRequirementStatus != StorageOperationStatus.OK) { + log.debug("Failed to update component instance requirement on instance {} in container {}", componentInstanceUniqueId, containerComponentId); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateRequirementStatus))); + } + Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(containerComponent); + + if (updateContainerRes.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value()); + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + return resultOp; + } + resultOp = Either.left(requirementDef); + return resultOp; + + } finally { + if (resultOp == null || resultOp.isRight()) { + janusGraphDao.rollback(); + } else { + janusGraphDao.commit(); + } + // unlock resource + graphLockOperation.unlockComponent(containerComponentId, componentTypeEnum.getNodeType()); + } + } public Either<List<ComponentInstanceProperty>, ResponseFormat> updateInstanceCapabilityProperties(ComponentTypeEnum componentTypeEnum, String containerComponentId, String componentInstanceUniqueId, String capabilityType, String capabilityName, List<ComponentInstanceProperty> properties, String userId) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java index 4f3120aba2..5c3bd859be 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java @@ -88,9 +88,11 @@ import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.user.UserBusinessLogic; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.datastructure.Wrapper; @@ -1095,6 +1097,67 @@ public class ComponentInstanceServlet extends AbstractValidationsServlet { throw e; } } + + @PUT + @Path("/{containerComponentType}/{containerComponentId}/componentInstances/{componentInstanceUniqueId}/requirement/{capabilityType}/requirementName/{requirementName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Operation(description = "Update Instance Requirement", method = "PUT", + summary = "Returns updated requirement", responses = { + @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), + @ApiResponse(responseCode = "200", description = "Resource instance requirement updated"), + @ApiResponse(responseCode = "403", description = "Restricted operation"), + @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), + @ApiResponse(responseCode = "404", description = "Component/Component Instance/Requirement - not found")}) + @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) + public Response updateInstanceRequirement( + @PathParam("containerComponentType") final String containerComponentType, + @PathParam("containerComponentId") final String containerComponentId, + @PathParam("componentInstanceUniqueId") final String componentInstanceUniqueId, + @PathParam("capabilityType") final String capabilityType, + @PathParam("requirementName") final String requirementName, + @Parameter(description = "Instance capabilty requirement to update", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug(START_HANDLE_REQUEST_OF, url); + loggerSupportability.log(LoggerSupportabilityActions.UPDATE_INSTANCE_REQUIREMENT, StatusCode.STARTED,"Starting to update requirement {} in component instance {} by {}", requirementName, componentInstanceUniqueId, userId ); + try { + + log.debug(START_HANDLE_REQUEST_OF, url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + if (componentInstanceBusinessLogic == null) { + log.debug(UNSUPPORTED_COMPONENT_TYPE, containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either<RequirementDefinition, ResponseFormat> mappedRequirementDataEither = getMappedRequirementData(data, new User(userId), componentTypeEnum); + if(mappedRequirementDataEither.isRight()) { + log.debug("Failed to update requirements"); + return buildErrorResponse(mappedRequirementDataEither.right().value()); + } + RequirementDefinition requirementDef = mappedRequirementDataEither.left().value(); + + Either<RequirementDefinition, ResponseFormat> response = componentInstanceBusinessLogic.updateInstanceRequirement(componentTypeEnum, containerComponentId, componentInstanceUniqueId, capabilityType, requirementName, requirementDef, userId); + + if (response.isRight()) { + return buildErrorResponse(response.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), response.left().value()); + + } catch (ComponentException e) { + throw e; + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update component instance requirement"); + log.debug("Update component instance requirement with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Either<RequirementDefinition, ResponseFormat> getMappedRequirementData(String inputJson, User user, + ComponentTypeEnum componentTypeEnum){ + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(inputJson, user, RequirementDefinition.class, AuditingActionEnum.GET_TOSCA_MODEL, componentTypeEnum); + } @POST @Path("/{containerComponentType}/{containerComponentId}/serviceProxy") diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java index 9a55fb885c..3e4907721d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java @@ -307,7 +307,7 @@ public class CapabilityRequirementConverter { Either<Map<String, String[]>, ToscaError> result = null; for (Map.Entry<String, List<RequirementDefinition>> entry : requirements.entrySet()) { Optional<RequirementDefinition> failedToAddRequirement = entry.getValue() - .stream() + .stream().filter(RequirementDefinition::isExternal) .filter(r->!addEntry(componentsCache, toscaRequirements, component, new SubstitutionEntry(r.getName(), r.getParentName(), ""), r.getPreviousName(), r.getOwnerId(), r.getPath())) .findAny(); if(failedToAddRequirement.isPresent()){ diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java index d585c6f77a..12ffe1c193 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java @@ -1143,6 +1143,36 @@ class ComponentInstanceBusinessLogicTest { componentInstanceUniqueId, capabilityType, capabilityName, properties, userId); assertNotNull(result); } + + @Test + void testUpdateInstanceRequirement() { + ComponentInstanceBusinessLogic testSubject; + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.RESOURCE; + createComponents(); + String userId = "userId"; + resource.setLastUpdaterUserId(userId); + String containerComponentId = resource.getUniqueId(); + String componentInstanceUniqueId = TO_INSTANCE_ID; + String capabilityType = ""; + String capabilityName = ""; + RequirementDefinition requirementDef = new RequirementDefinition(); + + Either<RequirementDefinition, ResponseFormat> result; + + when(toscaOperationFacade.getToscaFullElement(containerComponentId)).thenReturn(Either.left(resource)); + testSubject = createTestSubject(); + when(toscaOperationFacade.updateComponentInstanceRequirement(containerComponentId, TO_INSTANCE_ID, requirementDef)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(resource)).thenReturn(Either.left(resource)); + when(graphLockOperation.unlockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource))) + .thenReturn(StorageOperationStatus.OK); + when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource))) + .thenReturn(StorageOperationStatus.OK); + + result = testSubject.updateInstanceRequirement(componentTypeEnum, containerComponentId, + componentInstanceUniqueId, capabilityType, capabilityName, requirementDef, userId); + assertEquals(requirementDef, result.left().value()); + + } @Test void testCopyComponentInstanceWrongUserId() { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java index d801314c79..0eee7a1238 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentInstanceServletTest.java @@ -39,6 +39,7 @@ import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import javax.ws.rs.Path; import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @@ -66,6 +67,7 @@ import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.user.UserBusinessLogic; @@ -433,4 +435,37 @@ public class ComponentInstanceServletTest extends JerseyTest { .header("USER_ID", USER_ID).post(Entity.entity(inputs, MediaType.APPLICATION_JSON)); assertThat(response.getStatus()).isEqualTo(HttpStatus.NOT_FOUND_404); } + + @Test + public void testUpdateInstanceRequirement(){ + + String containerComponentType = "services"; + String componentId = "componentId"; + String componentInstanceId = "componentInstanceIdInstanceId"; + String capabilityType = "capabilityType"; + String requirementName = "requirementName"; + RequirementDefinition requirementDefinition = new RequirementDefinition(); + ObjectMapper mapper = new ObjectMapper(); + String requirementJson = null; + try { + requirementJson = mapper.writeValueAsString(requirementDefinition); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + String path = "/v1/catalog/" + containerComponentType + "/" + componentId + "/componentInstances/" + + componentInstanceId + "/requirement/" + capabilityType + "/requirementName/" + requirementName; + when(componentsUtils.convertJsonToObjectUsingObjectMapper(eq(requirementJson), any(User.class), eq(RequirementDefinition.class), + eq(AuditingActionEnum.GET_TOSCA_MODEL), eq(ComponentTypeEnum.SERVICE))).thenReturn(Either.left(requirementDefinition)); + when(componentInstanceBusinessLogic.updateInstanceRequirement(ComponentTypeEnum.SERVICE, + componentId, componentInstanceId, capabilityType, requirementName, requirementDefinition, USER_ID)) + .thenReturn(Either.left(requirementDefinition)); + when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); + when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); + + Response response = target() + .path(path) + .request(MediaType.APPLICATION_JSON) + .header("USER_ID", USER_ID).put(Entity.entity(requirementDefinition, MediaType.APPLICATION_JSON)); + assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); + } } |