diff options
Diffstat (limited to 'catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java')
-rw-r--r-- | catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java | 1768 |
1 files changed, 1768 insertions, 0 deletions
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 new file mode 100644 index 0000000000..6bbe88f30c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java @@ -0,0 +1,1768 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.components.impl; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine; +import org.openecomp.sdc.be.components.distribution.engine.INotificationData; +import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.GroupTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.DistributionTransitionEnum; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent; +import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent; +import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent; +import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.kpi.api.ASDCKpiApi; +import org.openecomp.sdc.common.util.ThreadLocalsHolder; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.context.WebApplicationContext; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +@org.springframework.stereotype.Component("serviceBusinessLogic") +public class ServiceBusinessLogic extends ComponentBusinessLogic { + + private static final String STATUS_SUCCESS_200 = "200"; + + private static final String STATUS_DEPLOYED = "DEPLOYED"; + + @Autowired + private IElementOperation elementDao; + + @Autowired + private IDistributionEngine distributionEngine; + + // @Autowired + // private AuditingDao auditingDao; + + @Autowired + private AuditCassandraDao auditCassandraDao; + + @Autowired + private ServiceComponentInstanceBusinessLogic serviceComponentInstanceBusinessLogic; + + @Autowired + private ICacheMangerOperation cacheManagerOperation; + + private static Logger log = LoggerFactory.getLogger(ServiceBusinessLogic.class.getName()); + private static final String INITIAL_VERSION = "0.1"; + + public ServiceBusinessLogic() { + log.debug("ServiceBusinessLogic started"); + } + + public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) { + + Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "change Service Distribution State", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + log.debug("check request state"); + Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state, user); + if (validateEnum.isRight()) { + return Either.right(validateEnum.right().value()); + } + DistributionTransitionEnum distributionTransition = validateEnum.left().value(); + AuditingActionEnum auditAction = (distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT); + Either<String, ResponseFormat> commentResponse = validateComment(commentObj, user, auditAction); + if (commentResponse.isRight()) { + return Either.right(commentResponse.right().value()); + } + String comment = commentResponse.left().value(); + + Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment); + if (validateService.isRight()) { + return Either.right(validateService.right().value()); + } + Service service = validateService.left().value(); + DistributionStatusEnum initState = service.getDistributionStatus(); + + Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment); + if (validateUser.isRight()) { + return Either.right(validateUser.right().value()); + } + user = validateUser.left().value(); + + // lock resource + /* + * StorageOperationStatus lockResult = graphLockOperation.lockComponent(serviceId, NodeTypeEnum.Service); if (!lockResult.equals(StorageOperationStatus.OK)) { BeEcompErrorManager.getInstance().processEcompError(EcompErrorName. + * BeFailedLockObjectError, "ChangeServiceDistributionState"); log.debug("Failed to lock service {} error - {}", serviceId, lockResult); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, + * service.getVersion(), service.getServiceName()); + * + * createAudit(user, auditAction, comment, service, responseFormat); return Either.right(componentsUtils.getResponseFormat(ActionStatus. GENERAL_ERROR)); } + */ + Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState"); + if (lockResult.isRight()) { + ResponseFormat responseFormat = lockResult.right().value(); + createAudit(user, auditAction, comment, service, responseFormat); + return Either.right(responseFormat); + } + + try { + + DistributionStatusEnum newState; + if (distributionTransition == DistributionTransitionEnum.APPROVE) { + newState = DistributionStatusEnum.DISTRIBUTION_APPROVED; + } else { + newState = DistributionStatusEnum.DISTRIBUTION_REJECTED; + } + Either<Service, StorageOperationStatus> result = serviceOperation.updateDestributionStatus(service, user, newState); + if (result.isRight()) { + titanGenericDao.rollback(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "ChangeServiceDistributionState"); + BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState"); + log.debug("service {} is change destribuation status failed", service.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName()); + createAudit(user, auditAction, comment, service, responseFormat); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + titanGenericDao.commit(); + Service updatedService = result.left().value(); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, updatedService.getDistributionStatus().name()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, initState.name()); + createAudit(user, auditAction, comment, updatedService, responseFormat, auditingFields); + return Either.left(result.left().value()); + + } finally { + graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); + } + + } + + public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) { + Either<User, ResponseFormat> resp = validateUserExists(userId, "get Component Audit Records", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either<List<Map<String, Object>>, ActionStatus> result; + try { + + // Certified Version + if (componentVersion.endsWith(".0")) { + Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID); + if (eitherAuditingForCertified.isLeft()) { + result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value())); + } else { + result = Either.right(eitherAuditingForCertified.right().value()); + } + } + // Uncertified Version + else { + result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion); + } + } catch (Exception e) { + log.debug("get Audit Records failed with exception {}", e); + result = Either.right(ActionStatus.GENERAL_ERROR); + } + + if (result.isRight()) { + return Either.right(componentsUtils.getResponseFormat(result.right().value())); + } else { + return Either.left(result.left().value()); + } + + } + + private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) { + // First Query + Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion); + + if (eitherprevVerAudit.isRight()) { + return Either.right(eitherprevVerAudit.right().value()); + } + + // Second Query + Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion); + if (eitherCurrVerAudit.isRight()) { + return Either.right(eitherCurrVerAudit.right().value()); + } + + List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value()); + List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value()); + + List<Map<String, Object>> duplicateElements = new ArrayList<Map<String, Object>>(); + duplicateElements.addAll(prevVerAuditList); + duplicateElements.retainAll(currVerAuditList); + + List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<Map<String, Object>>(); + joinedNonDuplicatedList.addAll(prevVerAuditList); + joinedNonDuplicatedList.removeAll(duplicateElements); + joinedNonDuplicatedList.addAll(currVerAuditList); + + return Either.left(joinedNonDuplicatedList); + } + + private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) { + + List<Map<String, Object>> prevVerAudit = new ArrayList<Map<String, Object>>(); + for (AuditingGenericEvent auditEvent : prevVerAuditList) { + auditEvent.fillFields(); + prevVerAudit.add(auditEvent.getFields()); + } + return prevVerAudit; + } + + /** + * createService + * + * @param service + * - Service + * @param user + * - modifier data (userId) + * @return Either<Service, responseFormat> + */ + public Either<Service, ResponseFormat> createService(Service service, User user) { + + // get user details + Either<User, ResponseFormat> eitherCreator = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + // validate user role + Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, new ArrayList<Role>(), AuditingActionEnum.CREATE_RESOURCE, null); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + service.setCreatorUserId(user.getUserId()); + + // warn on overridden fields + checkFieldsForOverideAttampt(service); + // enrich object + log.debug("enrich service with version and state"); + service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + service.setVersion(INITIAL_VERSION); + service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE); + if (createServiceResponse.isRight()) { + return createServiceResponse; + } + return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, serviceOperation, user); + } + + private void checkFieldsForOverideAttampt(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"); + } + } + + private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, IServiceOperation dataModel, User user) { + log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + + Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service"); + if (lockResult.isRight()) { + ResponseFormat responseFormat = lockResult.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + return Either.right(responseFormat); + } + + log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult); + + try { + + createMandatoryArtifactsData(service, user); + createServiceApiArtifactsData(service, user); + setToscaArtifactsPlaceHolders(service, user); + + Either<Service, StorageOperationStatus> dataModelResponse = dataModel.createService(service); + + // service created successfully!!! + if (dataModelResponse.isLeft()) { + log.debug("Service created successfully!!!"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + ASDCKpiApi.countCreatedServicesKPI(); + + Service createdService = dataModelResponse.left().value(); + // //add service to cache + // cacheManagerOperation.updateComponentInCache(createdService.getUniqueId(), + // createdService.getLastUpdateDate(), NodeTypeEnum.Service); + + return Either.left(dataModelResponse.left().value()); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE); + log.debug("audit before sending response"); + componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + return Either.right(responseFormat); + + } finally { + graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service); + } + } + + private void createServiceApiArtifactsData(Service service, User user) { + // create mandatory artifacts + + // TODO it must be removed after that artifact uniqueId creation will be + // moved to ArtifactOperation + // String serviceUniqueId = + // UniqueIdBuilder.buildServiceUniqueId(service.getComponentMetadataDefinition().getMetadataDataDefinition().getName(), + // service.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion()); + String serviceUniqueId = service.getUniqueId(); + Map<String, ArtifactDefinition> artifactMap = service.getArtifacts(); + if (artifactMap == null) + artifactMap = new HashMap<String, ArtifactDefinition>(); + + Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts(); + List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory(); + + List<CategoryDefinition> categories = service.getCategories(); + boolean isCreateArtifact = true; + if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) { + for (String exlude : exludeServiceCategory) { + if (exlude.equalsIgnoreCase(categories.get(0).getName())) { + isCreateArtifact = false; + break; + } + } + + } + + if (serviceApiArtifacts != null && isCreateArtifact) { + Set<String> keys = serviceApiArtifacts.keySet(); + for (String serviceApiArtifactName : keys) { + Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName); + ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true); + artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API); + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + } + + service.setArtifacts(artifactMap); + } + } + + private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) { + + Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum); + if (validationResponse.isRight()) { + return Either.right(validationResponse.right().value()); + } + 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); + + return Either.left(service); + } + + private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) { + Either<Boolean, ResponseFormat> componentsFieldsValidation = validateComponentFieldsBeforeCreate(user, service, actionEnum); + if (componentsFieldsValidation.isRight()) { + return componentsFieldsValidation; + } + + // validate service name uniqueness + log.debug("validate service name uniqueness"); + Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum); + if (serviceNameUniquenessValidation.isRight()) { + return serviceNameUniquenessValidation; + } + + // validate category + log.debug("validate category"); + Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum); + if (categoryValidation.isRight()) { + return categoryValidation; + } + + log.debug("validate projectName"); + Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum); + if (projectCodeValidation.isRight()) { + return projectCodeValidation; + } + + return Either.left(true); + + } + + private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) { + log.debug("validate Service category"); + + if (service.getCategories() == null || service.getCategories().size() == 0) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue()); + componentsUtils.auditComponentAdmin(errorResponse, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + return Either.right(errorResponse); + } + + Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories()); + if (validatCategory.isRight()) { + ResponseFormat responseFormat = validatCategory.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + return Either.right(responseFormat); + } + + return Either.left(true); + } + + public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) { + + Either<User, ResponseFormat> resp = validateUserExists(userId, "validate Service Name Exists", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either<Boolean, StorageOperationStatus> dataModelResponse = serviceOperation.validateServiceNameExists(serviceName); + + if (dataModelResponse.isLeft()) { + Map<String, Boolean> result = new HashMap<>(); + result.put("isValid", dataModelResponse.left().value()); + log.debug("validation was successfully performed."); + return Either.left(result); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value())); + + return Either.right(responseFormat); + } + + public void setElementDao(IElementOperation elementDao) { + this.elementDao = elementDao; + } + + public void setServiceOperation(ServiceOperation serviceOperation) { + this.serviceOperation = serviceOperation; + } + + public void setCassandraAuditingDao(AuditCassandraDao auditingDao) { + this.auditCassandraDao = auditingDao; + } + + /* + * public void setUserAdmin(UserAdminBuisinessLogic userAdmin) { this.userAdmin = userAdmin; } + * + * public void setComponentsUtils(ComponentsUtils componentsUtils) { this.componentsUtils = componentsUtils; } + * + * public void setGraphLockOperation(IGraphLockOperation graphLockOperation) { this.graphLockOperation = graphLockOperation; } + */ + + public ArtifactsBusinessLogic getArtifactBl() { + return artifactsBusinessLogic; + } + + public void setArtifactBl(ArtifactsBusinessLogic artifactBl) { + this.artifactsBusinessLogic = artifactBl; + } + + public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) { + Either<User, ResponseFormat> eitherCreator = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + // validate user role + Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, serviceUpdate, new ArrayList<Role>(), null, null); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + + Either<Service, StorageOperationStatus> storageStatus = serviceOperation.getService(serviceId); + if (storageStatus.isRight()) { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "")); + } + + Service currentService = storageStatus.left().value(); + + if (!ComponentValidationUtils.canWorkOnService(currentService.getUniqueId(), serviceOperation, user.getUserId())) { + log.info("Restricted operation for user {} on service {}", user.getUserId(), currentService.getCreatorUserId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate); + if (validationRsponse.isRight()) { + log.info("service update metadata: validations field."); + return validationRsponse; + } + Service serviceToUpdate = validationRsponse.left().value(); + // lock resource + + Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata"); + if (lockResult.isRight()) { + return Either.right(lockResult.right().value()); + } + try { + Either<Service, StorageOperationStatus> updateResponse = serviceOperation.updateService(serviceToUpdate, true); + if (updateResponse.isRight()) { + titanGenericDao.rollback(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Update Service Metadata"); + BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata"); + log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + titanGenericDao.commit(); + return Either.left(updateResponse.left().value()); + } finally { + graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); + } + } + + private Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) { + + boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion()); + Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + String creatorUserIdUpdated = serviceUpdate.getCreatorUserId(); + String creatorUserIdCurrent = currentService.getCreatorUserId(); + if (creatorUserIdUpdated != null && !creatorUserIdCurrent.equals(creatorUserIdUpdated)) { + log.info("update srvice: recived request to update creatorUserId to {} the field is not updatable ignoring.", creatorUserIdUpdated); + } + + String creatorFullNameUpdated = serviceUpdate.getCreatorFullName(); + String creatorFullNameCurrent = currentService.getCreatorFullName(); + if (creatorFullNameUpdated != null && !creatorFullNameCurrent.equals(creatorFullNameUpdated)) { + log.info("update srvice: recived request to update creatorFullName to {} the field is not updatable ignoring.", creatorFullNameUpdated); + } + + String lastUpdaterUserIdUpdated = serviceUpdate.getLastUpdaterUserId(); + String lastUpdaterUserIdCurrent = currentService.getLastUpdaterUserId(); + if (lastUpdaterUserIdUpdated != null && !lastUpdaterUserIdCurrent.equals(lastUpdaterUserIdUpdated)) { + log.info("update srvice: recived request to update lastUpdaterUserId to {} the field is not updatable ignoring.", lastUpdaterUserIdUpdated); + } + + String lastUpdaterFullNameUpdated = serviceUpdate.getLastUpdaterFullName(); + String lastUpdaterFullNameCurrent = currentService.getLastUpdaterFullName(); + if (lastUpdaterFullNameUpdated != null && !lastUpdaterFullNameCurrent.equals(lastUpdaterFullNameUpdated)) { + log.info("update srvice: recived request to update lastUpdaterFullName to {} the field is not updatable ignoring.", lastUpdaterFullNameUpdated ); + } + + response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + DistributionStatusEnum distributionStatusUpdated = serviceUpdate.getDistributionStatus(); + DistributionStatusEnum distributionStatusCurrent = currentService.getDistributionStatus(); + if (distributionStatusUpdated != null && !distributionStatusUpdated.name().equals((distributionStatusCurrent != null ? distributionStatusCurrent.name() : null))) { + log.info("update srvice: recived request to update distributionStatus to {} the field is not updatable ignoring.", distributionStatusUpdated); + } + + if (serviceUpdate.getProjectCode() != null) { + response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + } + + response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + Long creationDateUpdated = serviceUpdate.getCreationDate(); + Long creationDateCurrent = currentService.getCreationDate(); + if (creationDateUpdated != null && !creationDateCurrent.equals(creationDateUpdated)) { + log.info("update srvice: recived request to update creationDate to {} the field is not updatable ignoring.", creationDateUpdated); + } + + String versionUpdated = serviceUpdate.getVersion(); + String versionCurrent = currentService.getVersion(); + if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) { + log.info("update srvice: recived request to update version to {} the field is not updatable ignoring.", versionUpdated); + } + + response = validateAndUpdateDescription(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateTags(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateContactId(user, currentService, serviceUpdate, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + Long lastUpdateDateUpdated = serviceUpdate.getLastUpdateDate(); + Long lastUpdateDateCurrent = currentService.getLastUpdateDate(); + if (lastUpdateDateUpdated != null && !lastUpdateDateCurrent.equals(lastUpdateDateUpdated)) { + log.info("update srvice: recived request to update lastUpdateDate to {} the field is not updatable ignoring.", lastUpdateDateUpdated); + } + + LifecycleStateEnum lifecycleStateUpdated = serviceUpdate.getLifecycleState(); + LifecycleStateEnum lifecycleStateCurrent = currentService.getLifecycleState(); + if (lifecycleStateUpdated != null && !lifecycleStateCurrent.name().equals(lifecycleStateUpdated.name())) { + log.info("update srvice: recived request to update lifecycleState to {} the field is not updatable ignoring.", lifecycleStateUpdated); + } + + Boolean isHighestVersionUpdated = serviceUpdate.isHighestVersion(); + Boolean isHighestVersionCurrent = currentService.isHighestVersion(); + if (isHighestVersionUpdated != null && !isHighestVersionCurrent.equals(isHighestVersionUpdated)) { + log.info("update srvice: recived request to update isHighestVersion to {} the field is not updatable ignoring.", isHighestVersionUpdated); + } + + String uuidUpdated = serviceUpdate.getUUID(); + String uuidCurrent = currentService.getUUID(); + if (!uuidCurrent.equals(uuidUpdated)) { + log.info("update srvice: recived request to update uuid to {} the field is not updatable ignoring.", uuidUpdated); + } + + String currentInvariantUuid = currentService.getInvariantUUID(); + String updatedInvariantUuid = serviceUpdate.getInvariantUUID(); + + if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) { + log.warn("Product invariant UUID is automatically set and cannot be updated"); + serviceUpdate.setInvariantUUID(currentInvariantUuid); + } + return Either.left(currentService); + + } + + private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) { + String contactIdUpdated = serviceUpdate.getContactId(); + String contactIdCurrent = currentService.getContactId(); + if (!contactIdCurrent.equals(contactIdUpdated)) { + Either<Boolean, ResponseFormat> validatContactId = validateContactId(user, serviceUpdate, audatingAction); + if (validatContactId.isRight()) { + ResponseFormat errorRespons = validatContactId.right().value(); + return Either.right(errorRespons); + } + currentService.setContactId(contactIdUpdated.toLowerCase()); + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + List<String> tagsUpdated = serviceUpdate.getTags(); + List<String> tagsCurrent = currentService.getTags(); + if (tagsUpdated == null || tagsUpdated.isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS); + componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, "", "", audatingAction, ComponentTypeEnum.SERVICE); + return Either.right(responseFormat); + } + + if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) { + Either<Boolean, ResponseFormat> validatResponse = validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction); + if (validatResponse.isRight()) { + ResponseFormat errorRespons = validatResponse.right().value(); + return Either.right(errorRespons); + } + currentService.setTags(tagsUpdated); + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + String descriptionUpdated = serviceUpdate.getDescription(); + String descriptionCurrent = currentService.getDescription(); + if (!descriptionCurrent.equals(descriptionUpdated)) { + Either<Boolean, ResponseFormat> validateDescriptionResponse = validateDescriptionAndCleanup(user, serviceUpdate, audatingAction); + if (validateDescriptionResponse.isRight()) { + ResponseFormat errorRespons = validateDescriptionResponse.right().value(); + return Either.right(errorRespons); + } + currentService.setDescription(serviceUpdate.getDescription()); + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) { + String projectCodeUpdated = serviceUpdate.getProjectCode(); + String projectCodeCurrent = currentService.getProjectCode(); + if (!projectCodeCurrent.equals(projectCodeUpdated)) { + Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction); + if (validatProjectCodeResponse.isRight()) { + ResponseFormat errorRespons = validatProjectCodeResponse.right().value(); + return Either.right(errorRespons); + } + currentService.setProjectCode(projectCodeUpdated); + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + String iconUpdated = serviceUpdate.getIcon(); + String iconCurrent = currentService.getIcon(); + if (!iconCurrent.equals(iconUpdated)) { + if (!hasBeenCertified) { + Either<Boolean, ResponseFormat> validatIconResponse = validateIcon(user, serviceUpdate, audatingAction); + if (validatIconResponse.isRight()) { + ResponseFormat errorRespons = validatIconResponse.right().value(); + return Either.right(errorRespons); + } + currentService.setIcon(iconUpdated); + } else { + log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + String serviceNameUpdated = serviceUpdate.getName(); + String serviceNameCurrent = currentService.getName(); + if (!serviceNameCurrent.equals(serviceNameUpdated)) { + if (!hasBeenCertified) { + Either<Boolean, ResponseFormat> validatServiceNameResponse = validateComponentName(user, serviceUpdate, audatingAction); + if (validatServiceNameResponse.isRight()) { + ResponseFormat errorRespons = validatServiceNameResponse.right().value(); + return Either.right(errorRespons); + } + + Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, audatingAction); + if (serviceNameUniquenessValidation.isRight()) { + return serviceNameUniquenessValidation; + } + currentService.setName(serviceNameUpdated); + currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated)); + currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated)); + + } else { + log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories(); + List<CategoryDefinition> categoryCurrent = currentService.getCategories(); + Either<Boolean, ResponseFormat> validatCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction); + if (validatCategoryResponse.isRight()) { + ResponseFormat errorRespons = validatCategoryResponse.right().value(); + return Either.right(errorRespons); + } + if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) { + if (!hasBeenCertified) { + currentService.setCategories(categoryUpdated); + } else { + log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + + } + + public Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) { + if (list != null) { + if (list.size() > 1) { + log.debug("Must be only one category for service"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue()); + return Either.right(responseFormat); + } + CategoryDefinition category = list.get(0); + if (category.getSubcategories() != null) { + log.debug("Subcategories cannot be defined for service"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY); + return Either.right(responseFormat); + } + if (!ValidationUtils.validateStringNotEmpty(category.getName())) { + log.debug("Resource category is empty"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue()); + return Either.right(responseFormat); + } + + log.debug("validating service category {} against valid categories list", list); + Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories(); + if (categorys.isRight()) { + log.debug("failed to retrive service categories from Titan"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value()); + return Either.right(responseFormat); + } + List<CategoryDefinition> categoryList = categorys.left().value(); + for (CategoryDefinition value : categoryList) { + if (value.getName().equals(category.getName())) { + return Either.left(true); + } + } + log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue())); + } + return Either.left(false); + } + + public ResponseFormat deleteService(String serviceId, User user) { + ResponseFormat responseFormat; + String ecompErrorContext = "delete service"; + + Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false); + if (eitherCreator.isRight()) { + return eitherCreator.right().value(); + } + user = eitherCreator.left().value(); + + Either<Service, StorageOperationStatus> serviceStatus = serviceOperation.getService(serviceId); + if (serviceStatus.isRight()) { + log.debug("failed to get service {}", serviceId); + return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), ""); + } + + Service service = serviceStatus.left().value(); + + StorageOperationStatus result = StorageOperationStatus.OK; + Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete"); + if (lockResult.isRight()) { + result = StorageOperationStatus.GENERAL_ERROR; + return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + } + + try { + + result = markComponentToDelete(service); + if (result.equals(StorageOperationStatus.OK)) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT); + } else { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result); + responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName()); + } + return responseFormat; + + } finally { + if (result == null || !result.equals(StorageOperationStatus.OK)) { + log.warn("operation failed. do rollback"); + BeEcompErrorManager.getInstance().logBeSystemError("Delete Service"); + titanGenericDao.rollback(); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); + } + } + + public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) { + ResponseFormat responseFormat; + String ecompErrorContext = "delete service"; + Either<User, ResponseFormat> validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext); + if (validateEmptyResult.isRight()) { + return validateEmptyResult.right().value(); + } + + Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false); + if (eitherCreator.isRight()) { + return eitherCreator.right().value(); + } + user = eitherCreator.left().value(); + + Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId()); + if (getResult.isRight()) { + return getResult.right().value(); + } + Service service = getResult.left().value(); + + StorageOperationStatus result = StorageOperationStatus.OK; + Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete"); + if (lockResult.isRight()) { + result = StorageOperationStatus.GENERAL_ERROR; + return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + } + + try { + result = markComponentToDelete(service); + if (result.equals(StorageOperationStatus.OK)) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT); + } else { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result); + responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName()); + } + return responseFormat; + + } finally { + if (result == null || !result.equals(StorageOperationStatus.OK)) { + log.warn("operation failed. do rollback"); + BeEcompErrorManager.getInstance().logBeSystemError("Delete Service"); + titanGenericDao.rollback(); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service); + } + } + + public Either<Service, ResponseFormat> getService(String serviceId, User user) { + String ecompErrorContext = "Get service"; + Either<User, ResponseFormat> validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext); + if (validateEmptyResult.isRight()) { + return Either.right(validateEmptyResult.right().value()); + } + + Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + Either<Service, StorageOperationStatus> storageStatus = serviceOperation.getService(serviceId); + if (storageStatus.isRight()) { + log.debug("failed to get service by id {}", serviceId); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId)); + } + // Service service = + // createServiceApiArtifactLIst(storageStatus.left().value()); + Service service = storageStatus.left().value(); + return Either.left(service); + } + + public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) { + Either<User, ResponseFormat> resp = validateUserExists(userId, "get Service By Name And Version", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either<Service, StorageOperationStatus> storageStatus = serviceOperation.getServiceByNameAndVersion(serviceName, serviceVersion, null, false); + if (storageStatus.isRight()) { + log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName)); + } + Service service = storageStatus.left().value(); + return Either.left(service); + } + + private void createMandatoryArtifactsData(Service service, User user) { + // create mandatory artifacts + + // TODO it must be removed after that artifact uniqueId creation will be + // moved to ArtifactOperation + // String serviceUniqueId = + // UniqueIdBuilder.buildServiceUniqueId(service.getComponentMetadataDefinition().getMetadataDataDefinition().getName(), + // service.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion()); + String serviceUniqueId = service.getUniqueId(); + Map<String, ArtifactDefinition> artifactMap = service.getArtifacts(); + if (artifactMap == null) + artifactMap = new HashMap<String, ArtifactDefinition>(); + + Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts(); + List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory(); + + String category = service.getCategories().get(0).getName(); + boolean isCreateArtifact = true; + if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) { + for (String exlude : exludeServiceCategory) { + if (exlude.equalsIgnoreCase(category)) { + isCreateArtifact = false; + break; + } + } + + } + + if (informationalServiceArtifacts != null && isCreateArtifact) { + Set<String> keys = informationalServiceArtifacts.keySet(); + for (String informationalServiceArtifactName : keys) { + Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName); + ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false); + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + + } + + service.setArtifacts(artifactMap); + } + } + + private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) { + + ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL); + + if (isServiceApi) { + artifactInfo.setMandatory(false); + artifactInfo.setServiceApi(true); + } + return artifactInfo; + } + + private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition, User user) { + DistributionTransitionEnum transitionEnum = null; + + transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition); + if (transitionEnum == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Change Service Distribution"); + BeEcompErrorManager.getInstance().logBeSystemError("Change Service Distribution"); + log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString()); + ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(error); + } + + return Either.left(transitionEnum); + } + + private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment, User user, AuditingActionEnum auditAction) { + String data = comment.getUserRemarks(); + + if (data == null || data.trim().isEmpty()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "Change Service Distribution"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution"); + log.debug("user comment cannot be empty or null."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + data = ValidationUtils.removeNoneUtf8Chars(data); + data = ValidationUtils.removeHtmlTags(data); + data = ValidationUtils.normaliseWhitespace(data); + data = ValidationUtils.stripOctets(data); + + if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "Change Service Distribution"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution"); + log.debug("user comment exceeds limit."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH))); + } + if (!ValidationUtils.validateIsEnglish(data)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + return Either.left(data); + } + + private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) { + Either<Service, StorageOperationStatus> storageStatus = serviceOperation.getService(serviceId); + if (storageStatus.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId); + createAudit(user, auditAction, comment, responseFormat); + return Either.right(responseFormat); + } + Service service = storageStatus.left().value(); + + if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) { + log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName()); + createAudit(user, auditAction, comment, service, responseFormat); + return Either.right(responseFormat); + } + return Either.left(service); + } + + private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) { + log.debug("get user from DB"); + /* + * Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId());s if (eitherCreator.isRight() || eitherCreator.left().value() == null) { BeEcompErrorManager.getInstance().processEcompError(EcompErrorName. BeUserMissingError, + * "Activate Distribution", user.getUserId()); log. debug("changeServiceDistributionState method - user is not listed. userId=" + user.getUserId()); ResponseFormat responseFormat = + * componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND); createAudit(user, auditAction, comment, responseFormat); return Either.right(responseFormat); } user = eitherCreator.left().value(); log.debug("validate user role"); if + * (!validateUserTemp(user, Role.ADMIN, Role.GOVERNOR)) { log.info("role {} is not allowed to perform this action", user.getRole()); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + * createAudit(user, auditAction, comment, service, responseFormat); return Either.right(responseFormat); } + */ + // get user details + Either<User, ResponseFormat> eitherCreator = validateUser(user, "Activate Distribution", service, auditAction, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + // validate user role + List<Role> roles = new ArrayList<>(); + roles.add(Role.ADMIN); + roles.add(Role.GOVERNOR); + Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, roles, auditAction, comment); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + return Either.left(user); + } + + private void createAudit(User user, AuditingActionEnum auditAction, String comment, ResponseFormat responseFormat) { + EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class); + + createAudit(user, auditAction, comment, null, responseFormat, auditingFields); + } + + private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) { + EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, component.getDistributionStatus().name()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, component.getDistributionStatus().name()); + createAudit(user, auditAction, comment, component, component.getLifecycleState().name(), component.getVersion(), responseFormat, auditingFields); + } + + private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat, EnumMap<AuditingFieldsKeysEnum, Object> auditingFields) { + log.debug("audit before sending response"); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment); + componentsUtils.auditComponent(responseFormat, user, component, null, null, auditAction, ComponentTypeEnum.SERVICE, auditingFields); + } + + private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, String prevState, String prevVersion, ResponseFormat responseFormat, EnumMap<AuditingFieldsKeysEnum, Object> auditingFields) { + log.debug("audit before sending response"); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment); + componentsUtils.auditComponent(responseFormat, user, component, prevState, prevVersion, auditAction, ComponentTypeEnum.SERVICE, auditingFields); + } + + public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) { + + Either<User, ResponseFormat> eitherCreator = validateUserExists(modifier.getUserId(), "activate Distribution", false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + + User user = eitherCreator.left().value(); + + Either<Service, ResponseFormat> result = null; + ResponseFormat response = null; + Service updatedService = null; + String did = ThreadLocalsHolder.getUuid(); + EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, did); + // DE194021 + String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0); + if (configuredEnvName != null && false == envName.equals(configuredEnvName)) { + log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName); + envName = configuredEnvName; + } + // DE194021 + + ServletContext servletContext = request.getSession().getServletContext(); + boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(request.getSession().getServletContext()); // DE + if (!isDistributionEngineUp) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Distribution Engine is DOWN"); + BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN"); + log.debug("Distribution Engine is DOWN"); + response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(response); + } + + Either<Service, StorageOperationStatus> serviceRes = serviceOperation.getService(serviceId); + if (serviceRes.isRight()) { + log.debug("failed retrieving service"); + response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId); + componentsUtils.auditComponent(response, user, null, null, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE, auditingFields); + return Either.right(response); + } + Service service = serviceRes.left().value(); + String dcurrStatus = service.getDistributionStatus().name(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, dcurrStatus); + + Either<INotificationData, StorageOperationStatus> readyForDistribution = distributionEngine.isReadyForDistribution(service, did, envName); + if (readyForDistribution.isLeft()) { + INotificationData notificationData = readyForDistribution.left().value(); + StorageOperationStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user.getUserId(), user.getFullName()); + if (notifyServiceResponse == StorageOperationStatus.OK) { + Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED); + if (updateStateRes.isLeft() && updateStateRes.left().value() != null) { + updatedService = updateStateRes.left().value(); + dcurrStatus = updatedService.getDistributionStatus().name(); + } else { + // The response is not relevant + updatedService = service; + } + ASDCKpiApi.countActivatedDistribution(); + response = componentsUtils.getResponseFormat(ActionStatus.OK); + result = Either.left(updatedService); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Activate Distribution - send notification"); + BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification"); + log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse); + response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + result = Either.right(response); + } + } else { + StorageOperationStatus distEngineValidationResponse = readyForDistribution.right().value(); + response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(distEngineValidationResponse), service.getName(), envName); + result = Either.right(response); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, dcurrStatus); + componentsUtils.auditComponent(response, user, service, null, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE, auditingFields); + return result; + } + + // convert to private after deletion of temp url + public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) { + + Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "update Distribution Status For Activation", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + String serviceId = service.getUniqueId(); + Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation"); + if (lockResult.isRight()) { + return Either.right(lockResult.right().value()); + } + try { + Either<Service, StorageOperationStatus> result = serviceOperation.updateDestributionStatus(service, user, state); + if (result.isRight()) { + titanGenericDao.rollback(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "updateDistributionStatusForActivation"); + BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation"); + log.debug("service {} change distribution status failed", serviceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + titanGenericDao.commit(); + return Either.left(result.left().value()); + } finally { + graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); + } + } + + public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) { + + Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "mark Distribution As Deployed", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + log.debug("mark distribution deployed"); + + AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY; + Either<Service, StorageOperationStatus> getServiceResponse = serviceOperation.getService(serviceId); + if (getServiceResponse.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeServiceMissingError, "markDistributionAsDeployed", serviceId); + BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId); + log.debug("service {} not found", serviceId); + ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), ""); + + return Either.right(responseFormat); + } + + Service service = getServiceResponse.left().value(); + + Either<User, ResponseFormat> validateRoleForDeploy = validateRoleForDeploy(did, user, auditAction, service); + if (validateRoleForDeploy.isRight()) { + return Either.right(validateRoleForDeploy.right().value()); + } + user = validateRoleForDeploy.left().value(); + + return checkDistributionAndDeploy(did, user, auditAction, service); + + } + + public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock) { + Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri -> + // Only one VF Module Artifact per instance - add it to a list of one + Arrays.asList(new VfModuleArtifacGenerator(modifier, ri, service, shouldLock)); + + return generateDeploymentArtifacts(service, modifier, artifactTaskGeneratorCreator); + + } + + private List<GroupDefinition> collectGroupsForCompInstance(ComponentInstance currVF, Wrapper<ResponseFormat> responseWrapper) { + List<GroupDefinition> relevantGroups = new ArrayList<>(); + Either<List<GroupDefinition>, StorageOperationStatus> eitherGroups = groupOperation.getAllGroups(currVF.getComponentUid(), NodeTypeEnum.Resource); + + if (eitherGroups.isRight()) { + final StorageOperationStatus storageStatus = eitherGroups.right().value(); + if (storageStatus != StorageOperationStatus.NOT_FOUND && storageStatus != StorageOperationStatus.OK) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageStatus); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus)); + } + + } else { + relevantGroups = eitherGroups.left().value().stream().filter(p -> GroupTypeEnum.VF_MODULE.getGroupTypeName().equals(p.getType())).collect(Collectors.toList()); + } + return relevantGroups; + } + + private ArtifactDefinition getVfModuleArtifactForCompInstance(ComponentInstance currVF, Service service, User modifier, List<GroupDefinition> groupsForCurrVF, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) { + ArtifactDefinition vfModuleAertifact = null; + + Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny(); + if (optionalVfModuleArtifact.isPresent()) { + vfModuleAertifact = optionalVfModuleArtifact.get(); + } else { + Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(modifier, currVF, service, payloadWrapper.getInnerElement()); + if (createVfModuleArtifact.isLeft()) { + vfModuleAertifact = createVfModuleArtifact.left().value(); + } else { + responseWrapper.setInnerElement(createVfModuleArtifact.right().value()); + } + } + return vfModuleAertifact; + } + + private void fillVfModuleHeatEnvPayload(List<GroupDefinition> groupsForCurrVF, ComponentInstance currVFInstance, Wrapper<String> payloadWrapper) { + // Converts GroupDefinition to VfModuleArtifactPayload which is the + // format used in the payload + + List<VfModuleArtifactPayload> vfModulePayloadForCurrVF = groupsForCurrVF.stream().map(group -> new VfModuleArtifactPayload(group)).collect(Collectors.toList()); + Collections.sort(vfModulePayloadForCurrVF, (art1, art2) -> VfModuleArtifactPayload.compareByGroupName(art1, art2)); + // Update Payload With Heat Env + vfModulePayloadForCurrVF.stream().forEach(e -> addHeatEnvArtifactsToVFModulePayload(e, currVFInstance)); + + final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + String vfModulePayloadString = gson.toJson(vfModulePayloadForCurrVF); + payloadWrapper.setInnerElement(vfModulePayloadString); + + } + + private void addHeatEnvArtifactsToVFModulePayload(VfModuleArtifactPayload vfModulePayload, ComponentInstance currVFInstance) { + List<String> originalModuleArtifacts = vfModulePayload.getArtifacts(); + if (!MapUtils.isEmpty(currVFInstance.getDeploymentArtifacts()) && !CollectionUtils.isEmpty(originalModuleArtifacts)) { + + final Collection<ArtifactDefinition> depInsArtifacts = currVFInstance.getDeploymentArtifacts().values(); + // All Heat_ENV + List<ArtifactDefinition> heatEnvArtifacts = depInsArtifacts.stream().filter(art -> art.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())).collect(Collectors.toList()); + // Unique Id Of Artifacts In the vf module + List<String> moduleArtUniqueId = depInsArtifacts.stream().filter(art -> originalModuleArtifacts.contains(art.getArtifactUUID())).map(art -> art.getUniqueId()).collect(Collectors.toList()); + // Collect Only Heat Artifatcs that are Generated from artifacts in + // the module + List<String> relevantHeatEnvUUID = heatEnvArtifacts.stream().filter(heatEnv -> moduleArtUniqueId.contains(heatEnv.getGeneratedFromId())).map(heatEnv -> heatEnv.getArtifactUUID()).collect(Collectors.toList()); + + List<String> fullArtifactList = new ArrayList<>(); + fullArtifactList.addAll(originalModuleArtifacts); + fullArtifactList.addAll(relevantHeatEnvUUID); + + vfModulePayload.setArtifacts(fullArtifactList); + } + } + + private Either<ArtifactDefinition, ResponseFormat> generateVfModuleArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock) { + ArtifactDefinition vfModuleAertifact = null; + Wrapper<ResponseFormat> responseWrapper = new Wrapper<>(); + Wrapper<String> payloadWrapper = new Wrapper<>(); + List<GroupDefinition> groupsForCurrVF = collectGroupsForCompInstance(currVFInstance, responseWrapper); + if (responseWrapper.isEmpty()) { + fillVfModuleHeatEnvPayload(groupsForCurrVF, currVFInstance, payloadWrapper); + } + if (responseWrapper.isEmpty()) { + vfModuleAertifact = getVfModuleArtifactForCompInstance(currVFInstance, service, modifier, groupsForCurrVF, payloadWrapper, responseWrapper); + } + if (responseWrapper.isEmpty() && vfModuleAertifact != null) { + vfModuleAertifact = fillVfModulePayload(modifier, currVFInstance, vfModuleAertifact, shouldLock, payloadWrapper, responseWrapper); + } + + Either<ArtifactDefinition, ResponseFormat> result; + if (responseWrapper.isEmpty()) { + result = Either.left(vfModuleAertifact); + } else { + result = Either.right(responseWrapper.getInnerElement()); + } + + return result; + } + + private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleAertifact, boolean shouldLock, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) { + ArtifactDefinition result = null; + final Either<Resource, StorageOperationStatus> eitherResource = resourceOperation.getResource(currVF.getComponentUid()); + if (eitherResource.isRight()) { + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(eitherResource.right().value()))); + } else { + Resource resource = eitherResource.left().value(); + Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleAertifact, resource, currVF.getName(), modifier, shouldLock, () -> System.currentTimeMillis(), + () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleAertifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8)))); + if (eitherPayload.isLeft()) { + result = eitherPayload.left().value(); + } else { + responseWrapper.setInnerElement(eitherPayload.right().value()); + } + } + + return result; + } + + private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(User modifier, ComponentInstance currVF, Service service, String vfModulePayloadString) { + + ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition(); + + 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); + + Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactOperation.addArifactToComponent(vfModuleArtifactDefinition, currVF.getUniqueId(), NodeTypeEnum.ResourceInstance, true, true); + + Either<ArtifactDefinition, ResponseFormat> result; + if (addArifactToComponent.isLeft()) { + result = Either.left(addArifactToComponent.left().value()); + } else { + result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value()))); + } + + return result; + } + + public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock) { + + Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance -> + // Get All Deployment Artifacts + service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()). + // Filter in Only Heat Env + filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())). + // Create ArtifactGenerator from those Artifacts + map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock)).collect(Collectors.toList()); + + return generateDeploymentArtifacts(service, modifier, artifactTaskGeneratorCreator); + + } + + private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, User modifier, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) { + + List<Future<Either<CallVal, ResponseFormat>>> allFutures = new ArrayList<>(); + + // Get Flat List of (Callable) ArtifactGenerator for all the RI in the + // service + if (service.getComponentInstances() != null) { + List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList()); + if (artifactGenList != null && !artifactGenList.isEmpty()) { + ExecutorService executor = Executors.newFixedThreadPool(artifactGenList.size()); + + artifactGenList.stream().forEach(e -> allFutures.add(executor.submit(e))); + + boolean isSuccess = true; + ResponseFormat firstError = null; + for (Future<Either<CallVal, ResponseFormat>> entry : allFutures) { + try { + Either<CallVal, ResponseFormat> actionStatus = entry.get(20, TimeUnit.SECONDS); + if (actionStatus.isRight()) { + isSuccess = false; + if (firstError == null) { + firstError = actionStatus.right().value(); + } + log.debug("Failed to generate artifact error : {}", actionStatus.right().value()); + } + } catch (Exception e) { + log.debug("Failed to collect result from artifact generator ", e); + isSuccess = false; + firstError = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + } + } + executor.shutdown(); + if (!isSuccess) { + return Either.right(firstError); + } + } + + } + return Either.left(service); + } + + abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> { + + } + + class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> { + ArtifactDefinition artifactDefinition; + Service service; + String resourceInstanceName; + User modifier; + boolean shouldLock; + + HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock) { + this.artifactDefinition = artifactDefinition; + this.service = service; + this.resourceInstanceName = resourceInstanceName; + this.modifier = modifier; + this.shouldLock = shouldLock; + } + + @Override + public Either<ArtifactDefinition, ResponseFormat> call() throws Exception { + return artifactsBusinessLogic.generateHeatEnvArtifact(artifactDefinition, service, resourceInstanceName, modifier, shouldLock); + } + + public ArtifactDefinition getArtifactDefinition() { + return artifactDefinition; + } + + } + + class VfModuleArtifacGenerator extends ArtifactGenerator<ArtifactDefinition> { + private User user; + private ComponentInstance componentInstance; + private Service service; + boolean shouldLock; + + @Override + public Either<ArtifactDefinition, ResponseFormat> call() throws Exception { + return generateVfModuleArtifact(user, componentInstance, service, shouldLock); + } + + private VfModuleArtifacGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock) { + super(); + this.user = user; + this.componentInstance = componentInstance; + this.service = service; + this.shouldLock = shouldLock; + } + + } + + private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String did, User user, AuditingActionEnum auditAction, Service service) { + boolean isDeployed = isDistributionDeployed(did, service); + if (isDeployed) { + return Either.left(service); + } + Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(did, user, auditAction, service); + if (distributionSuccess.isRight()) { + return Either.right(distributionSuccess.right().value()); + } + + log.debug("mark distribution {} as deployed - success", did); + componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, STATUS_DEPLOYED, "OK", user); + return Either.left(service); + } + + private boolean isDistributionDeployed(String did, Service service) { + Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(did, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED); + + boolean isDeployed = false; + if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) { + // already deployed + log.debug("distribution {} is already deployed", did); + isDeployed = true; + } + return isDeployed; + } + + protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) { + + log.trace("checkDistributionSuccess"); + // get all "DRequest" records for this distribution + // Either<List<ESTimeBasedEvent>, ActionStatus> distRequestsResponse = + // auditingDao.getListOfDistributionByAction(did, + // AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName(), "", + // ResourceAdminEvent.class); + Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName()); + if (distRequestsResponse.isRight()) { + ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value()); + return Either.right(error); + } + + List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value(); + if (distributionRequests.isEmpty()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionMissingError, "markDistributionAsDeployed", did); + BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did); + log.info("distribution {} is not found", did); + ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND); + return Either.right(error); + } + boolean isRequestSucceeded = false; + for (ResourceAdminEvent event : distributionRequests) { + String eventStatus = event.getStatus(); + if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) { + isRequestSucceeded = true; + break; + } + } + + // get all "DNotify" records for this distribution + // Either<List<ESTimeBasedEvent>, ActionStatus> + // distNotificationsResponse = + // auditingDao.getListOfDistributionByAction(did, + // AuditingActionEnum.DISTRIBUTION_NOTIFY.getName(), "", + // DistributionNotificationEvent.class); + Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName()); + if (distNotificationsResponse.isRight()) { + ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value()); + return Either.right(error); + } + + List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value(); + boolean isNotificationsSucceeded = false; + for (DistributionNotificationEvent event : distributionNotifications) { + String eventStatus = event.getStatus(); + if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) { + isNotificationsSucceeded = true; + break; + } + } + + // if request failed OR there are notifications that failed + if (!(isRequestSucceeded && isNotificationsSucceeded)) { + + log.info("distribution {} has failed", did); + ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did); + auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did); + return Either.right(error); + } + return Either.left(true); + } + + private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) { + + ResponseFormat error = componentsUtils.getResponseFormat(status, params); + String message = ""; + if (error.getMessageId() != null) { + message = error.getMessageId() + ": "; + } + message += error.getFormattedMessage(); + + if (service != null) { + componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user); + } else { + componentsUtils.auditServiceDistributionDeployed(auditAction, "", "", "", did, error.getStatus().toString(), message, user); + } + return error; + } + + private Either<User, ResponseFormat> validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) { + Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false); + if (eitherCreator.isRight() || eitherCreator.left().value() == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUserMissingError, "Deploy Service", user.getUserId()); + BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId()); + log.debug("validateRoleForDeploy method - user is not listed. userId={}", user.getUserId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId()); + auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND); + return Either.right(responseFormat); + } + user = eitherCreator.left().value(); + log.debug("validate user role"); + List<Role> roles = new ArrayList<>(); + roles.add(Role.ADMIN); + roles.add(Role.OPS); + Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, roles, auditAction, null); + if (validateRes.isRight()) { + log.info("role {} is not allowed to perform this action", user.getRole()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + auditDeployError(did, user, auditAction, service, ActionStatus.RESTRICTED_OPERATION); + return Either.right(responseFormat); + } + return Either.left(user); + + } + + @Override + public void setDeploymentArtifactsPlaceHolder(Component component, User user) { + // TODO Auto-generated method stub + + } + + @Override + public Either<List<String>, ResponseFormat> deleteMarkedComponents() { + return deleteMarkedComponents(ComponentTypeEnum.SERVICE); + } + + private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + HealthCheckBusinessLogic healthCheckBl = webApplicationContext.getBean(HealthCheckBusinessLogic.class); + return healthCheckBl; + } + + @Override + public ComponentInstanceBusinessLogic getComponentInstanceBL() { + return serviceComponentInstanceBusinessLogic; + } + + @Override + public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText) { + + Either<User, ResponseFormat> resp = validateUserExists(userId, "Get Component Instances", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + ComponentOperation componentOperation = getComponentOperation(componentTypeEnum); + + Either<List<ComponentInstance>, StorageOperationStatus> componentInstancesResponse = componentOperation.getAllComponentInstncesMetadata(componentId, componentTypeEnum.getNodeType()); + if (componentInstancesResponse.isRight()) { + + if (componentInstancesResponse.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + return Either.left(new ArrayList<ComponentInstance>()); + } + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentInstancesResponse.right().value())); + return Either.right(responseFormat); + } + + List<ComponentInstance> componentInstances = componentInstancesResponse.left().value(); + componentInstances = componentInstances.stream().filter(instance -> instance.getOriginType().equals(OriginTypeEnum.VF)).collect(Collectors.toList()); + + return Either.left(componentInstances); + } + + public ICacheMangerOperation getCacheManagerOperation() { + return cacheManagerOperation; + } + + public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) { + this.cacheManagerOperation = cacheManagerOperation; + } +} |