diff options
Diffstat (limited to 'catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java')
-rw-r--r-- | catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java | 649 |
1 files changed, 649 insertions, 0 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java new file mode 100644 index 0000000000..c8aa188e30 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java @@ -0,0 +1,649 @@ +/*- + * ============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.tosca; + +import java.io.IOException; +import org.apache.commons.codec.binary.Base64; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Triple; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperation; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +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.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.be.tosca.model.ToscaTemplate; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import org.openecomp.sdc.generator.data.Artifact; +import org.openecomp.sdc.generator.data.ArtifactType; +import org.openecomp.sdc.generator.data.GenerationData; +import org.openecomp.sdc.generator.impl.ArtifactGenerationServiceImpl; +import com.google.gson.Gson; + +import fj.data.Either; + +/** + * @author tg851x + * + */ +@org.springframework.stereotype.Component("csar-utils") +public class CsarUtils { + private static Logger log = LoggerFactory.getLogger(ToscaExportHandler.class.getName()); + + @Autowired + private ArtifactCassandraDao artifactCassandraDao; + @Autowired + private ComponentsUtils componentsUtils; + @Autowired + private ToscaExportHandler toscaExportUtils; + @Autowired + private ArtifactsBusinessLogic artifactsBusinessLogic; + @Autowired + protected ServiceOperation serviceOperation; + + @javax.annotation.Resource + private ServiceBusinessLogic serviceBusinessLogic; + + private Gson gson = new Gson(); + + private static final String DEFINITIONS_PATH = "Definitions/"; + private static final String ARTIFACTS_PATH = "Artifacts/"; + private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta"; + private static final String TOSCA_META_VERSION = "1.0"; + private static final String CSAR_VERSION = "1.1"; + + /** + * + * @param component + * @param getFromCS + * @param isInCertificationRequest + * @param shouldLock + * @param inTransaction + * @return + */ + public Either<byte[], ResponseFormat> createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest, boolean shouldLock, boolean inTransaction) { + return createCsar(component, getFromCS, isInCertificationRequest, false, shouldLock, inTransaction); + } + + private Either<byte[], ResponseFormat> createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) { + final String CREATED_BY = component.getCreatorFullName(); + + String fileName; + Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts(); + ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE); + fileName = artifactDefinition.getArtifactName(); + + String toscaBlock0 = createToscaBlock0(TOSCA_META_VERSION, CSAR_VERSION, CREATED_BY, fileName); + + byte[] toscaBlock0Byte = toscaBlock0.getBytes(); + + Either<byte[], ResponseFormat> generateCsarZipResponse = generateCsarZip(toscaBlock0Byte, component, getFromCS, isInCertificationRequest, mockGenerator, shouldLock, inTransaction); + + if (generateCsarZipResponse.isRight()) { + return Either.right(generateCsarZipResponse.right().value()); + } + + return Either.left(generateCsarZipResponse.left().value()); + } + + private Either<byte[], ResponseFormat> generateCsarZip(byte[] toscaBlock0Byte, Component component, boolean getFromCS, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) { + + ZipOutputStream zip = null; + ByteArrayOutputStream out = null; + try { + out = new ByteArrayOutputStream(); + zip = new ZipOutputStream(out); + + zip.putNextEntry(new ZipEntry(TOSCA_META_PATH_FILE_NAME)); + zip.write(toscaBlock0Byte); + Either<ZipOutputStream, ResponseFormat> populateZip = populateZip(component, getFromCS, zip, isInCertificationRequest, mockGenerator, shouldLock, inTransaction); + if (populateZip.isRight()) { + log.debug("Failed to populate CSAR zip file {}", populateZip.right().value()); + return Either.right(populateZip.right().value()); + } + zip = populateZip.left().value(); + + zip.finish(); + byte[] byteArray = out.toByteArray(); + + return Either.left(byteArray); + } catch (IOException e) { + log.debug("createCsar failed IOexception", e); + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(responseFormat); + } finally { + try { + if (zip != null) { + zip.close(); + } + if (out != null) { + out.close(); + } + } catch (Exception e) { + log.error("Failed to close resources ", e); + } + } + } + + private Either<ZipOutputStream, ResponseFormat> populateZip(Component component, boolean getFromCS, ZipOutputStream zip, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) { + + LifecycleStateEnum lifecycleState = component.getLifecycleState(); + String componentYaml = null; + Either<ToscaRepresentation, ToscaError> exportComponent = null; + byte[] mainYaml = null; + // <file name, esid, component> + List<Triple<String, String, Component>> dependencies = null; + List<ImmutablePair<Component, byte[]>> generatorInputs = new LinkedList<>(); + + String fileName; + Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts(); + ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE); + fileName = artifactDefinition.getArtifactName(); + + if (getFromCS || !(lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + String esId = artifactDefinition.getEsId(); + Either<byte[], ActionStatus> fromCassandra = getFromCassandra(esId); + if (fromCassandra.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(fromCassandra.right().value()); + return Either.right(responseFormat); + } + mainYaml = fromCassandra.left().value(); + + } else { + exportComponent = toscaExportUtils.exportComponent(component); + if (exportComponent.isRight()) { + log.debug("exportComponent failed", exportComponent.right().value()); + ActionStatus convertedFromToscaError = componentsUtils.convertFromToscaError(exportComponent.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertedFromToscaError); + return Either.right(responseFormat); + } + ToscaRepresentation exportResult = exportComponent.left().value(); + componentYaml = exportResult.getMainYaml(); + mainYaml = componentYaml.getBytes(); + dependencies = exportResult.getDependencies(); + } + + try { + zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName)); + zip.write(mainYaml); + + generatorInputs.add(new ImmutablePair<Component, byte[]>(component, mainYaml)); + + if (dependencies == null) { + Either<ToscaTemplate, ToscaError> dependenciesRes = toscaExportUtils.getDependencies(component); + if (dependenciesRes.isRight()) { + log.debug("Failed to retrieve dependencies for component {}, error {}", component.getUniqueId(), dependenciesRes.right().value()); + ActionStatus convertFromToscaError = componentsUtils.convertFromToscaError(dependenciesRes.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertFromToscaError); + return Either.right(responseFormat); + } + dependencies = dependenciesRes.left().value().getDependencies(); + } + if (dependencies != null && !dependencies.isEmpty()) { + for (Triple<String, String, Component> d : dependencies) { + String esId = d.getMiddle(); + Component childComponent = d.getRight(); + fileName = d.getLeft(); + Either<byte[], ActionStatus> entryData = getEntryData(esId, childComponent); + + if (entryData.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(entryData.right().value()); + return Either.right(responseFormat); + } + + byte[] content = entryData.left().value(); + zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName)); + zip.write(content); + + generatorInputs.add(new ImmutablePair<Component, byte[]>(childComponent, content)); + } + } + + List<ArtifactDefinition> aiiArtifactList = new LinkedList<>(); + // Artifact Generation + if (component.getComponentType() == ComponentTypeEnum.SERVICE && (lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + Either<List<ArtifactDefinition>, ResponseFormat> handleAAIArtifacts = handleAAIArtifacts(component, zip, mockGenerator, shouldLock, inTransaction, generatorInputs); + + if (handleAAIArtifacts.isLeft()) { + aiiArtifactList = handleAAIArtifacts.left().value(); + } else { + log.debug("AAI Artifacts handling failed"); + return Either.right(handleAAIArtifacts.right().value()); + } + + if (isInCertificationRequest) { + Either<ActionStatus, ResponseFormat> handleAllAAIArtifactsInDataModel = handleAllAAIArtifactsInDataModel(component, aiiArtifactList, shouldLock, inTransaction); + + if (handleAllAAIArtifactsInDataModel.isRight()) { + log.debug("AAI Artifacts handling (create, update, delete) failed"); + return Either.right(handleAllAAIArtifactsInDataModel.right().value()); + } + } + + } + + // Collecting All Deployment Artifacts + Either<ZipOutputStream, ActionStatus> collectAndWriteToScarDeploymentArtifacts = collectAndWriteToScarDeploymentArtifacts(zip, component, aiiArtifactList); + + if (collectAndWriteToScarDeploymentArtifacts.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } catch (IOException e) { + log.debug("Failed to create CSAR zip for component {}", component.getUniqueId(), e); + } + + return Either.left(zip); + } + + private Either<ZipOutputStream, ActionStatus> collectAndWriteToScarDeploymentArtifacts(ZipOutputStream zip, Component component, List<ArtifactDefinition> aiiArtifactList) throws IOException { + + Collection<ArtifactDefinition> deploymentArtifactsToAdd = null; + Collection<ArtifactDefinition> allArtifactsToAdd = new LinkedList<>(); + + if (component.getComponentType() == ComponentTypeEnum.SERVICE) { + Either<Service, StorageOperationStatus> getServiceResponse = serviceOperation.getService(component.getUniqueId()); + + if (getServiceResponse.isLeft()) { + Service service = getServiceResponse.left().value(); + + if (!aiiArtifactList.isEmpty()) { + deploymentArtifactsToAdd = service.getDeploymentArtifacts().values().stream().filter(e -> e.getGenerated() == null || !e.getGenerated()).collect(Collectors.toList()); + allArtifactsToAdd.addAll(aiiArtifactList); + allArtifactsToAdd.addAll(deploymentArtifactsToAdd); + } else { + allArtifactsToAdd.addAll(service.getDeploymentArtifacts().values()); + } + } + } + + if (!allArtifactsToAdd.isEmpty()) { + + for (ArtifactDefinition deploymentArtifactDefinition : allArtifactsToAdd) { + String artifactFileName = deploymentArtifactDefinition.getArtifactName(); + byte[] payloadData = deploymentArtifactDefinition.getPayloadData(); + + if (payloadData == null) { + String esId = deploymentArtifactDefinition.getEsId(); + if (esId != null) { + Either<byte[], ActionStatus> fromCassandra = getFromCassandra(esId); + + if (fromCassandra.isRight()) { + return Either.right(fromCassandra.right().value()); + } + payloadData = fromCassandra.left().value(); + } else { + log.debug("Artifact {} payload not supplied in ArtifactDefinition and not found in DB", artifactFileName); + continue; + } + } + + byte[] decodedPayload = null; + + if (Base64.isBase64(payloadData)) { + // decodedPayload = Base64.getDecoder().decode(payloadData); + decodedPayload = Base64.decodeBase64(payloadData); + } else { + decodedPayload = payloadData; + } + + zip.putNextEntry(new ZipEntry(ARTIFACTS_PATH + artifactFileName)); + zip.write(decodedPayload); + } + } + + return Either.left(zip); + } + + private Either<List<ArtifactDefinition>, ResponseFormat> handleAAIArtifacts(Component component, ZipOutputStream zip, boolean mockGenerator, boolean shouldLock, boolean inTransaction, List<ImmutablePair<Component, byte[]>> generatorInputs) { + + ComponentTypeEnum componentType = component.getComponentType(); + List<Artifact> generatedArtifacts = null; + List<ArtifactDefinition> aaiArtifacts = null; + + if (componentType == ComponentTypeEnum.SERVICE && !generatorInputs.isEmpty()) { + List<Artifact> convertedGeneratorInputs = convertToGeneratorArtifactsInput(generatorInputs); + + Either<List<Artifact>, ResponseFormat> generatorResponse; + + if (mockGenerator) { + generatorResponse = artifactGenerator(convertedGeneratorInputs, ArtifactType.OTHER, component); + } else { + generatorResponse = artifactGenerator(convertedGeneratorInputs, ArtifactType.AAI, component); + } + + if (generatorResponse.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), generatorResponse.toString()); + return Either.right(responseFormat); + } + + generatedArtifacts = generatorResponse.left().value(); + + aaiArtifacts = convertToArtifactDefinitionFromArtifactGeneratedData(generatedArtifacts); + + } + + return Either.left(aaiArtifacts); + } + + private Either<ActionStatus, ResponseFormat> handleAllAAIArtifactsInDataModel(Component component, List<ArtifactDefinition> artifactsFromAAI, boolean shouldLock, boolean inTransaction) { + + Either<ActionStatus, ResponseFormat> handleAAIArtifactsResponse = null; + User lastComponentUpdater = null; + + List<ArtifactDefinition> aaiArtifatcsToCreate = getAAIArtifatcsForCreate(artifactsFromAAI, component); + List<ArtifactDefinition> aaiArtifatcsToDelete = getAAIArtifatcsForDelete(artifactsFromAAI, component); + List<ArtifactDefinition> aaiArtifatcsToUpdate = getAAIArtifatcsForUpdate(artifactsFromAAI, component); + + String lastUpdaterUserId = component.getLastUpdaterUserId(); + Either<User, ResponseFormat> validateUserExists = artifactsBusinessLogic.validateUserExists(lastUpdaterUserId, "CSAR creation util", true); + + if (validateUserExists.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), "User not found"); + return Either.right(responseFormat); + } + + lastComponentUpdater = validateUserExists.left().value(); + + handleAAIArtifactsResponse = handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToDelete, ArtifactOperation.Delete, lastComponentUpdater, shouldLock, inTransaction); + + if (handleAAIArtifactsResponse.isRight()) { + return handleAAIArtifactsResponse; + } + + handleAAIArtifactsResponse = handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToCreate, ArtifactOperation.Create, lastComponentUpdater, shouldLock, inTransaction); + + if (handleAAIArtifactsResponse.isRight()) { + return handleAAIArtifactsResponse; + } + + return handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToUpdate, ArtifactOperation.Update, lastComponentUpdater, shouldLock, inTransaction); + } + + private List<ArtifactDefinition> getAAIArtifatcsForUpdate(List<ArtifactDefinition> artifactsFromAAI, Component component) { + + Set<String> componetDeploymentArtifactLables = component.getDeploymentArtifacts().keySet(); + Set<String> componetInformationalArtifactLables = component.getArtifacts().keySet(); + + List<ArtifactDefinition> artifactsAaiUpdate = artifactsFromAAI.stream().filter(e -> (componetDeploymentArtifactLables.contains(e.getArtifactLabel()) || componetInformationalArtifactLables.contains(e.getArtifactLabel()))) + .filter(e -> checkAaiForUpdate(component, e)).collect(Collectors.toList()); + + return artifactsAaiUpdate; + } + + private boolean checkAaiForUpdate(Component component, ArtifactDefinition artifactDefinition) { + ArtifactDefinition artifactDefinitionComp = component.getDeploymentArtifacts().get(artifactDefinition.getArtifactLabel()); + + if (artifactDefinitionComp == null) { + log.warn("Failed to get {} artifact", artifactDefinition.getArtifactLabel()); + return false; + } + + // Old Artifacts before the generated flag introduction if contains "aai" ignore case prefix updated + if (artifactDefinitionComp.getGenerated() == null) { + if (artifactDefinitionComp.getArtifactLabel().toLowerCase().startsWith("aai")) { + return true; + } else { + log.warn("The artifact {} flag is null but AAI prefix is abssent Not updated", artifactDefinition.getArtifactLabel()); + } + } else { + if (artifactDefinition.getGenerated()) { + return true; + } else { + log.warn("Generated artifact {} was already uploaded manually", artifactDefinition.getArtifactLabel()); + } + } + return false; + } + + private List<ArtifactDefinition> getAAIArtifatcsForDelete(List<ArtifactDefinition> artifactsFromAAI, Component component) { + + Set<String> aaiLabels = artifactsFromAAI.stream().map(e -> e.getArtifactLabel()).collect(Collectors.toSet()); + + List<ArtifactDefinition> artifactsForDeleteDeployment = component.getDeploymentArtifacts().values().stream(). + // Filter Out Artifacts that are not contained in artifacts returned + // from AAI API + filter(e -> !aaiLabels.contains(e.getArtifactLabel())).collect(Collectors.toList()); + + List<ArtifactDefinition> artifactsForDeleteInformational = component.getArtifacts().values().stream(). + // Filter Out Artifacts that are not contained in artifacts returned + // from AAI API + filter(e -> !aaiLabels.contains(e.getArtifactLabel())).collect(Collectors.toList()); + + artifactsForDeleteDeployment.addAll(artifactsForDeleteInformational); + + return artifactsForDeleteDeployment.stream().filter(e -> (e.getGenerated() != null && e.getGenerated().equals(Boolean.TRUE)) || (e.getGenerated() == null && e.getArtifactLabel().toLowerCase().startsWith("aai"))).collect(Collectors.toList()); + } + + private List<ArtifactDefinition> getAAIArtifatcsForCreate(List<ArtifactDefinition> artifactsFromAAI, Component component) { + + Set<String> componentDeploymentLabels = component.getDeploymentArtifacts().keySet(); + Set<String> componentInfoLabels = component.getArtifacts().keySet(); + + // If the artifact label does not exist in the service - + // store the artifact (generate uuid and version, "generated" flag is TRUE) + return artifactsFromAAI.stream().filter(e -> !componentDeploymentLabels.contains(e.getArtifactLabel()) && !componentInfoLabels.contains(e.getArtifactLabel())).collect(Collectors.toList()); + } + + private Either<ActionStatus, ResponseFormat> handleAAIArtifactsInDataModelByOperationType(Component component, List<ArtifactDefinition> generatedArtifactsDefinitions, ArtifactOperation operationType, User user, boolean shouldLock, + boolean inTransaction) { + + String componentUniqueId = component.getUniqueId(); + ComponentTypeEnum componentType = component.getComponentType(); + + for (ArtifactDefinition artDef : generatedArtifactsDefinitions) { + String data = gson.toJson(artDef); + String dataMD5 = GeneralUtility.calculateMD5ByString(data); + String artifactUniqueId = null; + + if (operationType.equals(ArtifactOperation.Update) || operationType.equals(ArtifactOperation.Delete)) { + String artifactLabel = artDef.getArtifactLabel(); + ArtifactDefinition artifactDefinition = component.getDeploymentArtifacts().get(artifactLabel); + if (artifactDefinition != null) { + artifactUniqueId = artifactDefinition.getUniqueId(); + } + } + + Either<Either<ArtifactDefinition, Operation>, ResponseFormat> validateAndHandleArtifact = artifactsBusinessLogic.validateAndHandleArtifact(componentUniqueId, componentType, operationType, artifactUniqueId, artDef, dataMD5, data, null, + null, null, user, component, shouldLock, inTransaction); + + if (validateAndHandleArtifact.isRight()) { + if (ArtifactOperation.Create == operationType || ArtifactOperation.Update == operationType) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, componentType.getValue(), component.getName(), validateAndHandleArtifact.right().value().toString()); + + Either.right(responseFormat); + } else { + log.warn("Generated artifact {} could not be deleted", artDef.getArtifactLabel()); + } + } + } + + return Either.left(ActionStatus.OK); + } + + private List<ArtifactDefinition> convertToArtifactDefinitionFromArtifactGeneratedData(List<Artifact> generatorOutput) { + List<ArtifactDefinition> artifactDefList = new LinkedList<>(); + + for (Artifact artifact : generatorOutput) { + ArtifactDefinition newEntry = new ArtifactDefinition(); + newEntry.setArtifactName(artifact.getName()); + newEntry.setArtifactType(artifact.getType()); + newEntry.setArtifactGroupType(ArtifactGroupTypeEnum.findType(artifact.getGroupType())); + newEntry.setDescription(artifact.getDescription()); + + // Normalizing the artifact label to match those stored in DB + String normalizeArtifactLabel = ValidationUtils.normalizeArtifactLabel(artifact.getLabel()); + newEntry.setArtifactLabel(normalizeArtifactLabel); + newEntry.setPayload(artifact.getPayload()); + newEntry.setArtifactChecksum(artifact.getChecksum()); + // Flag that set to true in case that the artifact is generated by AI&I generator + newEntry.setGenerated(Boolean.TRUE); + + artifactDefList.add(newEntry); + } + + return artifactDefList; + } + + // List<ImmutablePair<Component, byte[] artifactBytes>> + // artifact stored by label + private List<Artifact> convertToGeneratorArtifactsInput(List<ImmutablePair<Component, byte[]>> inputs) { + List<Artifact> listOfArtifactsInput = new LinkedList<>(); + for (ImmutablePair<Component, byte[]> triple : inputs) { + Component component = triple.getLeft(); + + Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts(); + ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE); + + String artifactName = artifactDefinition.getArtifactName(); + String artifactType = artifactDefinition.getArtifactType(); + String artifactGroupType = artifactDefinition.getArtifactGroupType().getType(); + String artifactDescription = artifactDefinition.getDescription(); + String artifactLabel = artifactDefinition.getArtifactLabel(); + byte[] right = triple.getRight(); + // The md5 calculated on the uncoded data + String md5Hex = DigestUtils.md5Hex(right); + // byte[] payload = Base64.getEncoder().encode(right); + byte[] payload = Base64.encodeBase64(right); + String artifactVersion = artifactDefinition.getArtifactVersion(); + + Artifact convertedArtifact = new Artifact(artifactType, artifactGroupType, md5Hex, payload); + convertedArtifact.setName(artifactName); + convertedArtifact.setDescription(artifactDescription); + convertedArtifact.setLabel(artifactLabel); + convertedArtifact.setVersion(artifactVersion); + + listOfArtifactsInput.add(convertedArtifact); + } + + return listOfArtifactsInput; + } + + private Either<byte[], ActionStatus> getEntryData(String esId, Component childComponent) { + byte[] content; + if (esId == null || esId.isEmpty()) { + Either<ToscaRepresentation, ToscaError> exportRes = toscaExportUtils.exportComponent(childComponent); + if (exportRes.isRight()) { + log.debug("Failed to export tosca template for child component {} error {}", childComponent.getUniqueId(), exportRes.right().value()); + return Either.right(componentsUtils.convertFromToscaError(exportRes.right().value())); + } + content = exportRes.left().value().getMainYaml().getBytes(); + } else { + Either<byte[], ActionStatus> fromCassandra = getFromCassandra(esId); + if (fromCassandra.isRight()) { + return Either.right(fromCassandra.right().value()); + } else { + content = fromCassandra.left().value(); + } + } + return Either.left(content); + } + + private Either<byte[], ActionStatus> getFromCassandra(String esId) { + Either<ESArtifactData, CassandraOperationStatus> artifactResponse = artifactCassandraDao.getArtifact(esId); + + if (artifactResponse.isRight()) { + log.debug("In createCsar fetching of artifact from CS failed"); + log.debug("Failed to fetch from Cassandra by id {} error {} ", esId, artifactResponse.right().value()); + + StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactResponse.right().value()); + ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus); + return Either.right(convertedFromStorageResponse); + } else { + ESArtifactData artifactData = artifactResponse.left().value(); + return Either.left(artifactData.getDataAsArray()); + + } + } + + private String createToscaBlock0(String metaFileVersion, String csarVersion, String createdBy, String entryDef) { + final String BLOCK_0_TEMPLATE = "TOSCA-Meta-File-Version: %s\nCSAR-Version: %s\nCreated-By: %s\nEntry-Definitions: Definitions/%s\n"; + String readyBlock = String.format(BLOCK_0_TEMPLATE, metaFileVersion, csarVersion, createdBy, entryDef); + return readyBlock; + } + + private Either<List<Artifact>, ResponseFormat> artifactGenerator(List<Artifact> artifactList, ArtifactType type, Component component) { + + ArtifactGenerationServiceImpl artifactGenerationServiceImpl = new ArtifactGenerationServiceImpl(); + ArtifactTypes artifactTypes = new ArtifactTypes(); + List<ArtifactType> artifactTypesList = new LinkedList<>(); + ArtifactType otherType; + + if (type == null) { + otherType = ArtifactType.OTHER; + } else { + otherType = type; + } + + artifactTypesList.add(otherType); + artifactTypes.setArtifactTypes(artifactTypesList); + + String configJson = gson.toJson(artifactTypes); + GenerationData generatedArtifacts = artifactGenerationServiceImpl.generateArtifact(artifactList, configJson); + + Map<String, List<String>> errorData = generatedArtifacts.getErrorData(); + + if (!errorData.isEmpty()) { + Set<String> keySet = errorData.keySet(); + + for (String key : keySet) { + List<String> errorList = errorData.get(key); + log.debug("The Artifact Generator Failed - {} with following: {}", key, errorList); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), errorData.toString()); + return Either.right(responseFormat); + } + + return Either.left(generatedArtifacts.getResultData()); + } + +} |