X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fcomponents%2Fimpl%2FServiceBusinessLogic.java;h=9874020b49451dd7c6d1d0dfb34d9e33f8509390;hb=216ea4998de9ae4ee603d7f8f5f6725b218ca710;hp=aa011e91f497eec9f7b601a3bf122a88fafd658b;hpb=88fdc6dd75f1119ffa8e54dbfd721b6ed722b779;p=sdc.git diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java index aa011e91f4..9874020b49 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java @@ -19,6 +19,7 @@ * Modifications copyright (c) 2019 Nokia * ================================================================================ */ + package org.openecomp.sdc.be.components.impl; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; @@ -45,6 +46,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -53,6 +55,8 @@ import java.util.function.Function; import java.util.stream.Collectors; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.Getter; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -67,6 +71,7 @@ import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; +import org.openecomp.sdc.be.components.kafka.KafkaHandler; import org.openecomp.sdc.be.components.path.ForwardingPathValidator; import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils; import org.openecomp.sdc.be.components.utils.PropertiesUtils; @@ -97,9 +102,14 @@ import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo; @@ -118,6 +128,7 @@ import org.openecomp.sdc.be.model.GroupInstanceProperty; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Model; import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; @@ -133,6 +144,7 @@ import org.openecomp.sdc.be.model.operations.api.IGroupOperation; import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.ModelOperation; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; import org.openecomp.sdc.be.plugins.ServiceCreationPlugin; @@ -167,7 +179,7 @@ import org.springframework.web.context.WebApplicationContext; @org.springframework.stereotype.Component("serviceBusinessLogic") public class ServiceBusinessLogic extends ComponentBusinessLogic { - static final String IS_VALID = "isValid"; + private static final String IS_VALID = "isValid"; private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. "; private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. "; private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response"; @@ -181,21 +193,19 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { private final ServiceDistributionValidation serviceDistributionValidation; private final ForwardingPathValidator forwardingPathValidator; private final UiComponentDataConverter uiComponentDataConverter; + private final ModelOperation modelOperation; + private final ServiceRoleValidator serviceRoleValidator; + private final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator; + private final ServiceCategoryValidator serviceCategoryValidator; + private final ServiceValidator serviceValidator; + private final GroupBusinessLogic groupBusinessLogic; + private final KafkaHandler kafkaHandler; private ForwardingPathOperation forwardingPathOperation; private AuditCassandraDao auditCassandraDao; private ServiceTypeValidator serviceTypeValidator; private List serviceCreationPluginList; private ServiceFunctionValidator serviceFunctionValidator; - @Autowired - private ServiceRoleValidator serviceRoleValidator; - @Autowired - private ServiceInstantiationTypeValidator serviceInstantiationTypeValidator; - @Autowired - private ServiceCategoryValidator serviceCategoryValidator; - @Autowired - private ServiceValidator serviceValidator; - @Autowired public ServiceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic, InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsBusinessLogic artifactsBusinessLogic, @@ -205,7 +215,11 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator, ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator, ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator, - ComponentDescriptionValidator componentDescriptionValidator) { + ComponentDescriptionValidator componentDescriptionValidator, ModelOperation modelOperation, + final ServiceRoleValidator serviceRoleValidator, + final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator, + final ServiceCategoryValidator serviceCategoryValidator, final ServiceValidator serviceValidator, + KafkaHandler kafkaHandler) { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation, interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator, componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator); @@ -214,6 +228,13 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { this.serviceDistributionValidation = serviceDistributionValidation; this.forwardingPathValidator = forwardingPathValidator; this.uiComponentDataConverter = uiComponentDataConverter; + this.modelOperation = modelOperation; + this.serviceRoleValidator = serviceRoleValidator; + this.serviceInstantiationTypeValidator = serviceInstantiationTypeValidator; + this.serviceCategoryValidator = serviceCategoryValidator; + this.serviceValidator = serviceValidator; + this.groupBusinessLogic = groupBusinessLogic; + this.kafkaHandler = kafkaHandler; } @Autowired @@ -632,16 +653,6 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { return Either.left(archiveAudit); } - @VisibleForTesting - public void setServiceValidator(ServiceValidator serviceValidator) { - this.serviceValidator = serviceValidator; - } - - @VisibleForTesting - public void setServiceCategoryValidator(ServiceCategoryValidator serviceCategoryValidator) { - this.serviceCategoryValidator = serviceCategoryValidator; - } - private List> getAuditingFieldsList(List prevVerAuditList) { List> prevVerAudit = new ArrayList<>(); for (AuditingGenericEvent auditEvent : prevVerAuditList) { @@ -661,12 +672,12 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { public Either createService(Service service, User user) { // get user details user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false); - log.debug("User returned from validation: " + user.toString()); + log.debug("User returned from validation: {}", user); // validate user role validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null); service.setCreatorUserId(user.getUserId()); // warn on overridden fields - checkFieldsForOverideAttampt(service); + checkFieldsForOverideAttempt(service); // enrich object log.debug("enrich service with version and state"); service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); @@ -678,10 +689,10 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { if (createServiceResponse.isRight()) { return createServiceResponse; } - return createServiceByDao(service, user).left().bind(c -> updateCatalog(c, ChangeTypeEnum.LIFECYCLE).left().map(r -> (Service) r)); + return createServiceByDao(service, user).left().bind(c -> updateCatalog(c, ChangeTypeEnum.LIFECYCLE).left().map(Service.class::cast)); } - private void checkFieldsForOverideAttampt(Service service) { + private void checkFieldsForOverideAttempt(Service service) { checkComponentFieldsForOverrideAttempt(service); if (service.getDistributionStatus() != null) { log.info("Distribution Status cannot be defined by user. This field will be overridden by the application"); @@ -705,7 +716,9 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { if (service.isSubstituteCandidate() || genericTypeBusinessLogic.hasMandatorySubstitutionType(service)) { final Resource genericType = fetchAndSetDerivedFromGenericType(service); generatePropertiesFromGenericType(service, genericType); - generateAndAddInputsFromGenericTypeProperties(service, genericType); + if (Constants.DEFAULT_MODEL_NAME.equals(service.getModel()) || service.getModel() == null) { + generateAndAddInputsFromGenericTypeProperties(service, genericType); + } } beforeCreate(service); Either dataModelResponse = toscaOperationFacade.createToscaComponent(service); @@ -716,6 +729,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { ASDCKpiApi.countCreatedServicesKPI(); return Either.left(dataModelResponse.left().value()); } + janusGraphDao.rollback(); ResponseFormat responseFormat = componentsUtils .getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE); @@ -786,13 +800,13 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE); throw exp; } - service.setCreatorFullName(user.getFirstName() + " " + user.getLastName()); - service.setContactId(service.getContactId().toLowerCase()); - // Generate invariant UUID - must be here and not in operation since it - - // should stay constant during clone - String invariantUUID = UniqueIdBuilder.buildInvariantUUID(); - service.setInvariantUUID(invariantUUID); + if (!AuditingActionEnum.UPDATE_SERVICE_TOSCA_TEMPLATE.equals(actionEnum) && + !AuditingActionEnum.UPDATE_SERVICE_TOSCA_MODEL.equals(actionEnum)) { + service.setCreatorFullName(user.getFirstName() + " " + user.getLastName()); + service.setContactId(service.getContactId().toLowerCase()); + // Generate invariant UUID - must be here and not in operation since it should stay constant during clone + service.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID()); + } return Either.left(service); } @@ -844,28 +858,49 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId()); return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); } - Either validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate); - if (validationRsponse.isRight()) { + List subNodePropsToBeRemoved = getSubstitutionNodePropertiesToBeRemoved(currentService, serviceUpdate); + List subNodePropsToBeAdded = getSubstitutionNodePropertiesToBeAdded(currentService, serviceUpdate); + boolean subNodeChanged = isSubstitutionNodeChanged(currentService, serviceUpdate); + Either validationResponse = + validateAndUpdateServiceMetadata(user, currentService, serviceUpdate, subNodeChanged, ListUtils.emptyIfNull(subNodePropsToBeRemoved)); + if (validationResponse.isRight()) { log.info("service update metadata: validations field."); - return validationRsponse; + return validationResponse; } - Service serviceToUpdate = validationRsponse.left().value(); + Service serviceToUpdate = validationResponse.left().value(); // lock resource lockComponent(serviceId, currentService, "Update Service Metadata"); try { + if (subNodeChanged) { + if (!subNodePropsToBeRemoved.isEmpty()) { + removePropertiesFromService(currentService, subNodePropsToBeRemoved); + removeInputsFromService(currentService, subNodePropsToBeRemoved); + } + if (!subNodePropsToBeAdded.isEmpty()) { + addPropertiesToService(currentService, subNodePropsToBeAdded); + if (Constants.DEFAULT_MODEL_NAME.equals(currentService.getModel()) || currentService.getModel() == null) { + addInputsToService(currentService, subNodePropsToBeAdded); + } + } + } return toscaOperationFacade.updateToscaElement(serviceToUpdate).right().map(rf -> { janusGraphDao.rollback(); BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata"); log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId()); return (componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); - }).left().bind(c -> updateCatalogAndCommit(c)); + }).left().bind(this::updateCatalogAndCommit); + } catch (ComponentException e) { + janusGraphDao.rollback(); + BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata"); + log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); } finally { graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); } } private Either updateCatalogAndCommit(Service service) { - Either res = updateCatalog(service, ChangeTypeEnum.LIFECYCLE).left().map(s -> (Service) s); + Either res = updateCatalog(service, ChangeTypeEnum.LIFECYCLE).left().map(Service.class::cast); janusGraphDao.commit(); return res; } @@ -1029,9 +1064,18 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { } @VisibleForTesting - Either validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) { + Either validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate, boolean subNodeChanged, + List subNodePropsToBeRemoved) { try { boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion()); + if (subNodeChanged) { + if (!subNodePropsToBeRemoved.isEmpty()) { + areSubstitutionNodePropertiesInUse(currentService, subNodePropsToBeRemoved); + } + currentService.setDerivedFromGenericVersion(serviceUpdate.getDerivedFromGenericVersion()); + currentService.setDerivedFromGenericType(serviceUpdate.getDerivedFromGenericType()); + } + Either response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA); if (response.isRight()) { @@ -1098,6 +1142,168 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { } } + private void addPropertiesToService(Service currentService, List subNodePropsToBeAdded) { + ListUtils.emptyIfNull(subNodePropsToBeAdded).forEach(prop -> { + Either addPropertyEither = + toscaOperationFacade.addPropertyToComponent(prop, currentService); + if (addPropertyEither.isRight()) { + throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); + } + }); + } + + private void addInputsToService(Service currentService, List subNodePropsToBeAdded) { + ListUtils.emptyIfNull(subNodePropsToBeAdded).forEach(prop -> { + InputDefinition inputDef = new InputDefinition(prop); + Either status = + toscaOperationFacade.addInputToComponent(prop.getName(), inputDef, currentService); + if (status.isRight()) { + throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); + } + }); + } + + private void removePropertiesFromService(Service currentService, List subNodePropsToBeRemoved) { + List props = currentService.getProperties(); + List propsUniqueIdsToBeRemoved = + props.stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())).map(PropertyDefinition::getUniqueId) + .collect(Collectors.toList()); + ListUtils.emptyIfNull(props).stream().filter(prop -> propsUniqueIdsToBeRemoved.contains(prop.getUniqueId())).forEach(prop -> { + StorageOperationStatus status = toscaOperationFacade.deletePropertyOfComponent(currentService, prop.getName()); + if (status != StorageOperationStatus.OK) { + throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); + } + }); + } + + private void removeInputsFromService(Service currentService, List subNodePropsToBeRemoved) { + List props = currentService.getProperties(); + List inputs = currentService.getInputs(); + List propsUniqueIdsToBeRemoved = + props.stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())).map(PropertyDefinition::getUniqueId) + .collect(Collectors.toList()); + ListUtils.emptyIfNull(inputs).stream().filter(input -> input.isMappedToComponentProperty() && + (propsUniqueIdsToBeRemoved.contains(input.getPropertyId()) || subNodePropsToBeRemoved.contains(input.getName()))).forEach(input -> { + StorageOperationStatus status = toscaOperationFacade.deleteInputOfResource(currentService, input.getName()); + if (status != StorageOperationStatus.OK) { + throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); + } + }); + } + + private void areSubstitutionNodePropertiesInUse(Service service, List subNodePropsToBeRemoved) { + Map> componentInstancesProps = service.getComponentInstancesProperties(); + List propsUniqueIdsToBeRemoved = + ListUtils.emptyIfNull(service.getProperties()).stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())) + .map(PropertyDefinition::getUniqueId) + .collect(Collectors.toList()); + List inputsUniqueIdsToBeRemoved = ListUtils.emptyIfNull(service.getInputs()).stream() + .filter(input -> propsUniqueIdsToBeRemoved.contains(input.getPropertyId()) || subNodePropsToBeRemoved.contains(input.getName())) + .map(PropertyDefinition::getUniqueId) + .collect(Collectors.toList()); + Map> inUse = new HashMap<>(); + if (componentInstancesProps != null && !componentInstancesProps.isEmpty()) { + componentInstancesProps.forEach((compInstanceId, listOfProps) -> { + List propsInUse = new ArrayList<>(); + listOfProps.stream() + .filter(PropertyDataDefinition::isToscaFunction) + .filter(compProp -> ToscaFunctionType.isGetFunction(compProp.getToscaFunction().getType())) + .forEach(compProp -> { + ToscaFunction toscaFunction = compProp.getToscaFunction(); + ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) toscaFunction; + String propName = toscaGetFunction.getPropertyName(); + String propUniqueId = toscaGetFunction.getPropertyUniqueId(); + if (inputsUniqueIdsToBeRemoved.contains(propUniqueId) || propsUniqueIdsToBeRemoved.contains(propUniqueId) || + subNodePropsToBeRemoved.contains(propName)) { + propsInUse.add(compProp.getName()); + } + }); + if (!propsInUse.isEmpty()) { + Optional componentInstance = service.getComponentInstanceById(compInstanceId); + componentInstance.ifPresent(instance -> inUse.put(instance.getName(), propsInUse)); + } + + }); + } + if (!inUse.isEmpty()) { + String propsInUse = inUse.entrySet().stream().map(entry -> { + String properties = entry.getValue().stream().map(Object::toString).collect(Collectors.joining(", ")); + return properties + " on " + entry.getKey(); + }).collect(Collectors.joining(", properties ")); + throw new ByActionStatusComponentException(ActionStatus.SUBSTITUTION_NODE_TYPE_PROPERTY_IN_USE, propsInUse); + } + } + + + private boolean isSubstitutionNodeChanged(Service currentService, Service updatedService) { + String currentServiceType = currentService.getDerivedFromGenericType(); + String updatedServiceType = updatedService.getDerivedFromGenericType(); + String currentServiceVersion = currentService.getDerivedFromGenericVersion(); + String updatedServiceVersion = updatedService.getDerivedFromGenericVersion(); + return !(StringUtils.equals(currentServiceType, updatedServiceType) && StringUtils.equals(currentServiceVersion, updatedServiceVersion)); + } + + private List getSubstitutionNodePropertiesToBeRemoved(Service currentService, Service serviceUpdate) { + List currentProps = ListUtils.emptyIfNull(fetchDerivedFromGenericType(currentService, null).getProperties()); + List updatedProps = ListUtils.emptyIfNull(fetchDerivedFromGenericType(serviceUpdate, null).getProperties()); + if (!StringUtils.equals(currentService.getDerivedFromGenericType(), serviceUpdate.getDerivedFromGenericType())) { + return currentProps.stream().map(PropertyDefinition::getName).collect(Collectors.toList()); + } + + Map currentPropsMap = currentProps.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop)); + Map updatedPropsMap = updatedProps.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop)); + + List propNamesToBeRemoved = new ArrayList<>(); + for (String currentPropertyName : currentPropsMap.keySet()) { + if (updatedPropsMap.containsKey(currentPropertyName)) { + if (!haveSameType(currentPropsMap.get(currentPropertyName), updatedPropsMap.get(currentPropertyName))) { + propNamesToBeRemoved.add(currentPropertyName); + } + } else { + propNamesToBeRemoved.add(currentPropertyName); + } + } + + return propNamesToBeRemoved; + } + + private boolean haveSameType(final PropertyDefinition property1, final PropertyDefinition property2) { + if (property1.getType().equals("list")) { + return property2.getType().equals("list") && property1.getSchema().equals(property2.getSchema()); + } + if (property1.getType().equals("map")) { + return property2.getType().equals("map") && property1.getSchema().equals(property2.getSchema()); + } + return property1.getType().equals(property2.getType()); + } + + private List getSubstitutionNodePropertiesToBeAdded(Service currentService, Service serviceUpdate) { + List propsInCurrentVersion = ListUtils.emptyIfNull(fetchDerivedFromGenericType(currentService, null).getProperties()); + List propsInUpdatedVersion = ListUtils.emptyIfNull(fetchDerivedFromGenericType(serviceUpdate, null).getProperties()); + if (!StringUtils.equals(currentService.getDerivedFromGenericType(), serviceUpdate.getDerivedFromGenericType())) { + return propsInUpdatedVersion; + } + + Map mapOfPropsInCurrentVersion = propsInCurrentVersion.stream() + .collect(Collectors.toMap(prop -> prop.getName(), prop -> prop)); + Map mapOfPropsInUpdatedVersion = propsInUpdatedVersion.stream() + .collect(Collectors.toMap(prop -> prop.getName(), prop -> prop)); + + List propsToBeAdded = new ArrayList<>(); + for (Entry propertyInUpdatedVersion : mapOfPropsInUpdatedVersion.entrySet()) { + if (mapOfPropsInCurrentVersion.containsKey(propertyInUpdatedVersion.getKey())) { + if (!haveSameType(mapOfPropsInCurrentVersion.get(propertyInUpdatedVersion.getKey()), propertyInUpdatedVersion.getValue())) { + propsToBeAdded.add(propertyInUpdatedVersion.getValue()); + } + } else { + propsToBeAdded.add(propertyInUpdatedVersion.getValue()); + } + } + + return propsToBeAdded; + } + + private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) { if (updatedValue != null && !updatedValue.equals(originalValue)) { log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue); @@ -1301,7 +1507,39 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { return Either.left(serviceRelations); } - public ResponseFormat deleteService(String serviceId, User user) { + public void deleteServiceAllVersions(String serviceId, User user) { + validateUserExists(user); + Either serviceStatus = toscaOperationFacade.getToscaElement(serviceId); + if (serviceStatus.isRight()) { + log.debug("Failed to get service {}", serviceId); + componentException(serviceStatus.right().value()); + } + Service service = serviceStatus.left().value(); + if (Boolean.FALSE.equals(service.isArchived())) { + log.debug("The service, {}, requested for delete has not been archived.", serviceId); + throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, serviceId); + } + List deletedServiceList = new ArrayList<>(); + try { + String model = service.getModel(); + final Optional modelOptional = modelOperation.findModelByName(model); + deletedServiceList = toscaOperationFacade.deleteService(service.getInvariantUUID(), true); + if (log.isDebugEnabled()) { + deletedServiceList.forEach(deletedS -> log.debug("Component {} was deleted.", deletedS)); + } + if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) { + modelOperation.deleteModel(modelOptional.get(), false); + } + toscaOperationFacade.commitAndCheck(service.getUniqueId()); + updateCatalog(service, ChangeTypeEnum.DELETE); + } catch (ComponentException exception) { + log.debug("Failed to delete service, {}, in ServiceServlet", serviceId); + janusGraphDao.rollback(); + throw exception; + } + } + + public ResponseFormat markServiceForDeletion(String serviceId, User user) { ResponseFormat responseFormat; validateUserExists(user); Either serviceStatus = toscaOperationFacade.getToscaElement(serviceId); @@ -1446,7 +1684,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { Boolean isServiceApi) { ArtifactDefinition artifactInfo = artifactsBusinessLogic .createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL); - if (isServiceApi) { + if (Boolean.TRUE.equals(isServiceApi)) { artifactInfo.setMandatory(false); artifactInfo.setServiceApi(true); } @@ -1500,14 +1738,16 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName); envName = configuredEnvName; } - // DE194021 - ServletContext servletContext = request.getSession().getServletContext(); - boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE - if (!isDistributionEngineUp) { - BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN"); - log.debug("Distribution Engine is DOWN"); - response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); - return Either.right(response); + if (!kafkaHandler.isKafkaActive()) { + // DE194021 + ServletContext servletContext = request.getSession().getServletContext(); + boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE + if (!isDistributionEngineUp) { + BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN"); + log.debug("Distribution Engine is DOWN"); + response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(response); + } } Either serviceRes = toscaOperationFacade.getToscaElement(serviceId); if (serviceRes.isRight()) { @@ -1519,7 +1759,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { return Either.right(response); } Service service = serviceRes.left().value(); - if (service.isArchived()) { + if (Boolean.TRUE.equals(service.isArchived())) { log.info("Component is archived. Component id: {}", serviceId); return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName())); } @@ -1621,123 +1861,6 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { return asList; } - private List collectGroupsInstanceForCompInstance(ComponentInstance currVF) { - Map deploymentArtifacts = currVF.getDeploymentArtifacts(); - if (currVF.getGroupInstances() != null) { - currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts)); - } - return currVF.getGroupInstances(); - } - - private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper payloadWrapper, - Wrapper responseWrapper) { - ArtifactDefinition vfModuleAertifact = null; - if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) { - final Optional optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream() - .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType())).findAny(); - if (optionalVfModuleArtifact.isPresent()) { - vfModuleAertifact = optionalVfModuleArtifact.get(); - } - } - if (vfModuleAertifact == null) { - Either createVfModuleArtifact = createVfModuleArtifact(currVF, service, - payloadWrapper.getInnerElement()); - if (createVfModuleArtifact.isLeft()) { - vfModuleAertifact = createVfModuleArtifact.left().value(); - } else { - responseWrapper.setInnerElement(createVfModuleArtifact.right().value()); - } - } - return vfModuleAertifact; - } - - private void fillVfModuleInstHeatEnvPayload(List groupsForCurrVF, Wrapper payloadWrapper) { - List vfModulePayloads = new ArrayList<>(); - if (groupsForCurrVF != null) { - for (GroupInstance groupInstance : groupsForCurrVF) { - VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance); - vfModulePayloads.add(modulePayload); - } - vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName); - final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - String vfModulePayloadString = gson.toJson(vfModulePayloads); - payloadWrapper.setInnerElement(vfModulePayloadString); - } - } - - private Either generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, - Service service, boolean shouldLock, boolean inTransaction) { - ArtifactDefinition vfModuleArtifact = null; - Wrapper responseWrapper = new Wrapper<>(); - Wrapper payloadWrapper = new Wrapper<>(); - List groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance); - if (responseWrapper.isEmpty()) { - fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper); - } - if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) { - vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper); - } - if (responseWrapper.isEmpty() && vfModuleArtifact != null) { - vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, - responseWrapper, service); - } - Either result; - if (responseWrapper.isEmpty()) { - result = Either.left(vfModuleArtifact); - } else { - result = Either.right(responseWrapper.getInnerElement()); - } - return result; - } - - private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, - boolean inTransaction, Wrapper payloadWrapper, Wrapper responseWrapper, - Service service) { - ArtifactDefinition result = null; - Either eitherPayload = artifactsBusinessLogic - .generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, - inTransaction, System::currentTimeMillis, () -> Either.left( - artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), - currVF.getUniqueId()); - if (eitherPayload.isLeft()) { - result = eitherPayload.left().value(); - } else { - responseWrapper.setInnerElement(eitherPayload.right().value()); - } - if (result == null) { - result = vfModuleArtifact; - } - return result; - } - - private Either createVfModuleArtifact(ComponentInstance currVF, Service service, - String vfModulePayloadString) { - ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition(); - String newCheckSum = null; - vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact"); - vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata"); - vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType()); - vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); - vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata"); - vfModuleArtifactDefinition.setTimeout(0); - vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json"); - vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString); - if (vfModulePayloadString != null) { - newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes()); - } - vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum); - Either addArtifactToComponent = artifactToscaOperation - .addArtifactToComponent(vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId()); - Either result; - if (addArtifactToComponent.isLeft()) { - result = Either.left(addArtifactToComponent.left().value()); - } else { - result = Either - .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value()))); - } - return result; - } - public Either generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) { Function>> artifactTaskGeneratorCreator = resourceInstance -> // Get All Deployment Artifacts @@ -2026,7 +2149,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e); actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); } finally { - if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) { + if (lockResult != null && lockResult.isLeft() && Boolean.TRUE.equals(lockResult.left().value())) { graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service); } } @@ -2196,7 +2319,8 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { } Service service = serviceResultEither.left().value(); if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) { - ListUtils.emptyIfNull(service.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input))); + ListUtils.emptyIfNull(service.getInputs()).stream().filter(input -> CollectionUtils.isEmpty(input.getConstraints())) + .forEach(input -> input.setConstraints(setInputConstraint(input))); } UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn); return Either.left(dataTransfer); @@ -2208,35 +2332,24 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { } public boolean isServiceExist(String serviceName) { - Either latestByName = toscaOperationFacade.getLatestByServiceName(serviceName); - return latestByName.isLeft(); + return toscaOperationFacade.getLatestByServiceName(serviceName).isLeft(); } - abstract class ArtifactGenerator implements Callable> { + interface ArtifactGenerator extends Callable> { } @Getter - class HeatEnvArtifactGenerator extends ArtifactGenerator { + @AllArgsConstructor(access = AccessLevel.PRIVATE) + class HeatEnvArtifactGenerator implements ArtifactGenerator { private ArtifactDefinition artifactDefinition; private Service service; private String resourceInstanceName; private User modifier; - private String instanceId; private boolean shouldLock; private boolean inTransaction; - - HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, - boolean shouldLock, boolean inTransaction, String instanceId) { - this.artifactDefinition = artifactDefinition; - this.service = service; - this.resourceInstanceName = resourceInstanceName; - this.modifier = modifier; - this.shouldLock = shouldLock; - this.instanceId = instanceId; - this.inTransaction = inTransaction; - } + private String instanceId; @Override public Either call() throws Exception { @@ -2246,22 +2359,128 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { } } - class VfModuleArtifactGenerator extends ArtifactGenerator { + @AllArgsConstructor(access = AccessLevel.PRIVATE) + class VfModuleArtifactGenerator implements ArtifactGenerator { - boolean shouldLock; - boolean inTransaction; private User user; private ComponentInstance componentInstance; private Service service; + private boolean shouldLock; + private boolean inTransaction; + + private Either generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, + Service service, boolean shouldLock, + boolean inTransaction) { + ArtifactDefinition vfModuleArtifact = null; + Wrapper responseWrapper = new Wrapper<>(); + Wrapper payloadWrapper = new Wrapper<>(); + List groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance); + if (responseWrapper.isEmpty()) { + fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper); + } + if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) { + vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper); + } + if (responseWrapper.isEmpty() && vfModuleArtifact != null) { + vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, + responseWrapper, service); + } + if (responseWrapper.isEmpty()) { + return Either.left(vfModuleArtifact); + } else { + return Either.right(responseWrapper.getInnerElement()); + } + } + + private void fillVfModuleInstHeatEnvPayload(List groupsForCurrVF, Wrapper payloadWrapper) { + List vfModulePayloads = new ArrayList<>(); + if (groupsForCurrVF != null) { + for (GroupInstance groupInstance : groupsForCurrVF) { + VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance); + vfModulePayloads.add(modulePayload); + } + vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName); + final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + String vfModulePayloadString = gson.toJson(vfModulePayloads); + payloadWrapper.setInnerElement(vfModulePayloadString); + } + } + + private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper payloadWrapper, + Wrapper responseWrapper) { + ArtifactDefinition vfModuleAertifact = null; + if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) { + final Optional optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream() + .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType())).findAny(); + if (optionalVfModuleArtifact.isPresent()) { + vfModuleAertifact = optionalVfModuleArtifact.get(); + } + } + if (vfModuleAertifact == null) { + Either createVfModuleArtifact = createVfModuleArtifact(currVF, service, + payloadWrapper.getInnerElement()); + if (createVfModuleArtifact.isLeft()) { + vfModuleAertifact = createVfModuleArtifact.left().value(); + } else { + responseWrapper.setInnerElement(createVfModuleArtifact.right().value()); + } + } + return vfModuleAertifact; + } + + private List collectGroupsInstanceForCompInstance(ComponentInstance currVF) { + if (currVF.getGroupInstances() != null) { + currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(currVF.getDeploymentArtifacts())); + } + return currVF.getGroupInstances(); + } - private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, - boolean inTransaction) { - super(); - this.user = user; - this.componentInstance = componentInstance; - this.service = service; - this.shouldLock = shouldLock; - this.inTransaction = inTransaction; + private Either createVfModuleArtifact(ComponentInstance currVF, Service service, + String vfModulePayloadString) { + ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition(); + String newCheckSum = null; + vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact"); + vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata"); + vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType()); + vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); + vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata"); + vfModuleArtifactDefinition.setTimeout(0); + vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json"); + vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString); + if (vfModulePayloadString != null) { + newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes()); + } + vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum); + Either addArtifactToComponent = artifactToscaOperation + .addArtifactToComponent(vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId()); + if (addArtifactToComponent.isLeft()) { + return Either.left(addArtifactToComponent.left().value()); + } else { + return Either + .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value()))); + } + } + + private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, + boolean shouldLock, + boolean inTransaction, Wrapper payloadWrapper, Wrapper responseWrapper, + Service service) { + ArtifactDefinition result = null; + Either eitherPayload = artifactsBusinessLogic + .generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, + inTransaction, System::currentTimeMillis, () -> Either.left( + artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, + payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), + currVF.getUniqueId()); + if (eitherPayload.isLeft()) { + result = eitherPayload.left().value(); + } else { + responseWrapper.setInnerElement(eitherPayload.right().value()); + } + if (result == null) { + result = vfModuleArtifact; + } + return result; } @Override