diff options
Diffstat (limited to 'catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java')
-rw-r--r-- | catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java | 4127 |
1 files changed, 4127 insertions, 0 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java new file mode 100644 index 0000000000..16ed4a1868 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java @@ -0,0 +1,4127 @@ +/*- + * ============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.io.ByteArrayInputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.Configuration.DeploymentArtifactTypeConfig; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.validation.DeploymentArtifactHeatConfiguration; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.heat.HeatParameterType; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation; +import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation; +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.DaoStatusConverter; +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.ArtifactData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.resources.data.auditing.AuditingTypesConstants; +import org.openecomp.sdc.be.servlets.RepresentationUtils; +import org.openecomp.sdc.be.tosca.CsarUtils; +import org.openecomp.sdc.be.tosca.ToscaError; +import org.openecomp.sdc.be.tosca.ToscaExportHandler; +import org.openecomp.sdc.be.tosca.ToscaRepresentation; +import org.openecomp.sdc.be.user.IUserBusinessLogic; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.be.user.UserBusinessLogic; +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.util.GeneralUtility; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.common.util.YamlToObjectConverter; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.yaml.snakeyaml.Yaml; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.sun.org.apache.xerces.internal.parsers.SAXParser; + +import fj.data.Either; + +@org.springframework.stereotype.Component("artifactBusinessLogic") +public class ArtifactsBusinessLogic extends BaseBusinessLogic { + private static final String ARTIFACT_TYPE_OTHER = "OTHER"; + private static final String ARTIFACT_DESCRIPTION = "artifact description"; + private static final String ARTIFACT_LABEL = "artifact label"; + private static final String ARTIFACT_URL = "artifact url"; + private static final String ARTIFACT_NAME = "artifact name"; + private static final String ARTIFACT_PAYLOAD = "artifact payload"; + + private static final String ARTIFACT_PLACEHOLDER_TYPE = "type"; + private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName"; + private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description"; + + private static Integer defaultHeatTimeout; + private static final Integer NON_HEAT_TIMEOUT = 0; + private static Logger log = LoggerFactory.getLogger(ArtifactsBusinessLogic.class.getName()); + private Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + @javax.annotation.Resource + private IArtifactOperation artifactOperation; + + // @javax.annotation.Resource + // private IResourceUploader daoUploader; + + @javax.annotation.Resource + private IInterfaceLifecycleOperation interfaceLifecycleOperation; + @javax.annotation.Resource + private IUserAdminOperation userOperaton; + + // @javax.annotation.Resource + // private ESCatalogDAO esCatalogDao; + + @javax.annotation.Resource + private IElementOperation elementOperation; + + @javax.annotation.Resource + private ResourceBusinessLogic resourceBusinessLogic; + + @javax.annotation.Resource + private ServiceBusinessLogic serviceBusinessLogic; + + @javax.annotation.Resource + private UserBusinessLogic userAdminManager; + + @javax.annotation.Resource + private IHeatParametersOperation heatParametersOperation; + + @javax.annotation.Resource + private IComponentInstanceOperation resourceInstanceOperation; + + @Autowired + private ArtifactCassandraDao artifactCassandraDao; + + @Autowired + private ToscaExportHandler toscaExportUtils; + + @Autowired + private CsarUtils csarUtils; + + @Autowired + private LifecycleBusinessLogic lifecycleBusinessLogic; + + @Autowired + private IUserBusinessLogic userBusinessLogic; + + public ArtifactsBusinessLogic() { + defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes(); + if ((defaultHeatTimeout == null) || (defaultHeatTimeout < 1)) { + defaultHeatTimeout = 60; + } + } + + public static enum ArtifactOperation { + + Create(false), Update(false), Delete(false), Download(false); + + private boolean isExternalApi; + + ArtifactOperation(boolean isExternalApi) { + this.isExternalApi = isExternalApi; + } + + public boolean isExternalApi() { + return isExternalApi; + } + + public void setExternalApi(boolean isExternalApi) { + this.isExternalApi = isExternalApi; + } + } + + // new flow US556184 + public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, + String origMd5, String originData, String interfaceName, String operationName, String parentId, String containerComponentType) { + return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName, operationName, parentId, containerComponentType, true, false); + } + + public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, + String origMd5, String originData, String interfaceName, String operationName, String parentId, String containerComponentType, boolean shouldLock, boolean inTransaction) { + // step 1 + // detect auditing type + AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5); + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + // step 2 + // check header + if (userId == null) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + log.debug("handleArtifactRequest - no HTTP_CSP_HEADER , component id {}", componentId); + handleAuditing(auditingAction, null, componentId, null, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + // step 3 + // check user existence + // step 4 + // check user's role + Either<User, ResponseFormat> userResult = validateUserExists(userId, auditingAction, componentId, artifactId, componentType, inTransaction); + if (userResult.isRight()) { + return Either.right(userResult.right().value()); + } + + User user = userResult.left().value(); + Either<Boolean, ResponseFormat> validateUserRole = validateUserRole(user, auditingAction, componentId, artifactId, componentType, operation); + if (validateUserRole.isRight()) { + return Either.right(validateUserRole.right().value()); + } + + // steps 5 - 6 - 7 + // 5. check service/resource existence + // 6. check service/resource check out + // 7. user is owner of checkout state + org.openecomp.sdc.be.model.Component component = null; + // ComponentInstance resourceInstance = null; + String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId; + Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponent = validateComponentExists(realComponentId, userId, auditingAction, user, artifactId, componentType, containerComponentType, inTransaction); + if (validateComponent.isRight()) { + return Either.right(validateComponent.right().value()); + } + component = validateComponent.left().value(); + Either<Boolean, ResponseFormat> validateWorkOnResource = validateWorkOnComponent(component, userId, auditingAction, user, artifactId, operation, componentType); + if (validateWorkOnResource.isRight()) { + return Either.right(validateWorkOnResource.right().value()); + } + // step 8 + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> result = validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName, operationName, parentId, user, component, + shouldLock, inTransaction); + + return result; + } + + /** + * This Method validates only the Artifact and does not validate user / role / component ect...<br> + * For regular usage use <br> + * {@link #handleArtifactRequest(String, String, ComponentTypeEnum, ArtifactOperation, String, ArtifactDefinition, String, String, String, String, String, String)} + * + * @return + */ + public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> validateAndHandleArtifact(String componentUniqueId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactUniqueId, ArtifactDefinition artifactDefinition, + String origMd5, String originData, String interfaceName, String operationName, String parentId, User user, Component component, boolean shouldLock, boolean inTransaction) { + Component parent = component; + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + + AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5); + artifactDefinition = validateArtifact(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, parentId, auditingAction, user, component, parent, shouldLock, errorWrapper); + + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> result; + if (errorWrapper.isEmpty()) { + // step 10 + result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, origMd5, originData, interfaceName, operationName, auditingAction, user, parent, shouldLock, inTransaction); + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + private ArtifactDefinition validateArtifact(String componentId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, String parentId, AuditingActionEnum auditingAction, User user, + org.openecomp.sdc.be.model.Component component, org.openecomp.sdc.be.model.Component parent, boolean shouldLock, Wrapper<ResponseFormat> errorWrapper) { + if (operation == ArtifactOperation.Update || operation == ArtifactOperation.Delete || operation == ArtifactOperation.Download) { + Either<ArtifactDefinition, ResponseFormat> validateArtifact = validateArtifact(componentId, componentType, artifactId, component, auditingAction, parentId); + if (validateArtifact.isRight()) { + ResponseFormat responseFormat = validateArtifact.right().value(); + handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null); + errorWrapper.setInnerElement(validateArtifact.right().value()); + } else if (operation == ArtifactOperation.Download) { + artifactInfo = validateArtifact.left().value(); + handleHeatEnvDownload(componentId, user, component, validateArtifact, shouldLock, errorWrapper); + } + } + return artifactInfo; + } + + private void handleHeatEnvDownload(String componentId, User user, org.openecomp.sdc.be.model.Component component, Either<ArtifactDefinition, ResponseFormat> validateArtifact, boolean shouldLock, Wrapper<ResponseFormat> errorWrapper) { + ArtifactDefinition validatedArtifact = validateArtifact.left().value(); + + if (validatedArtifact.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType())) { + ComponentInstance componentInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findAny().get(); + ArtifactDefinition heatEnvWithHeatParams = componentInstance.getDeploymentArtifacts().values().stream().filter(p -> p.getUniqueId().equals(validatedArtifact.getUniqueId())).findAny().get(); + Either<ArtifactDefinition, ResponseFormat> eitherGenerated = generateHeatEnvArtifact(heatEnvWithHeatParams, component, componentInstance.getName(), user, shouldLock); + if (eitherGenerated.isRight()) { + errorWrapper.setInnerElement(eitherGenerated.right().value()); + } + } + } + + private boolean artifactGenerationRequired(org.openecomp.sdc.be.model.Component component, ArtifactDefinition artifactInfo) { + return artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && (component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> generateAndSaveToscaArtifact(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, + boolean shouldLock, boolean inTransaction, boolean fetchTemplatesFromDB) { + + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> generated = generateToscaArtifact(component, artifactDefinition, isInCertificationRequest, fetchTemplatesFromDB, shouldLock, inTransaction); + if (generated.isRight()) { + return generated; + } + byte[] decodedPayload = artifactDefinition.getPayloadData(); + artifactDefinition.setEsId(artifactDefinition.getUniqueId()); + artifactDefinition.setArtifactChecksum(GeneralUtility.calculateMD5ByByteArray(decodedPayload)); + return lockComponentAndUpdateArtifact(component.getUniqueId(), artifactDefinition, AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, artifactDefinition.getUniqueId(), user, component.getComponentType(), component, decodedPayload, null, null, + shouldLock, inTransaction); + + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> generateToscaArtifact(Component parent, ArtifactDefinition artifactInfo, boolean isInCertificationRequest, boolean fetchTemplatesFromDB, boolean shouldLock, + boolean inTransaction) { + log.debug("tosca artifact generation"); + if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())) { + Either<byte[], ResponseFormat> generated = csarUtils.createCsar(parent, fetchTemplatesFromDB, isInCertificationRequest, shouldLock, inTransaction); + + if (generated.isRight()) { + log.debug("Failed to export tosca csar for component {} error {}", parent.getUniqueId(), generated.right().value()); + + return Either.right(generated.right().value()); + } + byte[] value = generated.left().value(); + artifactInfo.setPayload(value); + + } else { + Either<ToscaRepresentation, ToscaError> exportComponent = toscaExportUtils.exportComponent(parent); + if (exportComponent.isRight()) { + log.debug("Failed export tosca yaml for component {} error {}", parent.getUniqueId(), exportComponent.right().value()); + ActionStatus status = componentsUtils.convertFromToscaError(exportComponent.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(status); + return Either.right(responseFormat); + } + log.debug("Tosca yaml exported for component {} ", parent.getUniqueId()); + String payload = exportComponent.left().value().getMainYaml(); + artifactInfo.setPayloadData(payload); + } + return Either.left(Either.left(artifactInfo)); + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, String origMd5, + String originData, String interfaceName, String operationName, AuditingActionEnum auditingAction, User user, org.openecomp.sdc.be.model.Component parent, boolean shouldLock, boolean inTransaction) { + if (interfaceName != null && operationName != null) { + interfaceName = interfaceName.toLowerCase(); + operationName = operationName.toLowerCase(); + } + switch (operation) { + case Download: + if (artifactGenerationRequired(parent, artifactInfo)) { + return generateToscaArtifact(parent, artifactInfo, false, false, shouldLock, inTransaction); + } + return handleDownload(componentId, artifactId, user, auditingAction, componentType, parent, shouldLock, inTransaction); + case Delete: + return handleDelete(componentId, artifactId, user, auditingAction, componentType, parent, interfaceName, operationName, shouldLock, inTransaction); + case Update: + ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactInfo.getArtifactType()); + if (componentType.equals(ComponentTypeEnum.RESOURCE_INSTANCE) + && (artifactType == ArtifactTypeEnum.HEAT || artifactType == ArtifactTypeEnum.HEAT_VOL || artifactType == ArtifactTypeEnum.HEAT_NET || artifactType == ArtifactTypeEnum.HEAT_ENV)) { + return handleUpdateHeatEnv(componentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, originData, origMd5, operation, shouldLock, inTransaction); + } + return handleUpdate(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5, originData, interfaceName, operationName, shouldLock, inTransaction); + case Create: + return handleCreate(componentId, artifactInfo, operation, auditingAction, user, componentType, parent, origMd5, originData, interfaceName, operationName, shouldLock, inTransaction); + } + return null; + } + + /** + * + * @param componentId + * @param artifactId + * @param userId + * @param componentType + * @param parentId + * TODO + * @return + */ + + public Either<ImmutablePair<String, byte[]>, ResponseFormat> handleDownloadToscaModelRequest(Component component, ArtifactDefinition csarArtifact, boolean shouldLock, boolean inTransaction) { + if (artifactGenerationRequired(component, csarArtifact)) { + Either<byte[], ResponseFormat> generated = csarUtils.createCsar(component, false, false, shouldLock, inTransaction); + + if (generated.isRight()) { + log.debug("Failed to export tosca csar for component {} error {}", component.getUniqueId(), generated.right().value()); + + return Either.right(generated.right().value()); + } + return Either.left(new ImmutablePair<String, byte[]>(csarArtifact.getArtifactName(), generated.left().value())); + } + return downloadArtifact(csarArtifact); + } + + public Either<ImmutablePair<String, byte[]>, ResponseFormat> handleDownloadRequestById(String componentId, String artifactId, String userId, ComponentTypeEnum componentType, String parentId, String containerComponentType) { + // perform all validation in common flow + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> result = handleArtifactRequest(componentId, userId, componentType, ArtifactOperation.Download, artifactId, null, null, null, null, null, parentId, containerComponentType); + if (result.isRight()) { + return Either.right(result.right().value()); + } + ArtifactDefinition artifactDefinition; + Either<ArtifactDefinition, Operation> insideValue = result.left().value(); + if (insideValue.isLeft()) { + artifactDefinition = insideValue.left().value(); + } else { + artifactDefinition = insideValue.right().value().getImplementation(); + } + // for tosca artifacts generated on download without saving + if (artifactDefinition.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && artifactDefinition.getPayloadData() != null) { + return Either.left(new ImmutablePair<String, byte[]>(artifactDefinition.getArtifactName(), artifactDefinition.getPayloadData())); + } + return downloadArtifact(artifactDefinition); + } + + private Either<ArtifactDefinition, ResponseFormat> validateArtifact(String componentId, ComponentTypeEnum componentType, String artifactId, org.openecomp.sdc.be.model.Component component, AuditingActionEnum auditingAction, String parentId) { + // step 9 + // check artifact existence + Either<ArtifactDefinition, StorageOperationStatus> artifactResult = artifactOperation.getArtifactById(artifactId, false); + if (artifactResult.isRight()) { + if (artifactResult.right().value().equals(StorageOperationStatus.ARTIFACT_NOT_FOUND)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""); + log.debug("addArtifact - artifact {} not found", artifactId); + return Either.right(responseFormat); + + } else { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(artifactResult.right().value())); + log.debug("addArtifact - failed to fetch artifact {}, error {}", artifactId, artifactResult.right().value()); + return Either.right(responseFormat); + } + } + // step 9.1 + // check artifact belong to component + boolean found = false; + switch (componentType) { + case RESOURCE: + case SERVICE: + found = checkArtifactInComponent(component, artifactId); + break; + case RESOURCE_INSTANCE: + found = checkArtifactInResourceInstance(component, componentId, artifactId); + break; + default: + + } + if (!found) { + // String component = + // componentType.equals(ComponentTypeEnum.RESOURCE) ? "resource" : + // "service"; + String componentName = componentType.name().toLowerCase(); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, componentName); + log.debug("addArtifact - Component artifact not found component Id {}, artifact id {}", componentId, artifactId); + return Either.right(responseFormat); + } + return Either.left(artifactResult.left().value()); + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleCreate(String parentId, ArtifactDefinition artifactInfo, ArtifactOperation operation, AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType, + org.openecomp.sdc.be.model.Component parent, String origMd5, String originData, String interfaceType, String operationName, boolean shouldLock, boolean inTransaction) { + + String artifactId = null; + + // step 11 + Either<byte[], ResponseFormat> payloadEither = validateInput(parentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5, originData, interfaceType, operationName, inTransaction); + if (payloadEither.isRight()) { + return Either.right(payloadEither.right().value()); + } + byte[] decodedPayload = payloadEither.left().value(); + NodeTypeEnum parentType = convertParentType(componentType); + // lock resource + + if (shouldLock) { + Either<Boolean, ResponseFormat> lockComponent = lockComponent(parent, "Upload Artifact - lock "); + if (lockComponent.isRight()) { + handleAuditing(auditingAction, parent, parentId, user, null, null, null, lockComponent.right().value(), componentType, null); + return Either.right(lockComponent.right().value()); + } + } + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp = null; + + try { + resultOp = createArtifact(parent, parentId, artifactInfo, decodedPayload, user, componentType, auditingAction, interfaceType, operationName); + return resultOp; + } finally { + if (shouldLock) { + unlockComponent(resultOp, parent, inTransaction); + } + + } + + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> lockComponentAndUpdateArtifact(String parentId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, String artifactId, User user, + ComponentTypeEnum componentType, org.openecomp.sdc.be.model.Component parent, byte[] decodedPayload, String interfaceType, String operationName, boolean shouldLock, boolean inTransaction) { + + NodeTypeEnum parentType = convertParentType(componentType); + + // lock resource + if (shouldLock) { + Either<Boolean, ResponseFormat> lockComponent = lockComponent(parent, "Update Artifact - lock "); + if (lockComponent.isRight()) { + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, lockComponent.right().value(), componentType, null); + return Either.right(lockComponent.right().value()); + } + } + + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp = null; + try { + resultOp = updateArtifactFlow(parent, parentId, artifactId, artifactInfo, user, decodedPayload, componentType, auditingAction, interfaceType, operationName); + return resultOp; + + } finally { + if (shouldLock) { + unlockComponent(resultOp, parent, inTransaction); + } + } + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleUpdate(String parentId, ArtifactDefinition artifactInfo, ArtifactOperation operation, AuditingActionEnum auditingAction, String artifactId, User user, + ComponentTypeEnum componentType, org.openecomp.sdc.be.model.Component parent, String origMd5, String originData, String interfaceType, String operationName, boolean shouldLock, boolean inTransaction) { + + Either<byte[], ResponseFormat> payloadEither = validateInput(parentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5, originData, interfaceType, operationName, inTransaction); + + if (payloadEither.isRight()) { + return Either.right(payloadEither.right().value()); + } + byte[] decodedPayload = payloadEither.left().value(); + + return lockComponentAndUpdateArtifact(parentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, decodedPayload, interfaceType, operationName, shouldLock, inTransaction); + } + + private Either<byte[], ResponseFormat> validateInput(String parentId, ArtifactDefinition artifactInfo, ArtifactOperation operation, AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, + org.openecomp.sdc.be.model.Component parent, String origMd5, String originData, String interfaceType, String operationName, boolean inTransaction) { + // Md5 validations + Either<Boolean, ResponseFormat> validateMd5 = validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation); + if (validateMd5.isRight()) { + ResponseFormat responseFormat = validateMd5.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + + // step 11 + Either<ArtifactDefinition, ResponseFormat> validateResult = validateInput(parentId, artifactInfo, operation, artifactId, user, interfaceType, operationName, componentType, parent, inTransaction); + if (validateResult.isRight()) { + ResponseFormat responseFormat = validateResult.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(validateResult.right().value()); + } + + Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction)); + if (payloadEither.isRight()) { + ResponseFormat responseFormat = payloadEither.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + log.debug("Error during handle payload"); + return Either.right(responseFormat); + } + + // validate heat parameters. this part must be after the parameters are + // extracted in "handlePayload" + Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParamers(artifactInfo, artifactInfo.getArtifactType()); + if (validateAndConvertHeatParamers.isRight()) { + ResponseFormat responseFormat = validateAndConvertHeatParamers.right().value(); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null); + log.debug("Error during handle payload"); + return Either.right(responseFormat); + } + return payloadEither; + } + + public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user, ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid, ResponseFormat responseFormat, + ComponentTypeEnum componentTypeEnum, String resourceInstanceName) { + + if (auditingActionEnum.getAuditingEsType().equals(AuditingTypesConstants.EXTERNAL_API_EVENT_TYPE)) { + return; + } + + EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = createArtifactAuditingFields(artifactDefinition, prevArtifactUuid, currentArtifactUuid); + + if (user == null) { + user = new User(); + user.setUserId("UNKNOWN"); + } + switch (componentTypeEnum) { + + case RESOURCE: + Resource resource = (Resource) component; + if (resource == null) { + // In that case, component ID should be instead of name + resource = new Resource(); + resource.setName(componentId); + } + componentsUtils.auditResource(responseFormat, user, resource, null, null, auditingActionEnum, auditingFields); + break; + + case SERVICE: + Service service = (Service) component; + if (service == null) { + // In that case, component ID should be instead of name + service = new Service(); + service.setName(componentId); + } + componentsUtils.auditComponent(responseFormat, user, service, null, null, auditingActionEnum, ComponentTypeEnum.SERVICE, auditingFields); + break; + + case RESOURCE_INSTANCE: + if (resourceInstanceName == null) { + resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName); + componentsUtils.auditComponent(responseFormat, user, component, null, null, auditingActionEnum, ComponentTypeEnum.RESOURCE_INSTANCE, auditingFields); + + break; + default: + break; + } + } + + private String getResourceInstanceNameFromComponent(Component component, String componentId) { + ComponentInstance resourceInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findFirst().orElse(null); + String resourceInstanceName = null; + if (resourceInstance != null) { + resourceInstanceName = resourceInstance.getName(); + } + return resourceInstanceName; + } + + public EnumMap<AuditingFieldsKeysEnum, Object> createArtifactAuditingFields(ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid) { + EnumMap<AuditingFieldsKeysEnum, Object> auditingFields = new EnumMap<AuditingFieldsKeysEnum, Object>(AuditingFieldsKeysEnum.class); + // Putting together artifact info + String artifactData = buildAuditingArtifactData(artifactDefinition); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ARTIFACT_DATA, artifactData); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_PREV_ARTIFACT_UUID, prevArtifactUuid); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, currentArtifactUuid); + return auditingFields; + } + + // ----- + + private String buildAuditingArtifactData(ArtifactDefinition artifactDefinition) { + StringBuilder sb = new StringBuilder(); + if (artifactDefinition != null) { + sb.append(artifactDefinition.getArtifactGroupType().getType()).append(",").append("'").append(artifactDefinition.getArtifactLabel()).append("'").append(",").append(artifactDefinition.getArtifactType()).append(",") + .append(artifactDefinition.getArtifactName()).append(",").append(artifactDefinition.getTimeout()).append(",").append(artifactDefinition.getEsId()); + + sb.append(","); + if (artifactDefinition.getArtifactVersion() != null) { + + sb.append(artifactDefinition.getArtifactVersion()); + } else { + sb.append(" "); + } + sb.append(","); + if (artifactDefinition.getArtifactUUID() != null) { + sb.append(artifactDefinition.getArtifactUUID()); + } else { + sb.append(" "); + } + } + return sb.toString(); + } + + private Either<Boolean, ResponseFormat> validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperation operation) { + + if (origMd5 != null) { + String encodeBase64Str = GeneralUtility.calculateMD5ByString(originData); + + if (false == encodeBase64Str.equals(origMd5)) { + log.debug("The calculated md5 is different then the received one"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_INVALID_MD5)); + } + } else { + if (operation == ArtifactOperation.Create) { + log.debug("Missing md5 header during artifact create"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_INVALID_MD5)); + } + // Update metadata + if (payload != null && payload.length != 0) { + log.debug("Cannot have payload while md5 header is missing"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + } + return Either.left(true); + } + + private Either<ArtifactDefinition, ResponseFormat> validateInput(String parentId, ArtifactDefinition artifactInfo, ArtifactOperation operation, String artifactId, User user, String interfaceName, String operationName, + ComponentTypeEnum componentType, Component parentComponent, boolean inTransaction) { + + Either<Boolean, ResponseFormat> validateAndSetArtifactname = validateAndSetArtifactname(artifactInfo); + if (validateAndSetArtifactname.isRight()) { + return Either.right(validateAndSetArtifactname.right().value()); + } + Either<ArtifactDefinition, ResponseFormat> artifactById = fetchCurrentArtifact(operation, artifactId); + if (artifactById.isRight()) { + return Either.right(artifactById.right().value()); + } + ArtifactDefinition currentArtifactInfo = artifactById.left().value(); + if (operationName != null && interfaceName != null) { + operationName = operationName.toLowerCase(); + interfaceName = interfaceName.toLowerCase(); + } + Either<ActionStatus, ResponseFormat> logicalNameStatus = handleArtifactLabel(parentId, operation, artifactId, artifactInfo, interfaceName, operationName, currentArtifactInfo, componentType, inTransaction); + if (logicalNameStatus.isRight()) { + return Either.right(logicalNameStatus.right().value()); + } + // This is a patch to block possibility of updating service api fields + // through other artifacts flow + + if (!operation.equals(ArtifactOperation.Create)) { + checkAndSetUnUpdatableFields(user, artifactInfo, currentArtifactInfo, (operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL)); + } else { + checkCreateFields(user, artifactInfo, (operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL)); + } + + composeArtifactId(parentId, artifactId, artifactInfo, interfaceName, operationName); + if (currentArtifactInfo != null) { + artifactInfo.setMandatory(currentArtifactInfo.getMandatory()); + } + + // artifactGroupType is not allowed to be updated + if (!operation.equals(ArtifactOperation.Create)) { + Either<ArtifactDefinition, ResponseFormat> validateGroupType = validateOrSetArtifactGroupType(artifactInfo, currentArtifactInfo); + if (validateGroupType.isRight()) { + return Either.right(validateGroupType.right().value()); + } + } + // TODO TEMP !!! + NodeTypeEnum parentType = convertParentType(componentType); + + // TODO TEMP !!! + boolean isCreate = operation.equals(ArtifactOperation.Create); + + if (isDeploymentArtifact(artifactInfo)) { + Either<Boolean, ResponseFormat> deploymentValidationResult = validateDeploymentArtifact(parentComponent, parentId, user.getUserId(), isCreate, artifactInfo, currentArtifactInfo, parentType); + if (deploymentValidationResult.isRight()) { + return Either.right(deploymentValidationResult.right().value()); + } + } else { + artifactInfo.setTimeout(NON_HEAT_TIMEOUT); + + /* + * if (informationDeployedArtifactsBusinessLogic. isInformationDeployedArtifact(artifactInfo)) { Either<Boolean, ResponseFormat> validationResult = informationDeployedArtifactsBusinessLogic.validateArtifact( isCreate, artifactInfo, + * parentComponent, parentType); if (validationResult.isRight()) { return Either.right(validationResult.right().value()); } } + */ + } + + Either<Boolean, ResponseFormat> descriptionResult = validateAndCleanDescription(artifactInfo); + if (descriptionResult.isRight()) { + return Either.right(descriptionResult.right().value()); + } + + if (currentArtifactInfo != null && currentArtifactInfo.getArtifactGroupType().equals(ArtifactGroupTypeEnum.SERVICE_API)) { + Either<ActionStatus, ResponseFormat> validateServiceApiType = validateArtifactType(user.getUserId(), artifactInfo, parentType); + if (validateServiceApiType.isRight()) { + return Either.right(validateServiceApiType.right().value()); + } + // Change of type is not allowed and should be ignored + + artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER); + + Either<Boolean, ResponseFormat> validateUrl = validateAndServiceApiUrl(artifactInfo); + if (validateUrl.isRight()) { + return Either.right(validateUrl.right().value()); + } + + Either<Boolean, ResponseFormat> validateUpdate = validateFirstUpdateHasPayload(artifactInfo, currentArtifactInfo); + if (validateUpdate.isRight()) { + log.debug("serviceApi first update cnnot be without payload."); + return Either.right(validateUpdate.right().value()); + } + } else { + Either<ActionStatus, ResponseFormat> validateArtifactType = validateArtifactType(user.getUserId(), artifactInfo, parentType); + if (validateArtifactType.isRight()) { + return Either.right(validateArtifactType.right().value()); + } + if (artifactInfo.getApiUrl() != null) { + artifactInfo.setApiUrl(null); + log.error("Artifact URL cannot be set through this API - ignoring"); + } + + if (artifactInfo.getServiceApi() != null) { + if (artifactInfo.getServiceApi()) { + artifactInfo.setServiceApi(false); + log.error("Artifact service API flag cannot be changed - ignoring"); + } + } + } + + return Either.left(artifactInfo); + } + + private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) { + if (componentType.equals(ComponentTypeEnum.RESOURCE)) { + return NodeTypeEnum.Resource; + } else if (componentType.equals(ComponentTypeEnum.RESOURCE_INSTANCE)) { + return NodeTypeEnum.ResourceInstance; + } else { + return NodeTypeEnum.Service; + } + } + + public Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleDelete(String parentId, String artifactId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType, org.openecomp.sdc.be.model.Component parent, + String interfaceType, String operationName, boolean shouldLock, boolean inTransaction) { + NodeTypeEnum parentType = convertParentType(componentType); + // lock resource + if (shouldLock) { + Either<Boolean, ResponseFormat> lockComponent = lockComponent(parent, "Delete Artifact - lock resource: "); + if (lockComponent.isRight()) { + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, lockComponent.right().value(), componentType, null); + return Either.right(lockComponent.right().value()); + } + } + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp = null; + Either<ArtifactDefinition, Operation> insideEither = null; + StorageOperationStatus error = null; + boolean isLeft = false; + ArtifactDefinition artifactDefinition = null; + Integer artifactParentsCount = 1; + try { + if (interfaceType != null && operationName != null) { + log.debug("Try to delete inteface lifecycle artifact {}", artifactId); + + Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation.deleteInterfaceOperation(parentId, interfaceType, UniqueIdBuilder.buildOperationByInterfaceUniqueId(parentId, interfaceType, operationName), + inTransaction); + isLeft = result.isLeft(); + if (isLeft) { + artifactDefinition = result.left().value().getImplementation(); + insideEither = Either.right(result.left().value()); + } + } else { + log.debug("Try to delete artifact, get parents {}", artifactId); + + Either<Integer, StorageOperationStatus> parentsOfArtifact = artifactOperation.getParentsOfArtifact(artifactId, parentType); + if (parentsOfArtifact.isRight()) { + log.debug("Failed to delete entry on graph for artifact {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(parentsOfArtifact.right().value()), ""); + resultOp = Either.right(responseFormat); + } else { + + artifactParentsCount = parentsOfArtifact.left().value(); + log.debug("Number of parents nodes on graph for artifact {} is {}", artifactId, artifactParentsCount); + + Either<ArtifactDefinition, StorageOperationStatus> result = artifactOperation.removeArifactFromResource(parentId, artifactId, parentType, false, true); + isLeft = result.isLeft(); + if (isLeft) { + log.debug("Artifact removed from graph {}", artifactId); + + artifactDefinition = result.left().value(); + insideEither = Either.left(result.left().value()); + } else { + error = result.right().value(); + } + } + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + if (isLeft) { + StorageOperationStatus deleteIfNotOnGraph = StorageOperationStatus.OK; + if (artifactParentsCount < 2) { + log.debug("Number of parent nodes is 1. Need to delete from ES {}", artifactId); + deleteIfNotOnGraph = deleteIfNotOnGraph(artifactId, artifactDefinition.getEsId(), true); + } + if (deleteIfNotOnGraph.equals(StorageOperationStatus.OK)) { + if (artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) { + log.debug("Artifact is mandatory or service API. Clean all fields for {}", artifactId); + artifactDefinition.setEsId(""); + artifactDefinition.setArtifactName(""); + artifactDefinition.setDescription(""); + artifactDefinition.setApiUrl(""); + artifactDefinition.setArtifactChecksum(""); + setDefaultArtifactTimeout(artifactDefinition.getArtifactGroupType(), artifactDefinition); + artifactDefinition.setArtifactUUID(""); + long time = System.currentTimeMillis(); + artifactDefinition.setPayloadUpdateDate(time); + artifactDefinition.setHeatParameters(null); + artifactDefinition.setHeatParamsUpdateDate(null); + Either<ArtifactDefinition, StorageOperationStatus> resStatus = null; + if (artifactParentsCount < 2) { + log.debug("Only one parent , clean existing placeholder for {}", artifactId); + resStatus = artifactOperation.updateArifactOnResource(artifactDefinition, parentId, artifactId, parentType, true); + } else { + log.debug("more than one parent , create new placeholder for {}", artifactId); + artifactDefinition.setUniqueId(null); + resStatus = artifactOperation.addArifactToComponent(artifactDefinition, parentId, parentType, true, true); + } + if (resStatus.isRight()) { + log.debug("Failed to clean placeholder for {}", artifactId); + responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(resStatus.right().value()), artifactDefinition.getArtifactDisplayName()); + resultOp = Either.right(responseFormat); + } else { + log.debug("Placeholder was cleaned for {}", artifactId); + + ArtifactDefinition artifactUfterChange = resStatus.left().value(); + + insideEither = Either.left(artifactUfterChange); + resultOp = Either.left(insideEither); + } + } else { + log.debug("Artifact isn't mandatory/service API. Removed. {}", artifactId); + resultOp = Either.left(insideEither); + } + + } else { + log.debug("failed to delete artifact from ES {} status {}", artifactId, deleteIfNotOnGraph); + responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(deleteIfNotOnGraph), artifactDefinition.getArtifactDisplayName()); + resultOp = Either.right(responseFormat); + } + } else { + log.debug("Failed to delete entry on graph for artifact {}", artifactId); + responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(error), ""); + resultOp = Either.right(responseFormat); + } + handleAuditing(auditingAction, parent, parentId, user, artifactDefinition, null, artifactId, responseFormat, componentType, null); + return resultOp; + } finally { + if (shouldLock) { + unlockComponent(resultOp, parent, inTransaction); + } + } + + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleDownload(String componentId, String artifactId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType, + org.openecomp.sdc.be.model.Component parent, boolean shouldLock, boolean inTransaction) { + Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactOperation.getArtifactById(artifactId, false); + if (artifactById.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value()); + log.debug("Error when getting artifact info by id{}, error: {}", artifactId, actionStatus.name()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(actionStatus, ""); + handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + ArtifactDefinition artifactDefinition = artifactById.left().value(); + if (artifactDefinition == null) { + log.debug("Empty artifact definition returned from DB by artifact id {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""); + handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + Either<ArtifactDefinition, Operation> insideEither = Either.left(artifactDefinition); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(auditingAction, parent, componentId, user, artifactDefinition, null, artifactId, responseFormat, componentType, null); + return Either.left(insideEither); + } + + private Either<ArtifactDefinition, ResponseFormat> fetchCurrentArtifact(ArtifactOperation operation, String artifactId) { + Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactOperation.getArtifactById(artifactId, true); + if (!operation.equals(ArtifactOperation.Create) && artifactById.isRight()) { + // in case of update artifact must be + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeArtifactMissingError, "Artifact Update / Upload", artifactId); + BeEcompErrorManager.getInstance().logBeArtifactMissingError("Artifact Update / Upload", artifactId); + log.debug("Failed to fetch artifact {}. error: {}", artifactId, artifactById.right().value()); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(artifactById.right().value()), artifactId)); + } + if (operation.equals(ArtifactOperation.Create) && artifactById.isLeft()) { + log.debug("Artifact {} already exist", artifactId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactById.left().value().getArtifactLabel())); + } + ArtifactDefinition currentArtifactInfo = null; + if (artifactById.isLeft()) { + // get previous value + currentArtifactInfo = artifactById.left().value(); + } + return Either.left(currentArtifactInfo); + } + + private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String componentId, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, String interfaceName, String operationName, + ArtifactDefinition currentArtifactInfo, ComponentTypeEnum componentType, boolean inTransaction) { + String artifactLabel = artifactInfo.getArtifactLabel(); + + if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingArtifactInformationError, "Artifact Update / Upload", "artifactLabel"); + BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel"); + log.debug("missing artifact logical name for component {}", componentId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL)); + } + if (operation.equals(ArtifactOperation.Create) && !artifactInfo.getMandatory()) { + + if (operationName != null) { + if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) { + log.debug("artifact label cannot be set {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED)); + } else { + artifactLabel = operationName; + } + } + String displayName = artifactInfo.getArtifactDisplayName(); + if (displayName == null || displayName.isEmpty()) + displayName = artifactLabel; + displayName = ValidationUtils.cleanArtifactDisplayName(displayName); + artifactInfo.setArtifactDisplayName(displayName); + + if (!ValidationUtils.validateArtifactLabel(artifactLabel)) { + log.debug("Invalid format form Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel); + + if (artifactLabel.isEmpty()) { + log.debug("missing normalized artifact logical name for component {}", componentId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL)); + } + + if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) { + log.debug("Invalid lenght form Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH))); + } + if (!validateLabelUniqueness(componentId, artifactLabel, componentType, inTransaction)) { + log.debug("Non unique Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel)); + } + } + artifactInfo.setArtifactLabel(artifactLabel); + + if (currentArtifactInfo != null && !currentArtifactInfo.getArtifactLabel().equals(artifactInfo.getArtifactLabel())) { + log.info("Logical artifact's name cannot be changed {}", artifactId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED)); + } + return Either.left(ActionStatus.OK); + } + + private boolean validateLabelUniqueness(String parentId, String artifactLabel, ComponentTypeEnum componentType, boolean inTransaction) { + boolean isUnique = true; + NodeTypeEnum parentType; + if (componentType.equals(ComponentTypeEnum.RESOURCE)) { + parentType = NodeTypeEnum.Resource; + } else { + parentType = NodeTypeEnum.Service; + } + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = artifactOperation.getArtifacts(parentId, parentType, inTransaction); + if (artifacts.isLeft()) { + for (String label : artifacts.left().value().keySet()) { + if (label.equals(artifactLabel)) { + isUnique = false; + break; + } + } + } + if (componentType.equals(ComponentTypeEnum.RESOURCE)) { + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation.getAllInterfacesOfResource(parentId, true, inTransaction); + if (allInterfacesOfResource.isLeft()) { + for (InterfaceDefinition interace : allInterfacesOfResource.left().value().values()) { + for (Operation operation : interace.getOperations().values()) { + if (operation.getImplementation() != null && operation.getImplementation().getArtifactLabel().equals(artifactLabel)) { + isUnique = false; + break; + } + } + } + } + } + return isUnique; + } + + // *************************************************************** + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> createArtifact(org.openecomp.sdc.be.model.Component parent, String parentId, ArtifactDefinition artifactInfo, byte[] decodedPayload, User user, + ComponentTypeEnum componentTypeEnum, AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) { + + ESArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload); + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp = null; + Either<ArtifactDefinition, Operation> insideEither = null; + + if (artifactData == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Upload Artifact"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact"); + log.debug("Failed to create artifact object for ES."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(auditingActionEnum, parent, parentId, user, artifactInfo, null, null, responseFormat, componentTypeEnum, null); + resultOp = Either.right(responseFormat); + return resultOp; + + } + // set on graph object id of artifact in ES! + artifactInfo.setEsId(artifactData.getId()); + + boolean isLeft = false; + String artifactUniqueId = null; + ArtifactDefinition artifactDefinition = null; + StorageOperationStatus error = null; + if (interfaceType != null && operationName != null) { + // lifecycle artifact + Operation operation = convertToOperation(artifactInfo, operationName); + + Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation.updateInterfaceOperation(parentId, interfaceType, operationName, operation); + + isLeft = result.isLeft(); + if (isLeft) { + artifactUniqueId = result.left().value().getImplementation().getUniqueId(); + artifactDefinition = result.left().value().getImplementation(); + + insideEither = Either.right(result.left().value()); + resultOp = Either.left(insideEither); + } else { + error = result.right().value(); + } + } else { + // information/deployment/api aritfacts + log.debug("Try to create entry on graph"); + NodeTypeEnum nodeType = convertParentType(componentTypeEnum); + Either<ArtifactDefinition, StorageOperationStatus> result = artifactOperation.addArifactToComponent(artifactInfo, parentId, nodeType, true, true); + + isLeft = result.isLeft(); + if (isLeft) { + artifactUniqueId = result.left().value().getUniqueId(); + artifactDefinition = result.left().value(); + + insideEither = Either.left(result.left().value()); + resultOp = Either.left(insideEither); + } else { + error = result.right().value(); + } + } + if (isLeft) { + boolean res = saveArtifacts(artifactData, parentId, false); + // String uniqueId = artifactDefinition.getUniqueId(); + + if (res) { + log.debug("Artifact saved into ES - {}", artifactUniqueId); + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(auditingActionEnum, parent, parentId, user, artifactInfo, artifactUniqueId, artifactUniqueId, responseFormat, componentTypeEnum, null); + return resultOp; + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Upload Artifact"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact"); + log.debug("Failed to save the artifact."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(auditingActionEnum, parent, parentId, user, artifactInfo, null, artifactUniqueId, responseFormat, componentTypeEnum, null); + + resultOp = Either.right(responseFormat); + return resultOp; + } + } else { + log.debug("Failed to create entry on graph for artifact {}", artifactInfo.getArtifactName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(error), artifactInfo.getArtifactDisplayName()); + handleAuditing(auditingActionEnum, parent, parentId, user, artifactInfo, null, null, responseFormat, componentTypeEnum, null); + resultOp = Either.right(responseFormat); + return resultOp; + } + + } + + private Either<Boolean, ResponseFormat> validateDeploymentArtifact(Component parentComponent, String parentId, String userId, boolean isCreate, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact, NodeTypeEnum parentType) { + + Either<Boolean, ResponseFormat> result = Either.left(true); + Wrapper<ResponseFormat> responseWrapper = new Wrapper<ResponseFormat>(); + + validateArtifactTypeExists(responseWrapper, artifactInfo); + + ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactInfo.getArtifactType()); + + Map<String, DeploymentArtifactTypeConfig> resourceDeploymentArtifacts = fillDeploymentArtifactTypeConf(parentType); + + if (responseWrapper.isEmpty()) { + validateDeploymentArtifactConf(artifactInfo, responseWrapper, artifactType, resourceDeploymentArtifacts); + } + + if (responseWrapper.isEmpty()) { + // Common code for all types + // not allowed to change artifactType + if (!isCreate) { + Either<Boolean, ResponseFormat> validateServiceApiType = validateArtifactTypeNotChanged(artifactInfo, currentArtifact); + if (validateServiceApiType.isRight()) { + responseWrapper.setInnerElement(validateServiceApiType.right().value()); + } + } + } + if (responseWrapper.isEmpty()) { + if (parentType.equals(NodeTypeEnum.Resource)) { + // if (parentComponent instanceof Resource) { + Resource resource = (Resource) parentComponent; + ResourceTypeEnum resourceType = resource.getResourceType(); + DeploymentArtifactTypeConfig config = resourceDeploymentArtifacts.get(artifactType.getType()); + if (config == null) { + responseWrapper.setInnerElement(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType())); + } else { + List<String> myList = config.getValidForResourceTypes(); + Either<Boolean, ResponseFormat> either = validateResourceType(resourceType, artifactInfo, myList); + if (either.isRight()) { + responseWrapper.setInnerElement(either.right().value()); + } + } + } + } + if (responseWrapper.isEmpty()) { + validateFileExtension(responseWrapper, () -> getDeploymentArtifactTypeConfig(parentType, artifactType), artifactInfo, parentType, artifactType); + } + + if (responseWrapper.isEmpty() && !NodeTypeEnum.ResourceInstance.equals(parentType)) { + String artifactName = artifactInfo.getArtifactName(); + if (isCreate || !artifactName.equalsIgnoreCase(currentArtifact.getArtifactName())) { + validateSingleDeploymentArtifactName(responseWrapper, artifactName, parentComponent, parentType); + } + } + + if (responseWrapper.isEmpty()) { + switch (artifactType) { + case HEAT: + case HEAT_VOL: + case HEAT_NET: { + result = validateHeatDeploymentArtifact(parentComponent, userId, isCreate, artifactInfo, currentArtifact, parentType); + break; + } + case HEAT_ENV: { + result = validateHeatEnvDeploymentArtifact(parentComponent, parentId, userId, isCreate, artifactInfo, parentType); + artifactInfo.setTimeout(NON_HEAT_TIMEOUT); + break; + } + case DCAE_INVENTORY_TOSCA: + case DCAE_INVENTORY_JSON: + case DCAE_INVENTORY_POLICY: + // Validation is done in handle payload. + case DCAE_INVENTORY_DOC: + case DCAE_INVENTORY_BLUEPRINT: + case DCAE_INVENTORY_EVENT: + // No specific validation + default: { + artifactInfo.setTimeout(NON_HEAT_TIMEOUT); + } + } + + } + + if (!responseWrapper.isEmpty()) { + result = Either.right(responseWrapper.getInnerElement()); + } + return result; + } + + private void validateDeploymentArtifactConf(ArtifactDefinition artifactInfo, Wrapper<ResponseFormat> responseWrapper, ArtifactTypeEnum artifactType, Map<String, DeploymentArtifactTypeConfig> resourceDeploymentArtifacts) { + if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType()); + responseWrapper.setInnerElement(responseFormat); + log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType()); + } + } + + private Map<String, DeploymentArtifactTypeConfig> fillDeploymentArtifactTypeConf(NodeTypeEnum parentType) { + Map<String, DeploymentArtifactTypeConfig> resourceDeploymentArtifacts = null; + if (parentType.equals(NodeTypeEnum.Resource)) { + resourceDeploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts(); + } else if (parentType.equals(NodeTypeEnum.ResourceInstance)) { + resourceDeploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts(); + } else { + resourceDeploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts(); + } + return resourceDeploymentArtifacts; + } + + public void validateArtifactTypeExists(Wrapper<ResponseFormat> responseWrapper, ArtifactDefinition artifactInfo) { + ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactInfo.getArtifactType()); + if (artifactType == null) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.GENERAL_ERROR); + responseWrapper.setInnerElement(responseFormat); + log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType()); + } + } + + private DeploymentArtifactTypeConfig getDeploymentArtifactTypeConfig(NodeTypeEnum parentType, ArtifactTypeEnum artifactType) { + DeploymentArtifactTypeConfig retConfig = null; + String fileType = artifactType.getType(); + if (parentType.equals(NodeTypeEnum.Resource)) { + retConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts().get(fileType); + } else if (parentType.equals(NodeTypeEnum.Service)) { + retConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts().get(fileType); + } else if (parentType.equals(NodeTypeEnum.ResourceInstance)) { + retConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts().get(fileType); + } + return retConfig; + } + + private Either<Boolean, ResponseFormat> extractHeatParameters(ArtifactDefinition artifactInfo) { + // extract heat parameters + if (artifactInfo.getPayloadData() != null) { + String heatDecodedPayload = GeneralUtility.isBase64Encoded(artifactInfo.getPayloadData()) ? new String(Base64.decodeBase64(artifactInfo.getPayloadData())) : new String(artifactInfo.getPayloadData()); + Either<List<HeatParameterDefinition>, ResultStatusEnum> heatParameters = ImportUtils.getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo.getArtifactType()); + if (heatParameters.isRight() && (!heatParameters.right().value().equals(ResultStatusEnum.ELEMENT_NOT_FOUND))) { + log.info("failed to parse heat parameters "); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactType()); + return Either.right(responseFormat); + } else if (heatParameters.isLeft() && heatParameters.left().value() != null) { + artifactInfo.setHeatParameters(heatParameters.left().value()); + } + } + return Either.left(true); + + } + + // Valid extension + public void validateFileExtension(Wrapper<ResponseFormat> responseWrapper, IDeploymentArtifactTypeConfigGetter deploymentConfigGetter, ArtifactDefinition artifactInfo, NodeTypeEnum parentType, ArtifactTypeEnum artifactType) { + String fileType = artifactType.getType(); + List<String> acceptedTypes = null; + DeploymentArtifactTypeConfig deploymentAcceptedTypes = deploymentConfigGetter.getDeploymentArtifactConfig(); + if (!parentType.equals(NodeTypeEnum.Resource) && !parentType.equals(NodeTypeEnum.Service) && !parentType.equals(NodeTypeEnum.ResourceInstance)) { + log.debug("parent type of artifact can be either resource or service"); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return; + } + + if (deploymentAcceptedTypes == null) { + log.debug("parent type of artifact can be either resource or service"); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType())); + return; + } else { + acceptedTypes = deploymentAcceptedTypes.getAcceptedTypes(); + } + /* + * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted. + * + * if ((!artifactType.equals(ArtifactTypeEnum.OTHER) && !artifactType.equals(ArtifactTypeEnum.HEAT_ARTIFACT )) && (acceptedTypes == null || acceptedTypes.isEmpty()) ) { log.debug( "No accepted types found for type {}, parent type {}", + * fileType, parentType.getName()); String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); String configEntryMissing = (parentType.equals(NodeTypeEnum.Resource)) ? "resourceDeploymentArtifacts:" + fileType : + * "serviceDeploymentArtifacts:" + fileType; BeEcompErrorManager.getInstance().processEcompError(EcompErrorName. BeMissingConfigurationError, methodName, configEntryMissing); BeEcompErrorManager.getInstance().logBeMissingConfigurationError( + * methodName, configEntryMissing); responseWrapper.setInnerElement(componentsUtils.getResponseFormat( ActionStatus.GENERAL_ERROR)); return; } + */ + + String artifactName = artifactInfo.getArtifactName(); + String fileExtension = GeneralUtility.getFilenameExtension(artifactName); + // Pavel - File extension validation is case-insensitive - Ella, + // 21/02/2016 + if (acceptedTypes != null && !acceptedTypes.isEmpty() && !acceptedTypes.contains(fileExtension.toLowerCase())) { + log.debug("File extension \"{}\" is not allowed for {} which is of type:{}", fileExtension, artifactName, fileType); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, fileType)); + return; + } + } + + private Either<Boolean, ResponseFormat> validateHeatEnvDeploymentArtifact(Component parentComponent, String parentId, String userId, boolean isCreate, ArtifactDefinition artifactInfo, NodeTypeEnum parentType) { + + Wrapper<ResponseFormat> errorWrapper = new Wrapper<ResponseFormat>(); + Wrapper<ArtifactDefinition> heatMDWrapper = new Wrapper<ArtifactDefinition>(); + Wrapper<byte[]> payloadWrapper = new Wrapper<>(); + + if (errorWrapper.isEmpty()) { + validateValidYaml(errorWrapper, artifactInfo); + } + + if (errorWrapper.isEmpty()) { + // Validate Heat Exist + validateHeatExist(artifactInfo.getUniqueId(), errorWrapper, heatMDWrapper, getDeploymentArtifacts(parentComponent, parentType, parentId)); + } + + if (errorWrapper.isEmpty() && isCreate) { + // Validate Only Single HeatEnv Artifact + validateSingleArtifactType(errorWrapper, ArtifactTypeEnum.HEAT_ENV, parentComponent, parentType, parentId); + } + + if (errorWrapper.isEmpty() && !heatMDWrapper.isEmpty()) { + fillArtifactPayloadValidation(errorWrapper, payloadWrapper, heatMDWrapper.getInnerElement()); + } + + if (errorWrapper.isEmpty() && !heatMDWrapper.isEmpty()) { + validateEnvVsHeat(errorWrapper, artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement()); + } + + // Init Response + Either<Boolean, ResponseFormat> eitherResponse; + if (errorWrapper.isEmpty()) { + eitherResponse = Either.left(true); + } else { + eitherResponse = Either.right(errorWrapper.getInnerElement()); + } + return eitherResponse; + } + + public void fillArtifactPayloadValidation(Wrapper<ResponseFormat> errorWrapper, Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactDefinition) { + if (artifactDefinition.getPayloadData() == null || artifactDefinition.getPayloadData().length == 0) { + Either<Boolean, ResponseFormat> fillArtifactPayload = fillArtifactPayload(payloadWrapper, artifactDefinition); + if (fillArtifactPayload.isRight()) { + errorWrapper.setInnerElement(fillArtifactPayload.right().value()); + log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName()); + } + } else { + payloadWrapper.setInnerElement(artifactDefinition.getPayloadData()); + } + } + + public Either<Boolean, ResponseFormat> fillArtifactPayload(Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactMD) { + Either<Boolean, ResponseFormat> result = Either.left(true); + Either<ESArtifactData, CassandraOperationStatus> eitherArtifactData = artifactCassandraDao.getArtifact(artifactMD.getEsId()); + // Either<ESArtifactData, ResourceUploadStatus> eitherArtifactData = + // esCatalogDao.getArtifact(artifactMD.getEsId()); + if (eitherArtifactData.isLeft()) { + byte[] data = eitherArtifactData.left().value().getDataAsArray(); + if (!GeneralUtility.isBase64Encoded(data)) { + data = Base64.encodeBase64(data); + } + payloadWrapper.setInnerElement(data); + } else { + StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus)); + result = Either.right(responseFormat); + } + return result; + + } + + @SuppressWarnings("unchecked") + private void validateEnvVsHeat(Wrapper<ResponseFormat> errorWrapper, ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) { + + String envPayload = (GeneralUtility.isBase64Encoded(envArtifact.getPayloadData())) ? new String(Base64.decodeBase64(envArtifact.getPayloadData())) : new String(envArtifact.getPayloadData()); + Map<String, Object> heatEnvToscaJson = (Map<String, Object>) new Yaml().load(envPayload); + + String heatDecodedPayload = (GeneralUtility.isBase64Encoded(heatPayloadData)) ? new String(Base64.decodeBase64(heatPayloadData)) : new String(heatPayloadData); + Map<String, Object> heatToscaJson = (Map<String, Object>) new Yaml().load(heatDecodedPayload); + + Either<Map<String, Object>, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils.findFirstToscaMapElement(heatEnvToscaJson, ToscaTagNamesEnum.PARAMETERS); + Either<Map<String, Object>, ResultStatusEnum> eitherHeatProperties = ImportUtils.findFirstToscaMapElement(heatToscaJson, ToscaTagNamesEnum.PARAMETERS); + if (eitherHeatEnvProperties.isRight()) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.CORRUPTED_FORMAT, "Heat Env"); + errorWrapper.setInnerElement(responseFormat); + log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName()); + } else if (eitherHeatProperties.isRight()) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(), heatArtifact.getArtifactName()); + errorWrapper.setInnerElement(responseFormat); + log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(), heatArtifact.getArtifactName()); + } else { + Set<String> heatPropertiesKeys = eitherHeatProperties.left().value().keySet(); + Set<String> heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet(); + heatEnvPropertiesKeys.removeAll(heatPropertiesKeys); + if (heatEnvPropertiesKeys.size() > 0) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(), heatArtifact.getArtifactName()); + errorWrapper.setInnerElement(responseFormat); + } + } + } + + private void validateValidYaml(Wrapper<ResponseFormat> errorWrapper, ArtifactDefinition artifactInfo) { + YamlToObjectConverter yamlConvertor = new YamlToObjectConverter(); + boolean isYamlValid = yamlConvertor.isValidYaml(artifactInfo.getPayloadData()); + if (!isYamlValid) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType()); + errorWrapper.setInnerElement(responseFormat); + log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName()); + } + } + + public boolean isValidXml(byte[] xmlToParse) { + XMLReader parser = new SAXParser(); + boolean isXmlValid = true; + try { + parser.parse(new InputSource(new ByteArrayInputStream(xmlToParse))); + } catch (IOException | SAXException e) { + isXmlValid = false; + } + return isXmlValid; + } + + public boolean isValidJson(byte[] jsonToParse) { + String parsed = new String(jsonToParse); + try { + gson.fromJson(parsed, Object.class); + } catch (Exception e) { + return false; + } + return true; + } + + public void validateSingleArtifactType(Wrapper<ResponseFormat> errorWrapper, ArtifactTypeEnum allowedArtifactType, Component parentComponent, NodeTypeEnum parentType, String parentRiId) { + boolean typeArtifactFound = false; + // Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = + // (parentType == NodeTypeEnum.Resource) ? + // informationDeployedArtifactsBusinessLogic.getAllDeployableArtifacts((Resource) + // parentComponent).iterator() + // : getDeploymentArtifacts(parentComponent, parentType).iterator(); + + Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, parentType, parentRiId).iterator(); + + while (!typeArtifactFound && parentDeploymentArtifactsItr.hasNext()) { + ArtifactTypeEnum foundArtifactType = ArtifactTypeEnum.findType(parentDeploymentArtifactsItr.next().getArtifactType()); + typeArtifactFound = (foundArtifactType == allowedArtifactType); + } + if (typeArtifactFound) { + String parentName = parentComponent.getName(); + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS, parentType.name(), parentName, allowedArtifactType.getType(), allowedArtifactType.getType()); + + errorWrapper.setInnerElement(responseFormat); + log.debug("Can't upload artifact of type: {}, because another artifact of this type already exist.", allowedArtifactType.getType()); + + } + } + + public void validateSingleDeploymentArtifactName(Wrapper<ResponseFormat> errorWrapper, String artifactName, Component parentComponent, NodeTypeEnum parentType) { + boolean artifactNameFound = false; + // Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = + // (parentType == NodeTypeEnum.Resource) ? + // informationDeployedArtifactsBusinessLogic.getAllDeployableArtifacts((Resource) + // parentComponent).iterator() + // : getDeploymentArtifacts(parentComponent, parentType).iterator(); + + Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, parentType, null).iterator(); + + while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) { + artifactNameFound = (artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName())); + } + if (artifactNameFound) { + String parentName = parentComponent.getName(); + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, parentType.name(), parentName, artifactName); + + errorWrapper.setInnerElement(responseFormat); + log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName); + + } + } + + private void validateHeatExist(String heatEnvId, Wrapper<ResponseFormat> errorWrapper, Wrapper<ArtifactDefinition> heatArtifactMDWrapper, Collection<ArtifactDefinition> parentDeploymentArtifacts) { + boolean heatFound = false; + Either<ArtifactDefinition, StorageOperationStatus> res = artifactOperation.getHeatArtifactByHeatEnvId(heatEnvId, true); + if (res.isRight()) { + return; + } + ArtifactDefinition heatArtifact = res.left().value(); + Iterator<ArtifactDefinition> parentArtifactsItr = parentDeploymentArtifacts.iterator(); + while (!heatFound && parentArtifactsItr.hasNext()) { + ArtifactDefinition currArtifact = parentArtifactsItr.next(); + if (heatArtifact.getUniqueId().equals(currArtifact.getUniqueId())) { + heatFound = true; + heatArtifactMDWrapper.setInnerElement(currArtifact); + log.trace("In validateHeatExist found artifact {}", currArtifact); + /* + * ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(currArtifact.getArtifactType()); if(artifactType == ArtifactTypeEnum.HEAT || artifactType == ArtifactTypeEnum.HEAT_VOL || artifactType == ArtifactTypeEnum.HEAT_NET){ + * heatFound = true; } if (heatFound) { heatArtifactMDWrapper.setInnerElement(currArtifact); } + */ + } + } + if (!heatFound) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.MISSING_HEAT); + errorWrapper.setInnerElement(responseFormat); + log.debug("Can't create heat env artifact because No heat Artifact exist."); + } + + } + + private Either<Boolean, ResponseFormat> validateHeatDeploymentArtifact(Component parentComponent, String userId, boolean isCreate, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact, NodeTypeEnum parentType) { + log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel()); + // timeout > 0 for HEAT artifacts + Integer timeout = artifactInfo.getTimeout(); + Integer defaultTimeout = (isCreate) ? defaultHeatTimeout : currentArtifact.getTimeout(); + if (timeout == null) { + artifactInfo.setTimeout(defaultTimeout); + // HEAT artifact but timeout is invalid + } else if (timeout < 1) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_INVALID_TIMEOUT)); + } + + // US649856 - Allow several HEAT files on Resource + /* + * if (isCreate) { Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); validateSingleArtifactType(errorWrapper, ArtifactTypeEnum.findType(artifactInfo.getArtifactType()), parentComponent, parentType); if (!errorWrapper.isEmpty()) { return + * Either.right(errorWrapper.getInnerElement()); } } + */ + + log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel()); + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateResourceType(ResourceTypeEnum resourceType, ArtifactDefinition artifactInfo, List<String> typeList) { + String listToString = (typeList != null) ? typeList.toString() : ""; + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, artifactInfo.getArtifactName(), listToString, resourceType.getValue()); + Either<Boolean, ResponseFormat> either = Either.right(responseFormat); + String resourceTypeName = resourceType.name(); + if (typeList != null && typeList.contains(resourceTypeName)) { + either = Either.left(true); + } + return either; + } + + private Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers(ArtifactDefinition artifactInfo, String artifactType) { + if (artifactInfo.getHeatParameters() != null) { + for (HeatParameterDefinition heatParam : artifactInfo.getHeatParameters()) { + String parameterType = heatParam.getType(); + HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType); + String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType(); + if (heatParameterType == null) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam.getType()); + return Either.right(responseFormat); + } + + StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.debug("Heat parameter {} is invalid. Status is: {}", heatParam.getName(), validateAndUpdateProperty); + ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE; + ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, artifactTypeStr, heatParam.getType(), heatParam.getName()); + return Either.right(responseFormat); + } + } + } + return Either.left(artifactInfo); + } + + public List<ArtifactDefinition> getDeploymentArtifacts(Component parentComponent, NodeTypeEnum parentType, String ciId) { + List<ArtifactDefinition> deploymentArtifacts = new ArrayList<>(); + if (parentComponent.getDeploymentArtifacts() != null && ciId != null) { + if (NodeTypeEnum.ResourceInstance == parentType) { + Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parentComponent, ciId, null, null, null); + if (getRI.isRight()) { + return deploymentArtifacts; + } + ComponentInstance ri = getRI.left().value(); + deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values()); + } else { + deploymentArtifacts.addAll(parentComponent.getDeploymentArtifacts().values()); + } + } + return deploymentArtifacts; + } + + private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) { + // on create if null add informational to current + if (artifactInfo.getArtifactGroupType() == null) { + artifactInfo.setArtifactGroupType(type); + } + if (artifactInfo.getUniqueId() != null) { + log.error("artifact uniqid cannot be set ignoring"); + } + artifactInfo.setUniqueId(null); + + if (artifactInfo.getArtifactRef() != null) { + log.error("artifact ref cannot be set ignoring"); + } + artifactInfo.setArtifactRef(null); + + if (artifactInfo.getArtifactRepository() != null) { + log.error("artifact repository cannot be set ignoring"); + } + artifactInfo.setArtifactRepository(null); + + if (artifactInfo.getUserIdCreator() != null) { + log.error("creator uuid cannot be set ignoring"); + } + artifactInfo.setArtifactCreator(user.getUserId()); + + if (artifactInfo.getUserIdLastUpdater() != null) { + log.error("userId of last updater cannot be set ignoring"); + } + artifactInfo.setUserIdLastUpdater(user.getUserId()); + + if (artifactInfo.getCreatorFullName() != null) { + log.error("creator Full name cannot be set ignoring"); + } + String fullName = user.getFirstName() + " " + user.getLastName(); + artifactInfo.setUpdaterFullName(fullName); + + if (artifactInfo.getUpdaterFullName() != null) { + log.error("updater Full name cannot be set ignoring"); + } + artifactInfo.setUpdaterFullName(fullName); + + if (artifactInfo.getCreationDate() != null) { + log.error("Creation Date cannot be set ignoring"); + } + long time = System.currentTimeMillis(); + artifactInfo.setCreationDate(time); + + if (artifactInfo.getLastUpdateDate() != null) { + log.error("Last Update Date cannot be set ignoring"); + } + artifactInfo.setLastUpdateDate(time); + + if (artifactInfo.getEsId() != null) { + log.error("es id cannot be set ignoring"); + } + artifactInfo.setEsId(null); + + } + + private Either<ArtifactDefinition, ResponseFormat> fetchCurrentArtifact(boolean isCreate, String artifactId) { + Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactOperation.getArtifactById(artifactId, true); + if (isCreate == false && artifactById.isRight()) { + // in case of update artifact must be + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeArtifactMissingError, "Artifact Update / Upload", artifactId); + BeEcompErrorManager.getInstance().logBeArtifactMissingError("Artifact Update / Upload", artifactId); + log.debug("Failed to fetch artifact {}. error: {}", artifactId, artifactById.right().value()); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(artifactById.right().value()), artifactId)); + } + if (isCreate && artifactById.isLeft()) { + log.debug("Artifact {} already exist", artifactId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactById.left().value().getArtifactLabel())); + } + ArtifactDefinition currentArtifactInfo = null; + if (artifactById.isLeft()) { + // get previous value + currentArtifactInfo = artifactById.left().value(); + } + return Either.left(currentArtifactInfo); + } + + private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String resourceId, boolean isCreate, String artifactId, ArtifactDefinition artifactInfo, String interfaceName, String operationName, ArtifactDefinition currentArtifactInfo, + NodeTypeEnum parentType) { + String artifactLabel = artifactInfo.getArtifactLabel(); + + if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingArtifactInformationError, "Artifact Update / Upload", "artifactLabel"); + BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel"); + log.debug("missing artifact logical name for component {}", resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL)); + } + if (isCreate && !artifactInfo.getMandatory()) { + + if (operationName != null) { + if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) { + log.debug("artifact label cannot be set {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED)); + } else { + artifactLabel = operationName; + } + } + String displayName = ValidationUtils.cleanArtifactDisplayName(artifactLabel); + artifactInfo.setArtifactDisplayName(displayName); + + if (!ValidationUtils.validateArtifactLabel(artifactLabel)) { + log.debug("Invalid format form Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel); + + if (artifactLabel.isEmpty()) { + log.debug("missing normalized artifact logical name for component {}", resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL)); + } + + if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) { + log.debug("Invalid lenght form Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH))); + } + if (!validateLabelUniqueness(resourceId, artifactLabel, parentType)) { + log.debug("Non unique Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel)); + } + } + artifactInfo.setArtifactLabel(artifactLabel); + + if (currentArtifactInfo != null && !currentArtifactInfo.getArtifactLabel().equals(artifactInfo.getArtifactLabel())) { + log.info("Logical artifact's name cannot be changed {}", artifactId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED)); + } + return Either.left(ActionStatus.OK); + } + + private boolean validateLabelUniqueness(String parentId, String artifactLabel, NodeTypeEnum parentType) { + boolean isUnique = true; + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = artifactOperation.getArtifacts(parentId, parentType, true); + if (artifacts.isLeft()) { + for (String label : artifacts.left().value().keySet()) { + if (label.equals(artifactLabel)) { + isUnique = false; + break; + } + } + } + if (parentType.equals(NodeTypeEnum.Resource)) { + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation.getAllInterfacesOfResource(parentId, true); + if (allInterfacesOfResource.isLeft()) { + for (InterfaceDefinition interace : allInterfacesOfResource.left().value().values()) { + for (Operation operation : interace.getOperations().values()) { + if (operation.getImplementation() != null && operation.getImplementation().getArtifactLabel().equals(artifactLabel)) { + isUnique = false; + break; + } + } + } + } + } + return isUnique; + } + + private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName, String operationName) { + String id = artifactId; + if (artifactId == null || artifactId.isEmpty()) { + String uniqueId = null; + if (interfaceName != null && operationName != null) { + uniqueId = UniqueIdBuilder.buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo.getArtifactLabel()); + } else { + uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel()); + } + artifactInfo.setUniqueId(uniqueId); + artifactInfo.setEsId(uniqueId); + id = uniqueId; + } else { + artifactInfo.setUniqueId(artifactId); + artifactInfo.setEsId(artifactId); + } + return id; + } + + private Either<ActionStatus, ResponseFormat> validateArtifactType(String userId, ArtifactDefinition artifactInfo, NodeTypeEnum parentType) { + if (artifactInfo.getArtifactType() == null || artifactInfo.getArtifactType().isEmpty()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingArtifactInformationError, "Artifact Upload / Update"); + BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel"); + log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE)); + } + + boolean artifactTypeExist = false; + Either<List<ArtifactType>, ActionStatus> allArtifactTypes = null; + ArtifactGroupTypeEnum artifactGroupType = artifactInfo.getArtifactGroupType(); + + if ((artifactGroupType != null) && artifactGroupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) { + allArtifactTypes = getDeploymentArtifactTypes(userId, artifactInfo, parentType); + } else { + + allArtifactTypes = elementOperation.getAllArtifactTypes(); + } + if (allArtifactTypes.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidConfigurationError, "Artifact Upload / Update", "artifactTypes", allArtifactTypes.right().value().name()); + BeEcompErrorManager.getInstance().logBeInvalidConfigurationError("Artifact Upload / Update", "artifactTypes", allArtifactTypes.right().value().name()); + log.debug("Failed to retrieve list of suported artifact types. error: {}", allArtifactTypes.right().value()); + return Either.right(componentsUtils.getResponseFormatByUserId(allArtifactTypes.right().value(), userId)); + } + + for (ArtifactType type : allArtifactTypes.left().value()) { + if (type.getName().equalsIgnoreCase(artifactInfo.getArtifactType())) { + artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase()); + artifactTypeExist = true; + break; + } + } + + if (!artifactTypeExist) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidTypeError, "Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(), "Artifact " + artifactInfo.getArtifactName()); + BeEcompErrorManager.getInstance().logBeInvalidTypeError("Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(), "Artifact " + artifactInfo.getArtifactName()); + log.debug("Not supported artifact type = {}", artifactInfo.getArtifactType()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType())); + } + + return Either.left(ActionStatus.OK); + } + + private Either<List<ArtifactType>, ActionStatus> getDeploymentArtifactTypes(String userId, ArtifactDefinition artifactInfo, NodeTypeEnum parentType) { + + Map<String, DeploymentArtifactTypeConfig> deploymentArtifacts = null; + List<ArtifactType> artifactTypes = new ArrayList<ArtifactType>(); + + if (parentType.equals(NodeTypeEnum.Service)) { + deploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts(); + } else if (parentType.equals(NodeTypeEnum.ResourceInstance)) { + deploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts(); + } else { + deploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts(); + } + if (deploymentArtifacts != null) { + for (String artifactType : deploymentArtifacts.keySet()) { + ArtifactType artifactT = new ArtifactType(); + artifactT.setName(artifactType); + artifactTypes.add(artifactT); + } + return Either.left(artifactTypes); + } else { + return Either.right(ActionStatus.GENERAL_ERROR); + } + + } + + private Either<Boolean, ResponseFormat> validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) { + if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD)); + } + return Either.left(true); + + } + + private Either<Boolean, ResponseFormat> validateAndSetArtifactname(ArtifactDefinition artifactInfo) { + if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME)); + } + + String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName()); + if (normalizeFileName == null || normalizeFileName.isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME)); + } + artifactInfo.setArtifactName(normalizeFileName); + + if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH))); + } + + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) { + if (artifactInfo.getArtifactType() == null || artifactInfo.getArtifactType().isEmpty()) { + log.info("artifact type is missing operation ignored"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE)); + } + + if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) { + log.info("artifact type cannot be changed operation ignored"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + return Either.left(true); + } + + private Either<ArtifactDefinition, ResponseFormat> validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) { + if (artifactInfo.getArtifactGroupType() == null) { + artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType()); + } + + else if (!currentArtifact.getArtifactGroupType().getType().equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) { + log.info("artifact group type cannot be changed. operation failed"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + return Either.left(artifactInfo); + } + + private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact, ArtifactGroupTypeEnum type) { + + // on update if null add informational to current + if (currentArtifact.getArtifactGroupType() == null && type != null) { + currentArtifact.setArtifactGroupType(type); + } + + if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) { + log.error("artifact uniqid cannot be set ignoring"); + } + artifactInfo.setUniqueId(currentArtifact.getUniqueId()); + + if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef().equals(artifactInfo.getArtifactRef())) { + log.error("artifact ref cannot be set ignoring"); + } + artifactInfo.setArtifactRef(currentArtifact.getArtifactRef()); + + if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository().equals(artifactInfo.getArtifactRepository())) { + log.error("artifact repository cannot be set ignoring"); + } + artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository()); + + if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator().equals(artifactInfo.getUserIdCreator())) { + log.error("creator uuid cannot be set ignoring"); + } + artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator()); + + if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator().equals(artifactInfo.getArtifactCreator())) { + log.error("artifact creator cannot be set ignoring"); + } + artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator()); + + if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater().equals(artifactInfo.getUserIdLastUpdater())) { + log.error("userId of last updater cannot be set ignoring"); + } + artifactInfo.setUserIdLastUpdater(user.getUserId()); + + if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName().equals(artifactInfo.getCreatorFullName())) { + log.error("creator Full name cannot be set ignoring"); + } + artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName()); + + if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName().equals(artifactInfo.getUpdaterFullName())) { + log.error("updater Full name cannot be set ignoring"); + } + String fullName = user.getFirstName() + " " + user.getLastName(); + artifactInfo.setUpdaterFullName(fullName); + + if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate().equals(artifactInfo.getCreationDate())) { + log.error("Creation Date cannot be set ignoring"); + } + artifactInfo.setCreationDate(currentArtifact.getCreationDate()); + + if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate().equals(artifactInfo.getLastUpdateDate())) { + log.error("Last Update Date cannot be set ignoring"); + } + long time = System.currentTimeMillis(); + artifactInfo.setLastUpdateDate(time); + + if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) { + log.error("es id cannot be set ignoring"); + } + artifactInfo.setEsId(currentArtifact.getUniqueId()); + + if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName().equals(artifactInfo.getArtifactDisplayName())) { + log.error(" Artifact Display Name cannot be set ignoring"); + } + artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName()); + + if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi().equals(artifactInfo.getServiceApi())) { + log.debug("serviceApi cannot be set. ignoring."); + } + artifactInfo.setServiceApi(currentArtifact.getServiceApi()); + + if (artifactInfo.getArtifactGroupType() != null && !currentArtifact.getArtifactGroupType().equals(artifactInfo.getArtifactGroupType())) { + log.debug("artifact group cannot be set. ignoring."); + } + artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType()); + + artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion()); + + if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID().isEmpty() && !currentArtifact.getArtifactUUID().equals(artifactInfo.getArtifactUUID())) { + log.debug("artifact UUID cannot be set. ignoring."); + } + artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID()); + + if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo.getHeatParameters().isEmpty() && !currentArtifact.getHeatParameters().isEmpty()) { + checkAndSetUnupdatableHeatParams(artifactInfo.getHeatParameters(), currentArtifact.getHeatParameters()); + } + } + + private void checkAndSetUnupdatableHeatParams(List<HeatParameterDefinition> heatParameters, List<HeatParameterDefinition> currentParameters) { + + Map<String, HeatParameterDefinition> currentParametersMap = getMapOfParameters(currentParameters); + for (HeatParameterDefinition parameter : heatParameters) { + HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId()); + + if (currentParam != null) { + + if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) { + log.debug("heat parameter name cannot be updated ({}). ignoring.", parameter.getName()); + parameter.setName(currentParam.getName()); + } + if (parameter.getDefaultValue() != null && !parameter.getDefaultValue().equalsIgnoreCase(currentParam.getDefaultValue())) { + log.debug("heat parameter defaultValue cannot be updated ({}). ignoring.", parameter.getDefaultValue()); + parameter.setDefaultValue(currentParam.getDefaultValue()); + } + if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) { + log.debug("heat parameter type cannot be updated ({}). ignoring.", parameter.getType()); + parameter.setType(currentParam.getType()); + } + if (parameter.getDescription() != null && !parameter.getDescription().equalsIgnoreCase(currentParam.getDescription())) { + log.debug("heat parameter description cannot be updated ({}). ignoring.", parameter.getDescription()); + parameter.setDescription(currentParam.getDescription()); + } + + // check and set current value + if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) { + log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue()); + parameter.setCurrentValue(currentParam.getDefaultValue()); + } + } + } + } + + private Map<String, HeatParameterDefinition> getMapOfParameters(List<HeatParameterDefinition> currentParameters) { + + Map<String, HeatParameterDefinition> currentParamsMap = new HashMap<String, HeatParameterDefinition>(); + for (HeatParameterDefinition param : currentParameters) { + currentParamsMap.put(param.getUniqueId(), param); + } + return currentParamsMap; + } + + private Either<Boolean, ResponseFormat> validateAndServiceApiUrl(ArtifactDefinition artifactInfo) { + if (!ValidationUtils.validateStringNotEmpty(artifactInfo.getApiUrl())) { + log.debug("Artifact url cannot be empty."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL)); + } + artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase()); + + if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL)); + } + if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH))); + } + + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateAndCleanDescription(ArtifactDefinition artifactInfo) { + if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) { + log.debug("Artifact description cannot be empty."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION)); + } + String description = artifactInfo.getDescription(); + description = ValidationUtils.removeNoneUtf8Chars(description); + description = ValidationUtils.normaliseWhitespace(description); + description = ValidationUtils.stripOctets(description); + description = ValidationUtils.removeHtmlTagsOnly(description); + if (!ValidationUtils.validateIsEnglish(description)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION, String.valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH))); + } + artifactInfo.setDescription(description); + return Either.left(true); + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> updateArtifactFlow(org.openecomp.sdc.be.model.Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo, User user, byte[] decodedPayload, + ComponentTypeEnum componentType, AuditingActionEnum auditingAction, String interfaceType, String operationName) { + ESArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload); + String prevArtifactId = null; + String currArtifactId = artifactId; + + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp = null; + Either<ArtifactDefinition, Operation> insideEither = null; + + if (artifactData == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Update Artifact"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Update Artifact"); + log.debug("Failed to create artifact object for ES."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + } + log.debug("Try to update entry on graph"); + String artifactUniqueId = null; + ArtifactDefinition artifactDefinition = null; + StorageOperationStatus error = null; + + boolean isLeft = false; + if (interfaceType != null && operationName != null) { + // lifecycle artifact + Operation operation = convertToOperation(artifactInfo, operationName); + + Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation.updateInterfaceOperation(parentId, interfaceType, operationName, operation); + + isLeft = result.isLeft(); + if (isLeft) { + artifactUniqueId = result.left().value().getUniqueId(); + artifactDefinition = result.left().value().getImplementation(); + + insideEither = Either.right(result.left().value()); + resultOp = Either.left(insideEither); + } else { + error = result.right().value(); + } + } else { + + NodeTypeEnum convertParentType = convertParentType(componentType); + Either<ArtifactDefinition, StorageOperationStatus> result = artifactOperation.updateArifactOnResource(artifactInfo, parentId, artifactId, convertParentType, true); + isLeft = result.isLeft(); + if (isLeft) { + artifactUniqueId = result.left().value().getUniqueId(); + artifactDefinition = result.left().value(); + + insideEither = Either.left(result.left().value()); + resultOp = Either.left(insideEither); + } else { + error = result.right().value(); + } + } + if (isLeft) { + log.debug("Enty on graph is updated. Update artifact in ES"); + boolean res; + // Changing previous and current artifactId for auditing + prevArtifactId = currArtifactId; + currArtifactId = artifactDefinition.getUniqueId(); + + if (!artifactDefinition.getUniqueId().equals(artifactId)) { + // different ids ==> artifact node was cloned . + // if no data in request get from ES + if (decodedPayload == null) { + if (!artifactDefinition.getMandatory() || artifactDefinition.getEsId() != null) { + Either<ESArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactId); + // Either<ESArtifactData, ResourceUploadStatus> + // artifactfromES = daoUploader.getArtifact(artifactId); + if (artifactFromCassandra.isRight()) { + log.debug("Failed to get artifact data from ES for artifact id {}", artifactId); + StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromCassandra.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus)); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + } + // clone data to new artifact + artifactData.setData(artifactFromCassandra.left().value().getData()); + } + } + artifactData.setId(artifactDefinition.getUniqueId()); + // create new entry in ES + res = true; + if (artifactData.getData() != null) { + res = saveArtifacts(artifactData, parentId, false); + // set on graph object id of artifact in ES! + if (res) { + artifactInfo.setEsId(artifactData.getId()); + Either<ArtifactDefinition, StorageOperationStatus> updateArifactRes = artifactOperation.updateArifactDefinition(artifactInfo, true); + if (updateArifactRes.isRight()) { + log.debug("Failed to update artifact on graph - {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateArifactRes.right().value())); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + + } else { + insideEither = Either.left(updateArifactRes.left().value()); + resultOp = Either.left(insideEither); + } + } + } + } else { + res = true; + if (artifactData.getData() != null) { + // override artifact in ES + res = saveArtifacts(artifactData, parentId, true); + if (res && artifactDefinition.getMandatory()) { + artifactInfo.setEsId(artifactData.getId()); + Either<ArtifactDefinition, StorageOperationStatus> updateArifactRes = artifactOperation.updateArifactDefinition(artifactInfo, true); + if (updateArifactRes.isRight()) { + log.debug("Failed to update artifact on graph - {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactRes.right().value()), artifactId); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + + } + } + } + } + if (res) { + log.debug("Artifact saved into ES - {}", artifactUniqueId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + // resultOp = Either.left(result.left().value()); + // return resultOp; + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Update Artifact"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Update Artifact"); + log.debug("Failed to save the artifact."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + // return resultOp; + } + } else { + log.debug("Failed to create entry on graph for artifact {}", artifactInfo.getArtifactDisplayName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(error), artifactInfo.getArtifactDisplayName()); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + // return resultOp; + } + + return resultOp; + } + + private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) { + log.trace("Starting payload handling"); + byte[] payload = artifactInfo.getPayloadData(); + byte[] decodedPayload = null; + + if (payload != null && payload.length != 0) { + + decodedPayload = Base64.decodeBase64(payload); + if (decodedPayload.length == 0) { + log.debug("Failed to decode the payload."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + return Either.right(responseFormat); + } + + String checkSum = GeneralUtility.calculateMD5ByByteArray(decodedPayload); + artifactInfo.setArtifactChecksum(checkSum); + log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum); + + // Specific payload validations of different types + Either<Boolean, ResponseFormat> isValidPayload = Either.left(true); + if (isDeploymentArtifact(artifactInfo)) { + log.trace("Starting deployment artifacts payload validation"); + String artifactType = artifactInfo.getArtifactType(); + if (ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType) + || ArtifactTypeEnum.HEAT_ENV.getType().equalsIgnoreCase(artifactType)) { + isValidPayload = validateDeploymentHeatPayload(decodedPayload, artifactType); + if (isValidPayload.isLeft()) { + isValidPayload = extractHeatParameters(artifactInfo); + } + } else if (ArtifactTypeEnum.YANG_XML.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.VNF_CATALOG.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.VF_LICENSE.getType().equalsIgnoreCase(artifactType) + || ArtifactTypeEnum.VENDOR_LICENSE.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.getType().equalsIgnoreCase(artifactType) + || ArtifactTypeEnum.MODEL_QUERY_SPEC.getType().equalsIgnoreCase(artifactType)) { + isValidPayload = validateYangPayload(decodedPayload, artifactType); + // else + // if(ArtifactTypeEnum.APPC_CONFIG.getType().equalsIgnoreCase(artifactType) + // || ){ + } else if (ArtifactTypeEnum.DCAE_INVENTORY_JSON.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.DCAE_INVENTORY_TOSCA.getType().equalsIgnoreCase(artifactType)) { + String artifactFileName = artifactInfo.getArtifactName(); + String fileExtension = GeneralUtility.getFilenameExtension(artifactFileName).toLowerCase(); + switch (fileExtension) { + case "xml": + isValidPayload = validateYangPayload(decodedPayload, artifactType); + break; + case "json": + isValidPayload = validateJsonPayload(decodedPayload, artifactType); + break; + case "yml": + case "yaml": + isValidPayload = validateYmlPayload(decodedPayload, artifactType); + break; + } + } + } + if (isValidPayload.isRight()) { + ResponseFormat responseFormat = isValidPayload.right().value(); + return Either.right(responseFormat); + } + + } // null/empty payload is normal if called from metadata update ONLY. + // The validation of whether this is metadata/payload update case is + // currently done separately + else { + if (!isArtifactMetadataUpdate) { + log.debug("Payload is missing."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD); + return Either.right(responseFormat); + } + } + log.trace("Ended payload handling"); + return Either.left(decodedPayload); + } + + private Either<Boolean, ResponseFormat> validateDeploymentHeatPayload(byte[] payload, String artifactType) { + // Basic YAML validation + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + if (!yamlToObjectConverter.isValidYaml(payload)) { + log.debug("Invalid YAML format"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML, artifactType); + return Either.right(responseFormat); + } + if (!ArtifactTypeEnum.HEAT_ENV.getType().equalsIgnoreCase(artifactType)) { + // HEAT specific YAML validation + DeploymentArtifactHeatConfiguration heatConfiguration = yamlToObjectConverter.convert(payload, DeploymentArtifactHeatConfiguration.class); + if (heatConfiguration == null || heatConfiguration.getHeat_template_version() == null || heatConfiguration.getResources() == null) { + log.debug("HEAT doesn't contain required \"heat_template_version\" and \"resources\" sections "); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactType); + return Either.right(responseFormat); + } + } + + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateYmlPayload(byte[] decodedPayload, String artifactType) { + Either<Boolean, ResponseFormat> res = Either.left(true); + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + if (!yamlToObjectConverter.isValidYaml(decodedPayload)) { + log.debug("Invalid YAML format"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML, artifactType); + res = Either.right(responseFormat); + } + + return res; + } + + private Either<Boolean, ResponseFormat> validateYangPayload(byte[] payload, String artifactType) { + boolean isXmlValid = isValidXml(payload); + if (!isXmlValid) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.INVALID_XML, artifactType); + log.debug("Invalid XML content"); + return Either.right(responseFormat); + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateJsonPayload(byte[] payload, String type) { + boolean isJsonValid = isValidJson(payload); + if (!isJsonValid) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.INVALID_JSON, type); + log.debug("Invalid JSON content"); + return Either.right(responseFormat); + } + return Either.left(true); + } + + public void handleTransaction(Either<Operation, ResponseFormat> opState) { + if (opState == null || opState.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + + public Either<Operation, ResponseFormat> deleteArtifactByInterface(String resourceId, String interfaceType, String operationName, String userId, String artifactId, ImmutablePair<User, Resource> userResourceAuditPair, boolean shouldLock, + boolean inTransaction) { + User user = new User(); + user.setUserId(userId); + Either<Resource, StorageOperationStatus> parent = resourceOperation.getResource(resourceId); + if (parent.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(parent.right().value())); + return Either.right(responseFormat); + } + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleDelete = handleDelete(resourceId, artifactId, user, AuditingActionEnum.ARTIFACT_DELETE, ComponentTypeEnum.RESOURCE, parent.left().value(), interfaceType, operationName, + false, inTransaction); + if (handleDelete.isRight()) { + return Either.right(handleDelete.right().value()); + } + Either<ArtifactDefinition, Operation> result = handleDelete.left().value(); + return Either.left(result.right().value()); + + } + + public StorageOperationStatus deleteAllComponentArtifactsIfNotOnGraph(List<ArtifactDefinition> artifacts) { + + if (artifacts != null && !artifacts.isEmpty()) { + for (ArtifactDefinition artifactDefinition : artifacts) { + String esId = artifactDefinition.getEsId(); + if (esId != null && !esId.isEmpty()) { + StorageOperationStatus deleteIfNotOnGraph = deleteIfNotOnGraph(artifactDefinition.getUniqueId(), esId, false); + if (!deleteIfNotOnGraph.equals(StorageOperationStatus.OK)) { + return deleteIfNotOnGraph; + } + } + } + } + return StorageOperationStatus.OK; + } + + private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) { + Operation op = new Operation(); + long time = System.currentTimeMillis(); + op.setCreationDate(time); + + String artifactName = artifactInfo.getArtifactName(); + artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName)); + + op.setImplementation(artifactInfo); + op.setLastUpdateDate(time); + return op; + } + + private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) { + String newArtifactName = operationName + "_" + artifactName; + log.trace("converting artifact name {} to {}", artifactName, newArtifactName); + return newArtifactName; + } + + public StorageOperationStatus deleteIfNotOnGraph(String artifactId, String artifactEsId, boolean deleteOnlyPayload) { + log.debug("deleteIfNotOnGraph: delete only payload = {}", deleteOnlyPayload); + Either<ArtifactData, TitanOperationStatus> checkArtifactNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class); + if ((artifactEsId != null && !artifactEsId.isEmpty())) { + boolean isNotExistOnGraph = checkArtifactNode.isRight() && checkArtifactNode.right().value().equals(TitanOperationStatus.NOT_FOUND); + + if ((isNotExistOnGraph) || (checkArtifactNode.left().value().getArtifactDataDefinition().getMandatory() && deleteOnlyPayload) + || (ArtifactGroupTypeEnum.SERVICE_API.equals(checkArtifactNode.left().value().getArtifactDataDefinition().getArtifactGroupType()) && deleteOnlyPayload)) { + // last one. need to delete in ES + log.debug("Entry on graph is deleted. Delete artifact in ES for id = {}", artifactEsId); + artifactCassandraDao.deleteArtifact(artifactEsId); + return StorageOperationStatus.OK; + // return + // componentsUtils.getResponseFormatByResourceId(ActionStatus.OK, + // resourceId); + + } else { + log.debug("Entry on graph is deleted. Exist more connections on this artifact. Don't delete artifact in ES for id = {}", artifactEsId); + return StorageOperationStatus.OK; + } + + } + return StorageOperationStatus.OK; + } + + // download by MSO + public Either<byte[], ResponseFormat> downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion, String artifactName) { + + // General validation + if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) { + log.debug("One of the function parameteres is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + // Normalizing artifact name + artifactName = ValidationUtils.normalizeFileName(artifactName); + + // Resource validation + Either<Resource, ResponseFormat> validateResourceNameAndVersion = validateResourceNameAndVersion(resourceName, resourceVersion); + if (validateResourceNameAndVersion.isRight()) { + return Either.right(validateResourceNameAndVersion.right().value()); + } + + Resource resource = validateResourceNameAndVersion.left().value(); + String resourceId = resource.getUniqueId(); + + // Service validation + Either<Service, ResponseFormat> validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion); + if (validateServiceNameAndVersion.isRight()) { + return Either.right(validateServiceNameAndVersion.right().value()); + } + + Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts(); + if (artifacts == null || artifacts.isEmpty()) { + log.debug("Deployment artifacts of resource {} are not found", resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + ArtifactDefinition deploymentArtifact = null; + + for (ArtifactDefinition artifactDefinition : artifacts.values()) { + if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName().equals(artifactName)) { + log.debug("Found deployment artifact {}", artifactName); + deploymentArtifact = artifactDefinition; + break; + } + } + + if (deploymentArtifact == null) { + log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + // Downloading the artifact + Either<ImmutablePair<String, byte[]>, ResponseFormat> downloadArtifactEither = downloadArtifact(deploymentArtifact); + if (downloadArtifactEither.isRight()) { + log.debug("Download artifact {} failed", artifactName); + return Either.right(downloadArtifactEither.right().value()); + } + log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId()); + return Either.left(downloadArtifactEither.left().value().getRight()); + } + + // download by MSO + public Either<byte[], ResponseFormat> downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) { + + // General validation + if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) { + log.debug("One of the function parameteres is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + // Normalizing artifact name + artifactName = ValidationUtils.normalizeFileName(artifactName); + + // Resource validation + /* + * Either<Resource, ResponseFormat> validateResourceNameAndVersion = validateResourceNameAndVersion(resourceName, resourceVersion); if (validateResourceNameAndVersion.isRight()) { return + * Either.right(validateResourceNameAndVersion.right().value()); } + * + * Resource resource = validateResourceNameAndVersion.left().value(); String resourceId = resource.getUniqueId(); + */ + + // Service validation + Either<Service, ResponseFormat> validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion); + if (validateServiceNameAndVersion.isRight()) { + return Either.right(validateServiceNameAndVersion.right().value()); + } + + Service service = validateServiceNameAndVersion.left().value(); + + // ResourceInstance validation + Either<ComponentInstance, ResponseFormat> validateResourceInstance = validateResourceInstance(service, resourceInstanceName); + if (validateResourceInstance.isRight()) { + return Either.right(validateResourceInstance.right().value()); + } + + ComponentInstance resourceInstance = validateResourceInstance.left().value(); + + Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts(); + + final String finalArtifactName = artifactName; + Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName); + + boolean hasDeploymentArtifacts = artifacts != null && artifacts.values().stream().anyMatch(filterArtifactByName); + ArtifactDefinition deployableArtifact; + + if (!hasDeploymentArtifacts) { + log.debug("Deployment artifact with name {} not found", artifactName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + log.debug("Found deployment artifact {}", artifactName); + deployableArtifact = artifacts.values().stream().filter(filterArtifactByName).findFirst().get(); + // Downloading the artifact + Either<ImmutablePair<String, byte[]>, ResponseFormat> downloadArtifactEither = downloadArtifact(deployableArtifact); + + if (downloadArtifactEither.isRight()) { + log.debug("Download artifact {} failed", artifactName); + return Either.right(downloadArtifactEither.right().value()); + } + log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId()); + return Either.left(downloadArtifactEither.left().value().getRight()); + } + + private Either<ComponentInstance, ResponseFormat> validateResourceInstance(Service service, String resourceInstanceName) { + + List<ComponentInstance> riList = service.getComponentInstances(); + for (ComponentInstance ri : riList) { + if (ri.getNormalizedName().equals(resourceInstanceName)) + return Either.left(ri); + } + + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName)); + } + + private Either<Service, ResponseFormat> validateServiceNameAndVersion(String serviceName, String serviceVersion) { + + Either<List<Service>, StorageOperationStatus> serviceListBySystemName = serviceOperation.getServiceListBySystemName(serviceName, false); + if (serviceListBySystemName.isRight()) { + log.debug("Couldn't fetch any service with name {}", serviceName); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceListBySystemName.right().value(), ComponentTypeEnum.SERVICE), serviceName)); + } + List<Service> serviceList = serviceListBySystemName.left().value(); + if (serviceList == null || serviceList.isEmpty()) { + log.debug("Couldn't fetch any service with name {}", serviceName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceName)); + } + + Service foundService = null; + for (Service service : serviceList) { + if (service.getVersion().equals(serviceVersion)) { + log.trace("Found service with version {}", serviceVersion); + foundService = service; + break; + } + } + + if (foundService == null) { + log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE.getValue(), serviceVersion)); + } + return Either.left(foundService); + } + + private Either<Resource, ResponseFormat> validateResourceNameAndVersion(String resourceName, String resourceVersion) { + Either<List<Resource>, StorageOperationStatus> resourceListBySystemName = resourceOperation.getResourceListBySystemName(resourceName, false); + if (resourceListBySystemName.isRight()) { + log.debug("Couldn't fetch any resource with name {}", resourceName); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()), resourceName)); + } + List<Resource> resourceList = resourceListBySystemName.left().value(); + if (resourceList == null || resourceList.isEmpty()) { + log.debug("Couldn't fetch any resource with name {}", resourceName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceName)); + } + + Resource foundResource = null; + for (Resource resource : resourceList) { + if (resource.getVersion().equals(resourceVersion)) { + log.trace("Found resource with version {}", resourceVersion); + foundResource = resource; + break; + } + } + + if (foundResource == null) { + log.debug("Couldn't find version {} for resource {}", resourceVersion, resourceName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.RESOURCE.getValue(), resourceVersion)); + } + return Either.left(foundResource); + } + + public Either<byte[], ResponseFormat> downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) { + // Validation + log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion, artifactName); + if (serviceName == null || serviceVersion == null || artifactName == null) { + log.debug("One of the function parameteres is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + // Normalizing artifact name + artifactName = ValidationUtils.normalizeFileName(artifactName); + + // Service validation + Either<Service, ResponseFormat> validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion); + if (validateServiceNameAndVersion.isRight()) { + return Either.right(validateServiceNameAndVersion.right().value()); + } + + String serviceId = validateServiceNameAndVersion.left().value().getUniqueId(); + + // Looking for deployment artifacts + Service service = validateServiceNameAndVersion.left().value(); + Map<String, ArtifactDefinition> artifacts = service.getDeploymentArtifacts(); + if (artifacts == null || artifacts.isEmpty()) { + log.debug("Deployment artifacts of service {} are not found", serviceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + ArtifactDefinition deploymentArtifact = null; + + for (ArtifactDefinition artifactDefinition : artifacts.values()) { + if (artifactDefinition.getArtifactName().equals(artifactName)) { + log.debug("Found deployment artifact {}", artifactName); + deploymentArtifact = artifactDefinition; + } + } + + if (deploymentArtifact == null) { + log.debug("No deployment artifact {} was found for service {}", artifactName, serviceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + // Downloading the artifact + Either<ImmutablePair<String, byte[]>, ResponseFormat> downloadArtifactEither = downloadArtifact(deploymentArtifact); + if (downloadArtifactEither.isRight()) { + log.debug("Download artifact {} failed", artifactName); + return Either.right(downloadArtifactEither.right().value()); + } + log.trace("Download of service artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId()); + return Either.left(downloadArtifactEither.left().value().getRight()); + } + + public Either<ImmutablePair<String, byte[]>, ResponseFormat> downloadArtifact(String artifactUniqueId) { + log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId); + Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactOperation.getArtifactById(artifactUniqueId, false); + if (artifactById.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value()); + log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus.name()); + return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, "")); + } + ArtifactDefinition artifactDefinition = artifactById.left().value(); + if (artifactDefinition == null) { + log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, "")); + } + + return downloadArtifact(artifactDefinition); + } + + private boolean checkArtifactInComponent(org.openecomp.sdc.be.model.Component component, String artifactId) { + boolean found = false; + Map<String, ArtifactDefinition> artifactsS = component.getArtifacts(); + if (artifactsS != null) { + for (Map.Entry<String, ArtifactDefinition> entry : artifactsS.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + Map<String, ArtifactDefinition> deploymentArtifactsS = component.getDeploymentArtifacts(); + if (!found && deploymentArtifactsS != null) { + for (Map.Entry<String, ArtifactDefinition> entry : deploymentArtifactsS.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + Map<String, ArtifactDefinition> toscaArtifactsS = component.getToscaArtifacts(); + if (!found && toscaArtifactsS != null) { + for (Map.Entry<String, ArtifactDefinition> entry : toscaArtifactsS.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + switch (component.getComponentType()) { + case RESOURCE: + Map<String, InterfaceDefinition> interfaces = ((Resource) component).getInterfaces(); + if (!found && interfaces != null) { + for (Map.Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) { + Map<String, Operation> operations = entry.getValue().getOperations(); + for (Map.Entry<String, Operation> entryOp : operations.entrySet()) { + if (entryOp.getValue().getImplementation() != null && entryOp.getValue().getImplementation().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + } + break; + case SERVICE: + Map<String, ArtifactDefinition> apiArtifacts = ((Service) component).getServiceApiArtifacts(); + if (!found && apiArtifacts != null) { + for (Map.Entry<String, ArtifactDefinition> entry : apiArtifacts.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + break; + default: + + } + + return found; + } + + private boolean checkArtifactInResourceInstance(Component component, String resourceInstanceId, String artifactId) { + + boolean found = false; + List<ComponentInstance> resourceInstances = component.getComponentInstances(); + ComponentInstance resourceInstance = null; + for (ComponentInstance ri : resourceInstances) { + if (ri.getUniqueId().equals(resourceInstanceId)) { + resourceInstance = ri; + break; + } + } + if (resourceInstance != null) { + Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts(); + if (artifacts != null) { + for (Map.Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + } + return found; + } + + private Either<? extends org.openecomp.sdc.be.model.Component, ResponseFormat> validateComponentExists(String componentId, String userId, AuditingActionEnum auditingAction, User user, String artifactId, ComponentTypeEnum componentType, + String containerComponentType, boolean inTransaction) { + + NodeTypeEnum nodeType = componentType.getNodeType(); + if (containerComponentType != null && NodeTypeEnum.ResourceInstance == nodeType) { + nodeType = (ComponentTypeEnum.findByParamName(containerComponentType)).getNodeType(); + } + ComponentOperation componentOperation = getComponentOperation(nodeType); + + if (componentOperation == null) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + log.debug("addArtifact - not supported component type {}", componentType); + handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + Either<? extends org.openecomp.sdc.be.model.Component, StorageOperationStatus> componentResult = componentOperation.getComponent(componentId, inTransaction); + + if (componentResult.isRight()) { + ActionStatus status = (componentType.equals(ComponentTypeEnum.RESOURCE)) ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND; + ComponentTypeEnum componentForAudit = (componentType.equals(ComponentTypeEnum.RESOURCE)) ? ComponentTypeEnum.RESOURCE : ComponentTypeEnum.SERVICE; + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId); + log.debug("Service not found, serviceId {}", componentId); + handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null); + return Either.right(responseFormat); + } + return Either.left(componentResult.left().value()); + } + + private Either<Boolean, ResponseFormat> validateWorkOnComponent(org.openecomp.sdc.be.model.Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId, ArtifactOperation operation, + ComponentTypeEnum componentType) { + if (operation != ArtifactOperation.Download) { + Either<Boolean, ResponseFormat> canWork = validateCanWorkOnComponent(component, userId); + if (canWork.isRight()) { + String uniqueId = component.getUniqueId(); + log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId); + handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, canWork.right().value(), component.getComponentType(), null); + return Either.right(canWork.right().value()); + } + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateWorkOnResource(Resource resource, String userId, AuditingActionEnum auditingAction, User user, String artifactId, ArtifactOperation operation) { + if (operation != ArtifactOperation.Download) { + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + String uniqueId = resource.getUniqueId(); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("Resource status isn't CHECKOUT or user isn't owner, resourceId {}", uniqueId); + handleAuditing(auditingAction, resource, uniqueId, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE, null); + return Either.right(responseFormat); + } + } + return Either.left(true); + } + + private Either<Boolean, ResponseFormat> validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType, ArtifactOperation operation) { + + if (operation != ArtifactOperation.Download) { + String role = user.getRole(); + if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role); + handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + } + return Either.left(true); + } + + private Either<User, ResponseFormat> validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType) { + + return validateUserExists(userId, auditingAction, componentId, artifactId, componentType, false); + + } + + private Either<User, ResponseFormat> validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType, boolean inTransaction) { + Either<User, ResponseFormat> validateUserExists = validateUserExists(userId, auditingAction.getName(), inTransaction); + + if (validateUserExists.isRight()) { + User user = new User(); + user.setUserId(userId); + handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, validateUserExists.right().value(), componentType, null); + return Either.right(validateUserExists.right().value()); + } + return Either.left(validateUserExists.left().value()); + } + + private AuditingActionEnum detectAuditingType(ArtifactOperation operation, String origMd5) { + AuditingActionEnum auditingAction = null; + switch (operation) { + case Create: + auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD; + break; + case Update: + auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE; + break; + case Delete: + auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE; + break; + case Download: + auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD; + break; + default: + break; + } + return auditingAction; + } + + private Either<ImmutablePair<String, byte[]>, ResponseFormat> downloadArtifact(ArtifactDefinition artifactDefinition) { + String esArtifactId = artifactDefinition.getEsId(); + Either<ESArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId); + if (artifactfromES.isRight()) { + CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value(); + StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse); + log.debug("Error when getting artifact from ES, error: {}", actionStatus.name()); + return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName())); + } + + ESArtifactData esArtifactData = artifactfromES.left().value(); + byte[] data = esArtifactData.getDataAsArray(); + if (data == null) { + log.debug("Artifact data from ES is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName())); + } + String artifactName = artifactDefinition.getArtifactName(); + log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName); + return Either.left(new ImmutablePair<String, byte[]>(artifactName, data)); + } + + public ESArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) { + ESArtifactData artifactData = new ESArtifactData(artifactInfo.getEsId(), artifactPayload); + return artifactData; + } + + private boolean saveArtifacts(ESArtifactData artifactData, String resourceId, boolean reload) { + + CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData); + + if (resourceUploadStatus.equals(CassandraOperationStatus.OK)) { + log.debug("Artifact {} was saved in component {}.", artifactData.getId(), resourceId); + } else { + log.info("Failed to save artifact {}.", artifactData.getId()); + return false; + } + return true; + } + + private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) { + return (auditingActionEnum.equals(AuditingActionEnum.ARTIFACT_METADATA_UPDATE)); + } + + private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) { + return (ArtifactGroupTypeEnum.DEPLOYMENT.equals(artifactInfo.getArtifactGroupType())); + } + + public IResourceOperation getResourceOperation() { + return this.resourceOperation; + } + + public Either<ArtifactDefinition, ResponseFormat> createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, String userId, ArtifactGroupTypeEnum groupType, boolean inTransaction) { + Either<User, ActionStatus> user = userAdminManager.getUser(userId, inTransaction); + if (user.isRight()) { + ResponseFormat responseFormat; + if (user.right().value().equals(ActionStatus.USER_NOT_FOUND)) { + log.debug("create artifact placeholder - not authorized user, userId {}", userId); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + } else { + log.debug("create artifact placeholder - failed to authorize user, userId {}", userId); + responseFormat = componentsUtils.getResponseFormat(user.right().value()); + } + return Either.right(responseFormat); + } + + ArtifactDefinition artifactDefinition = createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user.left().value(), groupType); + return Either.left(artifactDefinition); + } + + public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user, ArtifactGroupTypeEnum groupType) { + ArtifactDefinition artifactInfo = new ArtifactDefinition(); + + String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME); + String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE); + String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION); + + artifactInfo.setArtifactDisplayName(artifactName); + artifactInfo.setArtifactLabel(logicalName.toLowerCase()); + artifactInfo.setArtifactType(artifactType); + artifactInfo.setDescription(artifactDescription); + artifactInfo.setArtifactGroupType(groupType); + setDefaultArtifactTimeout(groupType, artifactInfo); + + setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo); + + return artifactInfo; + } + + private void setDefaultArtifactTimeout(ArtifactGroupTypeEnum groupType, ArtifactDefinition artifactInfo) { + if (groupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) { + artifactInfo.setTimeout(defaultHeatTimeout); + } else { + artifactInfo.setTimeout(NON_HEAT_TIMEOUT); + } + } + + private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) { + String uniqueId = null; + + if (resourceId != null) { + uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase()); + artifactInfo.setUniqueId(uniqueId); + } + artifactInfo.setUserIdCreator(user.getUserId()); + String fullName = user.getFullName(); + artifactInfo.setUpdaterFullName(fullName); + + long time = System.currentTimeMillis(); + + artifactInfo.setCreatorFullName(fullName); + artifactInfo.setCreationDate(time); + + artifactInfo.setLastUpdateDate(time); + artifactInfo.setUserIdLastUpdater(user.getUserId()); + + artifactInfo.setMandatory(true); + } + + public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction, ArtifactGroupTypeEnum groupType) { + return artifactOperation.getArtifacts(parentId, parentType, inTransaction, groupType.getType()); + } + + public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact, String parentId, NodeTypeEnum parentType, boolean inTransaction) { + return artifactOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, parentId, parentType, inTransaction); + + } + + private Either<ESArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String parameters) { + StringBuilder sb = new StringBuilder(); + + sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader()); + sb.append(parameters); + sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter()); + byte[] payload = sb.toString().getBytes(); + + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + + /* + * if (!yamlToObjectConverter.isValidYaml(payload)) { log.debug("Invalid YAML format"); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML, ArtifactTypeEnum.HEAT_ENV.getType()); return + * Either.right(responseFormat); } + */ + + ESArtifactData artifactData = createEsArtifactData(artifactDefinition, payload); + return Either.left(artifactData); + } + + /** + * + * @param artifactDefinition + * @return + */ + public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, String resourceInstanceName, User modifier, boolean shouldLock) { + List<HeatParameterDefinition> heatParameters = artifactDefinition.getHeatParameters(); + heatParameters.sort(Comparator.comparing(e -> e.getName())); + StringBuilder sb = new StringBuilder("parameters:\n"); + if (heatParameters != null) { + + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + if (heatParameterDefinition.getCurrentValue() != null) { + HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType()); + if (type != null) { + switch (type) { + case BOOLEAN: + sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatParameterDefinition.getCurrentValue())).append("\n"); + break; + case NUMBER: + // if + // (ValidationUtils.isFloatNumber(heatParameterDefinition.getCurrentValue())) + // { + // sb.append(" + // ").append(heatParameterDefinition.getName()).append(":").append(" + // ").append(Float.parseFloat(heatParameterDefinition.getCurrentValue())).append("\n"); + // } else { + // sb.append(" + // ").append(heatParameterDefinition.getName()).append(":").append(" + // ").append(Integer.parseInt(heatParameterDefinition.getCurrentValue())).append("\n"); + // } + sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(new BigDecimal(heatParameterDefinition.getCurrentValue()).toPlainString()).append("\n"); + break; + case COMMA_DELIMITED_LIST: + case JSON: + sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatParameterDefinition.getCurrentValue()).append("\n"); + break; + default: + String value = heatParameterDefinition.getCurrentValue(); + boolean starts = value.startsWith("\""); + boolean ends = value.endsWith("\""); + if (!(starts && ends)) { + starts = value.startsWith("'"); + ends = value.endsWith("'"); + if (!(starts && ends)) { + value = "\"" + value + "\""; + } + } + sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value); + sb.append("\n"); + break; + + } + } + } + } + } + return generateAndSaveHeatEnvArtifact(artifactDefinition, sb.toString(), component, resourceInstanceName, modifier, shouldLock); + + } + + /** + * + * @param artifactDefinition + * @param payload + * @return + */ + public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload, org.openecomp.sdc.be.model.Component component, String resourceInstanceName, User modifier, + boolean shouldLock) { + return generateArtifactPayload(artifactDefinition, component, resourceInstanceName, modifier, shouldLock, () -> artifactDefinition.getHeatParamsUpdateDate(), () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload)); + + } + + protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, String resourceInstanceName, User modifier, boolean shouldLock, + Supplier<Long> payloadUpdateDateGen, Supplier<Either<ESArtifactData, ResponseFormat>> esDataCreator) { + + if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0 || artifactDefinition.getPayloadUpdateDate() < payloadUpdateDateGen.get()) { + + log.trace("Generaing payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId()); + Either<ESArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get(); + ESArtifactData artifactData = null; + + if (artifactDataRes.isLeft()) { + artifactData = artifactDataRes.left().value(); + } else { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + return Either.right(artifactDataRes.right().value()); + } + String newCheckSum = GeneralUtility.calculateMD5ByByteArray(artifactData.getDataAsArray()); + String oldCheckSum; + String esArtifactId = artifactDefinition.getEsId(); + Either<ESArtifactData, CassandraOperationStatus> artifactfromES; + ESArtifactData esArtifactData; + if (esArtifactId != null && !esArtifactId.isEmpty()) { + artifactfromES = artifactCassandraDao.getArtifact(esArtifactId); + if (artifactfromES.isRight()) { + CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value(); + StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse); + log.debug("Error when getting artifact from ES, error: {}", actionStatus.name()); + return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName())); + } + esArtifactData = artifactfromES.left().value(); + oldCheckSum = GeneralUtility.calculateMD5ByByteArray(esArtifactData.getDataAsArray()); + } else { + oldCheckSum = artifactDefinition.getArtifactChecksum(); + } + Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus; + + if (shouldLock) { + Either<Boolean, ResponseFormat> lockComponent = lockComponent(component, "Update Artifact - lock resource: "); + if (lockComponent.isRight()) { + handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null, artifactDefinition.getUniqueId(), lockComponent.right().value(), component.getComponentType(), null); + return Either.right(lockComponent.right().value()); + } + } + try { + if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) { + + artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get()); + updateArifactDefinitionStatus = artifactOperation.updateArifactDefinition(artifactDefinition, false); + log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId()); + if (updateArifactDefinitionStatus.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()), artifactDefinition.getArtifactDisplayName()); + log.trace("Failed to update payloadUpdateDate ", artifactDefinition.getEsId()); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + return Either.right(responseFormat); + } + } else { + + oldCheckSum = artifactDefinition.getArtifactChecksum(); + artifactDefinition.setArtifactChecksum(newCheckSum); + artifactOperation.updateUUID(artifactDefinition, oldCheckSum, artifactDefinition.getArtifactVersion()); + artifactDefinition.setEsId(artifactDefinition.getUniqueId()); + updateArifactDefinitionStatus = artifactOperation.updateArifactDefinition(artifactDefinition, true); + + log.trace("Update Payload ", artifactDefinition.getEsId()); + + if (updateArifactDefinitionStatus.isLeft()) { + + artifactData.setId(artifactDefinition.getUniqueId()); + CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData); + + if (saveArtifactStatus.equals(CassandraOperationStatus.OK)) { + titanGenericDao.commit(); + log.debug("Artifact Saved In ES {}", artifactData.getId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + } else { + titanGenericDao.rollback(); + log.info("Failed to save artifact {}.", artifactData.getId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + return Either.right(responseFormat); + } + } else { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()), artifactDefinition.getArtifactDisplayName()); + log.debug("Failed To update artifact {}", artifactData.getId()); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + return Either.right(responseFormat); + + } + } + } finally { + if (shouldLock) { + graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType()); + } + } + } + + return Either.left(artifactDefinition); + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleUpdateHeatEnv(String componentId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, + org.openecomp.sdc.be.model.Component parent, String originData, String origMd5, ArtifactOperation operation, boolean shouldLock, boolean inTransaction) { + NodeTypeEnum parentType = convertParentType(componentType); + String parentId = parent.getUniqueId(); + Either<ArtifactDefinition, StorageOperationStatus> artifactRes = artifactOperation.getArtifactById(artifactId, false); + ArtifactDefinition currArtifact = artifactRes.left().value(); + + if (origMd5 != null) { + Either<Boolean, ResponseFormat> validateMd5 = validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation); + if (validateMd5.isRight()) { + ResponseFormat responseFormat = validateMd5.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + + if (artifactInfo.getPayloadData() != null && artifactInfo.getPayloadData().length != 0) { + Either<Boolean, ResponseFormat> deploymentValidationResult = validateDeploymentArtifact(parent, componentId, user.getUserId(), false, artifactInfo, currArtifact, NodeTypeEnum.ResourceInstance); + if (deploymentValidationResult.isRight()) { + ResponseFormat responseFormat = deploymentValidationResult.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + + Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction)); + if (payloadEither.isRight()) { + ResponseFormat responseFormat = payloadEither.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + } else { // duplicate + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + } + + // lock resource + if (shouldLock) { + Either<Boolean, ResponseFormat> lockComponent = lockComponent(parent, "Update Artifact - lock "); + if (lockComponent.isRight()) { + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, lockComponent.right().value(), componentType, null); + return Either.right(lockComponent.right().value()); + } + } + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp = null; + try { + resultOp = updateHeatEnvParams(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, currArtifact, origMd5, inTransaction); + return resultOp; + + } finally { + // unlock resource + if (resultOp == null || resultOp.isRight()) { + log.debug("all changes rollback"); + if (false == inTransaction) + titanGenericDao.rollback(); + } else { + log.debug("all changes committed"); + if (false == inTransaction) + titanGenericDao.commit(); + } + if (shouldLock) + componentType = parent.getComponentType(); + NodeTypeEnum nodeType = componentType.getNodeType(); + graphLockOperation.unlockComponent(parent.getUniqueId(), nodeType); + // graphLockOperation.unlockComponent(parentId, parentType); + } + } + + private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> updateHeatEnvParams(String componentId, String artifactId, ArtifactDefinition artifactInfo, User user, AuditingActionEnum auditingAction, Component parent, + ComponentTypeEnum componentType, ArtifactDefinition currArtifact1, String origMd5, boolean inTransaction) { + + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp = null; + Either<ArtifactDefinition, Operation> insideEither = null; + /* + * currently getArtifactById does not retrieve heatParameters Either<ArtifactDefinition, StorageOperationStatus> artifactRes = artifactOperation.getArtifactById(artifactId, false); ArtifactDefinition currArtifact = artifactRes.left().value(); + */ + Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user); + if (getRI.isRight()) { + return Either.right(getRI.right().value()); + } + ComponentInstance ri = getRI.left().value(); + Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user); + if (getArtifactRes.isRight()) { + return Either.right(getArtifactRes.right().value()); + } + ArtifactDefinition currArtifact = getArtifactRes.left().value(); + + if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getHeatParameters(); + List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getHeatParameters(); + List<HeatParameterDefinition> reducedHeatEnvParams = new ArrayList<HeatParameterDefinition>(); + + // upload + if (origMd5 != null) { + Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction, parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, + updatedHeatEnvParams, currArtifact.getArtifactName()); + if (uploadParamsValidationResult.isRight()) { + ResponseFormat responseFormat = uploadParamsValidationResult.right().value(); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + artifactInfo.setHeatParameters(updatedHeatEnvParams); + } + + Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParamers(artifactInfo, ArtifactTypeEnum.HEAT_ENV.getType()); + if (validateAndConvertHeatParamers.isRight()) { + ResponseFormat responseFormat = validateAndConvertHeatParamers.right().value(); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + + if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) { + String paramName; + // fill reduced heat env parameters List for updating + for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) { + paramName = heatEnvParam.getName(); + for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) { + if (paramName.equalsIgnoreCase(currHeatParam.getName())) { + String updatedParamValue = heatEnvParam.getCurrentValue(); + if (updatedParamValue != null && updatedParamValue.equals("")) { // reset + heatEnvParam.setCurrentValue(heatEnvParam.getDefaultValue()); + reducedHeatEnvParams.add(heatEnvParam); + } else if (updatedParamValue != null) { + reducedHeatEnvParams.add(heatEnvParam); + } + } + } + } + if (reducedHeatEnvParams.size() > 0) { + ArtifactDefinition reducedArtifactInfo = new ArtifactDefinition(artifactInfo); + reducedArtifactInfo.setHeatParameters(reducedHeatEnvParams); + Either<ArtifactDefinition, StorageOperationStatus> updateArtifactResult = artifactOperation.updateArifactOnResource(reducedArtifactInfo, componentId, artifactInfo.getUniqueId(), componentType.getNodeType(), inTransaction); + + if (updateArtifactResult.isRight()) { + log.debug("Failed to update artifact on graph - {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateArtifactResult.right().value())); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + ArtifactDefinition updatedArtifact = updateArtifactResult.left().value(); + String updatedArtifactId = updatedArtifact.getUniqueId(); + if (!currArtifact.getUniqueId().equals(updatedArtifactId)) { + currArtifact.setUniqueId(updatedArtifactId); + currArtifact.setPayloadUpdateDate(updatedArtifact.getPayloadUpdateDate()); + currArtifact.setCreationDate(updatedArtifact.getCreationDate()); + currArtifact.setLastUpdateDate(updatedArtifact.getLastUpdateDate()); + currArtifact.setEsId(updatedArtifact.getEsId()); + } + currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis()); + + Either<List<HeatParameterDefinition>, StorageOperationStatus> heatParamsForEnv = ((org.openecomp.sdc.be.model.operations.impl.ArtifactOperation) artifactOperation).getHeatParamsForEnv(currArtifact); + if (heatParamsForEnv.isRight()) { + log.debug("failed to get heat parameters values for heat artifact {}", updatedArtifact.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(heatParamsForEnv.right().value())); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + List<HeatParameterDefinition> updatedHeatParaetersList = heatParamsForEnv.left().value(); + currArtifact.setHeatParameters(updatedHeatParaetersList); + + Either<ArtifactDefinition, StorageOperationStatus> updateArifactRes = artifactOperation.updateArifactDefinition(currArtifact, true); + if (updateArifactRes.isRight()) { + log.debug("Failed to update artifact on graph - {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateArifactRes.right().value())); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + } + } + + insideEither = Either.left(currArtifact); + resultOp = Either.left(insideEither); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, currArtifact, null, artifactId, responseFormat, componentType, ri.getName()); + return resultOp; + } + + public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent, User user, ArtifactDefinition artifactInfo, String artifactId, ComponentTypeEnum componentType, + String riName, List<HeatParameterDefinition> currentHeatEnvParams, List<HeatParameterDefinition> updatedHeatEnvParams, String currArtifactName) { + + if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName); + return Either.right(responseFormat); + } + + for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) { + String paramName = uploadedHeatParam.getName(); + boolean isExistsInHeat = false; + for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) { + if (paramName.equalsIgnoreCase(currHeatParam.getName())) { + + isExistsInHeat = true; + uploadedHeatParam.setType(currHeatParam.getType()); + uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue()); + uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue()); + uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId()); + break; + } + } + if (!isExistsInHeat) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName); + return Either.right(responseFormat); + } + } + return Either.left(updatedHeatEnvParams); + } + + private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId, AuditingActionEnum auditingAction, User user) { + ResponseFormat responseFormat = null; + List<ComponentInstance> ris = component.getComponentInstances(); + for (ComponentInstance ri : ris) { + if (riID.equals(ri.getUniqueId())) { + return Either.left(ri); + } + } + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID); + log.debug("Resource Instance not found, resourceInstanceId {}", riID); + handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null); + return Either.right(responseFormat); + } + + private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId, AuditingActionEnum auditingAction, User user) { + ResponseFormat responseFormat = null; + Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts(); + for (ArtifactDefinition artifact : rtifactsMap.values()) { + if (artifactId.equals(artifact.getUniqueId())) { + return Either.left(artifact); + } + } + responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId()); + handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, ri.getName()); + return Either.right(responseFormat); + } + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType) { + + switch (componentType) { + case Service: + case ResourceInstance: + return serviceOperation; + case Resource: + return resourceOperation; + default: + return null; + } + } + + public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) { + ArtifactDefinition ret; + if (eitherArtifact.isLeft()) { + ret = eitherArtifact.left().value(); + } else { + ret = eitherArtifact.right().value().getImplementation(); + } + return ret; + } + + /** + * downloads artifact of component by UUIDs + * + * @param componentType + * @param componentUuid + * @param artifactUUID + * @param auditAdditionalParam + * @return + */ + public Either<byte[], ResponseFormat> downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID, Map<AuditingFieldsKeysEnum, Object> auditAdditionalParam) { + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + Either<byte[], ResponseFormat> result; + byte[] downloadedArtifact = null; + Component component = getLatestComponentByUuid(componentType, componentUuid, errorWrapper); + if (errorWrapper.isEmpty()) { + auditAdditionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getName()); + downloadedArtifact = downloadArtifact(component.getDeploymentArtifacts(), artifactUUID, errorWrapper, component.getName()); + } + if (errorWrapper.isEmpty()) { + result = Either.left(downloadedArtifact); + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + /** + * downloads an artifact of resource instance of component by UUIDs + * + * @param componentType + * @param componentUuid + * @param resourceName + * @param artifactUUID + * @param auditAdditionalParam + * @return + */ + public Either<byte[], ResponseFormat> downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, String artifactUUID, Map<AuditingFieldsKeysEnum, Object> auditAdditionalParam) { + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + Either<byte[], ResponseFormat> result; + byte[] downloadedArtifact = null; + ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName, errorWrapper); + if (errorWrapper.isEmpty()) { + auditAdditionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstance.getName()); + downloadedArtifact = downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, errorWrapper, resourceInstance.getName()); + } + if (errorWrapper.isEmpty()) { + result = Either.left(downloadedArtifact); + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + /** + * uploads an artifact to a component by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param additionalParams + * @return + */ + public Either<ArtifactDefinition, ResponseFormat> uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, Map<AuditingFieldsKeysEnum, Object> additionalParams) { + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> actionResult = null; + Either<ArtifactDefinition, ResponseFormat> uploadArtifactResult; + ArtifactDefinition uploadArtifact; + Component component = null; + String componentId = null; + ArtifactOperation operation = ArtifactOperation.Create; + operation.setExternalApi(true); + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component != null) { + componentId = component.getUniqueId(); + } else { + componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(); + } + } + if (errorWrapper.isEmpty()) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, getComponentRes.left().value().getMetadataDataDefinition().getName()); + actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null, null); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + uploadArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, uploadArtifact); + uploadArtifactResult = Either.left(uploadArtifact); + } else { + uploadArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return uploadArtifactResult; + } + + /** + * upload an artifact to a resource instance by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param resourceInstanceName + * @param additionalParams + * @return + */ + public Either<ArtifactDefinition, ResponseFormat> uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, + Map<AuditingFieldsKeysEnum, Object> additionalParams) { + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + Either<ArtifactDefinition, ResponseFormat> uploadArtifactResult; + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> actionResult = null; + ArtifactDefinition uploadArtifact; + Component component = null; + String componentInstanceId; + String componentId; + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + ImmutablePair<Component, ComponentInstance> componentRiPair = null; + Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component == null) { + componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName, errorWrapper); + } else { + componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName, errorWrapper); + } + } + if (errorWrapper.isEmpty()) { + componentInstanceId = componentRiPair.getRight().getUniqueId(); + componentId = componentRiPair.getLeft().getUniqueId(); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName); + ArtifactOperation operation = ArtifactOperation.Create; + operation.setExternalApi(true); + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + + actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType)); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component instance {} of component with type {} and uuid {}. Status is {}. ", resourceInstanceName, componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + uploadArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, uploadArtifact); + uploadArtifactResult = Either.left(uploadArtifact); + } else { + uploadArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return uploadArtifactResult; + } + + /** + * updates an artifact on a component by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param artifactUUID + * @param additionalParams + * @return + */ + public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String artifactUUID, + Map<AuditingFieldsKeysEnum, Object> additionalParams) { + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + Either<ArtifactDefinition, ResponseFormat> updateArtifactResult; + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> actionResult = null; + ArtifactDefinition updateArtifact; + Component component = null; + String componentId = null; + String artifactId = null; + ArtifactOperation operation = ArtifactOperation.Update; + operation.setExternalApi(true); + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component != null) { + componentId = component.getUniqueId(); + } else { + componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(); + } + } + if (errorWrapper.isEmpty()) { + artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, errorWrapper, componentId, componentType); + } + if (errorWrapper.isEmpty()) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, getComponentRes.left().value().getMetadataDataDefinition().getName()); + + actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null, null); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + updateArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, updateArtifact); + updateArtifactResult = Either.left(updateArtifact); + + } else { + updateArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return updateArtifactResult; + } + + /** + * updates an artifact on a resource instance by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param resourceInstanceName + * @param artifactUUID + * @param additionalParams + * @return + */ + public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, String artifactUUID, + Map<AuditingFieldsKeysEnum, Object> additionalParams) { + + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + Either<ArtifactDefinition, ResponseFormat> updateArtifactResult; + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> actionResult = null; + ArtifactDefinition updateArtifact; + Component component = null; + String componentInstanceId = null; + String componentId = null; + String artifactId = null; + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + ImmutablePair<Component, ComponentInstance> componentRiPair = null; + Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component == null) { + componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName, errorWrapper); + } else { + componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName, errorWrapper); + } + } + if (errorWrapper.isEmpty()) { + componentInstanceId = componentRiPair.getRight().getUniqueId(); + componentId = componentRiPair.getLeft().getUniqueId(); + artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, errorWrapper, componentInstanceId, ComponentTypeEnum.RESOURCE_INSTANCE); + } + if (errorWrapper.isEmpty()) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName); + ArtifactOperation operation = ArtifactOperation.Update; + operation.setExternalApi(true); + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + + actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo, origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType)); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component instance {} of component with type {} and uuid {}. Status is {}. ", resourceInstanceName, componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + updateArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, updateArtifact); + updateArtifactResult = Either.left(updateArtifact); + } else { + updateArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return updateArtifactResult; + + } + + /** + * deletes an artifact on a component by UUID + * + * @param request + * @param componentType + * @param componentUuid + * @param artifactUUID + * @param additionalParams + * @return + */ + public Either<ArtifactDefinition, ResponseFormat> deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String artifactUUID, Map<AuditingFieldsKeysEnum, Object> additionalParams) { + + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + Either<ArtifactDefinition, ResponseFormat> deleteArtifactResult; + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> actionResult = null; + ArtifactDefinition deleteArtifact; + Component component = null; + String componentId = null; + String artifactId = null; + ArtifactOperation operation = ArtifactOperation.Delete; + operation.setExternalApi(true); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component != null) { + componentId = component.getUniqueId(); + } else { + componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(); + } + } + if (errorWrapper.isEmpty()) { + artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, errorWrapper, componentId, componentType); + } + if (errorWrapper.isEmpty()) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, getComponentRes.left().value().getMetadataDataDefinition().getName()); + + actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + deleteArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, deleteArtifact); + deleteArtifactResult = Either.left(deleteArtifact); + } else { + deleteArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return deleteArtifactResult; + } + + /** + * deletes an artifact an a resource instance by UUID + * + * @param request + * @param componentType + * @param componentUuid + * @param resourceInstanceName + * @param artifactUUID + * @param additionalParams + * @return + */ + public Either<ArtifactDefinition, ResponseFormat> deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, String artifactUUID, + Map<AuditingFieldsKeysEnum, Object> additionalParams) { + + Wrapper<ResponseFormat> errorWrapper = new Wrapper<>(); + Either<ArtifactDefinition, ResponseFormat> deleteArtifactResult; + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> actionResult = null; + ArtifactDefinition deleteArtifact; + Component component = null; + String componentInstanceId = null; + String componentId = null; + String artifactId = null; + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + ImmutablePair<Component, ComponentInstance> componentRiPair = null; + Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component == null) { + componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName, errorWrapper); + } else { + componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName, errorWrapper); + } + } + if (errorWrapper.isEmpty()) { + componentInstanceId = componentRiPair.getRight().getUniqueId(); + componentId = componentRiPair.getLeft().getUniqueId(); + artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, errorWrapper, componentInstanceId, ComponentTypeEnum.RESOURCE_INSTANCE); + } + if (errorWrapper.isEmpty()) { + + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName); + ArtifactOperation operation = ArtifactOperation.Delete; + operation.setExternalApi(true); + + actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5, null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType)); + + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component instance {} of component with type {} and uuid {}. Status is {}. ", resourceInstanceName, componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + deleteArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, deleteArtifact); + deleteArtifactResult = Either.left(deleteArtifact); + } else { + deleteArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return deleteArtifactResult; + } + + private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, Wrapper<ResponseFormat> errorWrapper) { + ComponentInstance componentInstance = null; + StorageOperationStatus status; + Either<ComponentInstance, StorageOperationStatus> getResourceInstanceRes = null; + Component component = getLatestComponentByUuid(componentType, componentUuid, errorWrapper); + if (errorWrapper.isEmpty()) { + componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getNormalizedName().equals(resourceInstanceName)).findAny().get(); + if (componentInstance == null) { + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName, "resource instance", component.getComponentType().getValue(), component.getName())); + log.debug("Component instance {} was not found for component {}", resourceInstanceName, component.getName()); + } + } + if (errorWrapper.isEmpty()) { + getResourceInstanceRes = resourceInstanceOperation.getResourceInstanceById(componentInstance.getUniqueId()); + if (getResourceInstanceRes.isRight()) { + status = getResourceInstanceRes.right().value(); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + } + if (errorWrapper.isEmpty()) { + componentInstance = getResourceInstanceRes.left().value(); + getResourceInstanceRes = resourceInstanceOperation.getFullComponentInstance(componentInstance, componentType.getNodeType()); + if (getResourceInstanceRes.isRight()) { + status = getResourceInstanceRes.right().value(); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } else { + componentInstance = getResourceInstanceRes.left().value(); + } + } + return componentInstance; + } + + private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName, Wrapper<ResponseFormat> errorWrapper) { + + ImmutablePair<Component, ComponentInstance> relatedComponentComponentInstancePair = null; + ComponentInstance componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getNormalizedName().equals(resourceInstanceName)).findAny().get(); + if (componentInstance == null) { + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName, "resource instance", component.getComponentType().getValue(), component.getName())); + log.debug("Component instance {} was not found for component {}", resourceInstanceName, component.getName()); + } else { + relatedComponentComponentInstancePair = new ImmutablePair<>(component, componentInstance); + } + return relatedComponentComponentInstancePair; + } + + private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, Wrapper<ResponseFormat> errorWrapper) { + ComponentInstance componentInstance; + ImmutablePair<Component, ComponentInstance> relatedComponentComponentInstancePair = null; + Component component = getLatestComponentByUuid(componentType, componentUuid, errorWrapper); + if (errorWrapper.isEmpty()) { + componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getNormalizedName().equals(resourceInstanceName)).findAny().get(); + if (componentInstance == null) { + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName, "resource instance", component.getComponentType().getValue(), component.getName())); + log.debug("Component instance {} was not found for component {}", resourceInstanceName, component.getName()); + } else { + relatedComponentComponentInstancePair = new ImmutablePair<>(component, componentInstance); + } + } + return relatedComponentComponentInstancePair; + } + + private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, Wrapper<ResponseFormat> errorWrapper, String componentName) { + + byte[] downloadedArtifact = null; + Either<ImmutablePair<String, byte[]>, ResponseFormat> downloadArtifactEither = null; + List<ArtifactDefinition> deploymentArtifacts = null; + ArtifactDefinition deploymentArtifact = null; + if (artifacts != null && !artifacts.isEmpty()) { + deploymentArtifacts = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList()); + } + if (deploymentArtifacts == null || deploymentArtifacts.isEmpty()) { + log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID)); + } + if (errorWrapper.isEmpty()) { + deploymentArtifact = deploymentArtifacts.get(0); + downloadArtifactEither = downloadArtifact(deploymentArtifact); + if (downloadArtifactEither.isRight()) { + log.debug("Failed to download artifact {}. ", deploymentArtifact.getArtifactName()); + errorWrapper.setInnerElement(downloadArtifactEither.right().value()); + } + } + if (errorWrapper.isEmpty()) { + log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId()); + downloadedArtifact = downloadArtifactEither.left().value().getRight(); + } + return downloadedArtifact; + } + + private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid, Wrapper<ResponseFormat> errorWrapper) { + Component component = null; + Either<Component, StorageOperationStatus> getComponentRes = getComponentOperation(componentType).getLatestComponentByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } else { + component = getComponentRes.left().value(); + } + return component; + } + + private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, Wrapper<ResponseFormat> errorWrapper, String parentId, ComponentTypeEnum componentType) { + String artifactId = null; + ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND; + StorageOperationStatus storageStatus; + ArtifactDefinition latestArtifact = null; + List<ArtifactDefinition> artifacts = null; + NodeTypeEnum parentType; + if (componentType.equals(ComponentTypeEnum.RESOURCE)) { + parentType = NodeTypeEnum.Resource; + } else { + parentType = NodeTypeEnum.Service; + } + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactOperation.getArtifacts(parentId, parentType, false); + if (getArtifactsRes.isRight()) { + storageStatus = getArtifactsRes.right().value(); + log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType.name(), parentId, storageStatus); + if (!storageStatus.equals(StorageOperationStatus.NOT_FOUND)) { + actionStatus = componentsUtils.convertFromStorageResponse(storageStatus); + } + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus, artifactUUID)); + } + if (errorWrapper.isEmpty()) { + artifacts = getArtifactsRes.left().value().values().stream().filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList()); + if (artifacts == null || artifacts.isEmpty()) { + log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType.name(), parentId, actionStatus); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus, artifactUUID)); + } + } + if (errorWrapper.isEmpty()) { + latestArtifact = artifacts.stream().max((a1, a2) -> { + int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion())); + if (compareRes == 0) { + compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(), a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate()); + } + return compareRes; + }).get(); + if (latestArtifact == null) { + log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType.name(), parentId, actionStatus); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus, artifactUUID)); + } + } + if (errorWrapper.isEmpty()) { + artifactId = latestArtifact.getUniqueId(); + } + return artifactId; + } + + private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId, Wrapper<ResponseFormat> errorWrapper) { + + Component component = null; + Either<User, ActionStatus> getUserRes = userBusinessLogic.getUser(userId, false); + if (getUserRes.isRight()) { + log.debug("Could not fetch User of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId, getUserRes.right().value()); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(getUserRes.right().value())); + } + if (errorWrapper.isEmpty()) { + User modifier = getUserRes.left().value(); + LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout", LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API); + Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic.changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true); + if (checkoutRes.isRight()) { + log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId, checkoutRes.right().value().getStatus()); + errorWrapper.setInnerElement(checkoutRes.right().value()); + } else { + component = checkoutRes.left().value(); + } + } + return component; + } + + private void updateAuditParametersWithArtifactDefinition(Map<AuditingFieldsKeysEnum, Object> additionalParams, ArtifactDefinition artifact) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifact.getArtifactUUID()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_ARTIFACT_DATA, buildAuditingArtifactData(artifact)); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, artifact.getUpdaterFullName()); + } +} |