Initial OpenECOMP SDC commit
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / tosca / CsarUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.tosca;
22
23 import java.io.IOException;
24 import org.apache.commons.codec.binary.Base64;
25 import java.util.Collection;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.stream.Collectors;
31 import java.util.zip.ZipEntry;
32 import java.util.zip.ZipOutputStream;
33
34 import org.apache.commons.codec.digest.DigestUtils;
35 import org.apache.commons.io.output.ByteArrayOutputStream;
36 import org.apache.commons.lang3.tuple.ImmutablePair;
37 import org.apache.commons.lang3.tuple.Triple;
38 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
39 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperation;
40 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
41 import org.openecomp.sdc.be.dao.api.ActionStatus;
42 import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
43 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
44 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
45 import org.openecomp.sdc.be.impl.ComponentsUtils;
46 import org.openecomp.sdc.be.model.ArtifactDefinition;
47 import org.openecomp.sdc.be.model.Component;
48 import org.openecomp.sdc.be.model.LifecycleStateEnum;
49 import org.openecomp.sdc.be.model.Operation;
50 import org.openecomp.sdc.be.model.Service;
51 import org.openecomp.sdc.be.model.User;
52 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
53 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
54 import org.openecomp.sdc.be.model.operations.impl.ServiceOperation;
55 import org.openecomp.sdc.be.resources.data.ESArtifactData;
56 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
57 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
58 import org.openecomp.sdc.common.util.GeneralUtility;
59 import org.openecomp.sdc.common.util.ValidationUtils;
60 import org.openecomp.sdc.exception.ResponseFormat;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63 import org.springframework.beans.factory.annotation.Autowired;
64
65 import org.openecomp.sdc.generator.data.Artifact;
66 import org.openecomp.sdc.generator.data.ArtifactType;
67 import org.openecomp.sdc.generator.data.GenerationData;
68 import org.openecomp.sdc.generator.impl.ArtifactGenerationServiceImpl;
69 import com.google.gson.Gson;
70
71 import fj.data.Either;
72
73 /**
74  * @author tg851x
75  *
76  */
77 @org.springframework.stereotype.Component("csar-utils")
78 public class CsarUtils {
79         private static Logger log = LoggerFactory.getLogger(ToscaExportHandler.class.getName());
80
81         @Autowired
82         private ArtifactCassandraDao artifactCassandraDao;
83         @Autowired
84         private ComponentsUtils componentsUtils;
85         @Autowired
86         private ToscaExportHandler toscaExportUtils;
87         @Autowired
88         private ArtifactsBusinessLogic artifactsBusinessLogic;
89         @Autowired
90         protected ServiceOperation serviceOperation;
91
92         @javax.annotation.Resource
93         private ServiceBusinessLogic serviceBusinessLogic;
94
95         private Gson gson = new Gson();
96
97         private static final String DEFINITIONS_PATH = "Definitions/";
98         private static final String ARTIFACTS_PATH = "Artifacts/";
99         private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta";
100         private static final String TOSCA_META_VERSION = "1.0";
101         private static final String CSAR_VERSION = "1.1";
102
103         /**
104          * 
105          * @param component
106          * @param getFromCS
107          * @param isInCertificationRequest
108          * @param shouldLock
109          * @param inTransaction
110          * @return
111          */
112         public Either<byte[], ResponseFormat> createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest, boolean shouldLock, boolean inTransaction) {
113                 return createCsar(component, getFromCS, isInCertificationRequest, false, shouldLock, inTransaction);
114         }
115
116         private Either<byte[], ResponseFormat> createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) {
117                 final String CREATED_BY = component.getCreatorFullName();
118
119                 String fileName;
120                 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
121                 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
122                 fileName = artifactDefinition.getArtifactName();
123
124                 String toscaBlock0 = createToscaBlock0(TOSCA_META_VERSION, CSAR_VERSION, CREATED_BY, fileName);
125
126                 byte[] toscaBlock0Byte = toscaBlock0.getBytes();
127
128                 Either<byte[], ResponseFormat> generateCsarZipResponse = generateCsarZip(toscaBlock0Byte, component, getFromCS, isInCertificationRequest, mockGenerator, shouldLock, inTransaction);
129
130                 if (generateCsarZipResponse.isRight()) {
131                         return Either.right(generateCsarZipResponse.right().value());
132                 }
133
134                 return Either.left(generateCsarZipResponse.left().value());
135         }
136
137         private Either<byte[], ResponseFormat> generateCsarZip(byte[] toscaBlock0Byte, Component component, boolean getFromCS, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) {
138
139                 ZipOutputStream zip = null;
140                 ByteArrayOutputStream out = null;
141                 try {
142                         out = new ByteArrayOutputStream();
143                         zip = new ZipOutputStream(out);
144
145                         zip.putNextEntry(new ZipEntry(TOSCA_META_PATH_FILE_NAME));
146                         zip.write(toscaBlock0Byte);
147                         Either<ZipOutputStream, ResponseFormat> populateZip = populateZip(component, getFromCS, zip, isInCertificationRequest, mockGenerator, shouldLock, inTransaction);
148                         if (populateZip.isRight()) {
149                                 log.debug("Failed to populate CSAR zip file {}", populateZip.right().value());
150                                 return Either.right(populateZip.right().value());
151                         }
152                         zip = populateZip.left().value();
153
154                         zip.finish();
155                         byte[] byteArray = out.toByteArray();
156
157                         return Either.left(byteArray);
158                 } catch (IOException e) {
159                         log.debug("createCsar failed IOexception", e);
160
161                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
162                         return Either.right(responseFormat);
163                 } finally {
164                         try {
165                                 if (zip != null) {
166                                         zip.close();
167                                 }
168                                 if (out != null) {
169                                         out.close();
170                                 }
171                         } catch (Exception e) {
172                                 log.error("Failed to close resources ", e);
173                         }
174                 }
175         }
176
177         private Either<ZipOutputStream, ResponseFormat> populateZip(Component component, boolean getFromCS, ZipOutputStream zip, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) {
178
179                 LifecycleStateEnum lifecycleState = component.getLifecycleState();
180                 String componentYaml = null;
181                 Either<ToscaRepresentation, ToscaError> exportComponent = null;
182                 byte[] mainYaml = null;
183                 // <file name, esid, component>
184                 List<Triple<String, String, Component>> dependencies = null;
185                 List<ImmutablePair<Component, byte[]>> generatorInputs = new LinkedList<>();
186
187                 String fileName;
188                 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
189                 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
190                 fileName = artifactDefinition.getArtifactName();
191
192                 if (getFromCS || !(lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) {
193                         String esId = artifactDefinition.getEsId();
194                         Either<byte[], ActionStatus> fromCassandra = getFromCassandra(esId);
195                         if (fromCassandra.isRight()) {
196                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(fromCassandra.right().value());
197                                 return Either.right(responseFormat);
198                         }
199                         mainYaml = fromCassandra.left().value();
200
201                 } else {
202                         exportComponent = toscaExportUtils.exportComponent(component);
203                         if (exportComponent.isRight()) {
204                                 log.debug("exportComponent failed", exportComponent.right().value());
205                                 ActionStatus convertedFromToscaError = componentsUtils.convertFromToscaError(exportComponent.right().value());
206                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertedFromToscaError);
207                                 return Either.right(responseFormat);
208                         }
209                         ToscaRepresentation exportResult = exportComponent.left().value();
210                         componentYaml = exportResult.getMainYaml();
211                         mainYaml = componentYaml.getBytes();
212                         dependencies = exportResult.getDependencies();
213                 }
214
215                 try {
216                         zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName));
217                         zip.write(mainYaml);
218
219                         generatorInputs.add(new ImmutablePair<Component, byte[]>(component, mainYaml));
220
221                         if (dependencies == null) {
222                                 Either<ToscaTemplate, ToscaError> dependenciesRes = toscaExportUtils.getDependencies(component);
223                                 if (dependenciesRes.isRight()) {
224                                         log.debug("Failed to retrieve dependencies for component {}, error {}", component.getUniqueId(), dependenciesRes.right().value());
225                                         ActionStatus convertFromToscaError = componentsUtils.convertFromToscaError(dependenciesRes.right().value());
226                                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertFromToscaError);
227                                         return Either.right(responseFormat);
228                                 }
229                                 dependencies = dependenciesRes.left().value().getDependencies();
230                         }
231                         if (dependencies != null && !dependencies.isEmpty()) {
232                                 for (Triple<String, String, Component> d : dependencies) {
233                                         String esId = d.getMiddle();
234                                         Component childComponent = d.getRight();
235                                         fileName = d.getLeft();
236                                         Either<byte[], ActionStatus> entryData = getEntryData(esId, childComponent);
237
238                                         if (entryData.isRight()) {
239                                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(entryData.right().value());
240                                                 return Either.right(responseFormat);
241                                         }
242
243                                         byte[] content = entryData.left().value();
244                                         zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName));
245                                         zip.write(content);
246
247                                         generatorInputs.add(new ImmutablePair<Component, byte[]>(childComponent, content));
248                                 }
249                         }
250
251                         List<ArtifactDefinition> aiiArtifactList = new LinkedList<>();
252                         // Artifact Generation
253                         if (component.getComponentType() == ComponentTypeEnum.SERVICE && (lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) {
254                                 Either<List<ArtifactDefinition>, ResponseFormat> handleAAIArtifacts = handleAAIArtifacts(component, zip, mockGenerator, shouldLock, inTransaction, generatorInputs);
255
256                                 if (handleAAIArtifacts.isLeft()) {
257                                         aiiArtifactList = handleAAIArtifacts.left().value();
258                                 } else {
259                                         log.debug("AAI Artifacts handling failed");
260                                         return Either.right(handleAAIArtifacts.right().value());
261                                 }
262
263                                 if (isInCertificationRequest) {
264                                         Either<ActionStatus, ResponseFormat> handleAllAAIArtifactsInDataModel = handleAllAAIArtifactsInDataModel(component, aiiArtifactList, shouldLock, inTransaction);
265
266                                         if (handleAllAAIArtifactsInDataModel.isRight()) {
267                                                 log.debug("AAI Artifacts handling (create, update, delete) failed");
268                                                 return Either.right(handleAllAAIArtifactsInDataModel.right().value());
269                                         }
270                                 }
271
272                         }
273
274                         // Collecting All Deployment Artifacts
275                         Either<ZipOutputStream, ActionStatus> collectAndWriteToScarDeploymentArtifacts = collectAndWriteToScarDeploymentArtifacts(zip, component, aiiArtifactList);
276
277                         if (collectAndWriteToScarDeploymentArtifacts.isRight()) {
278                                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
279                         }
280                 } catch (IOException e) {
281                         log.debug("Failed to create CSAR zip for component {}", component.getUniqueId(), e);
282                 }
283
284                 return Either.left(zip);
285         }
286
287         private Either<ZipOutputStream, ActionStatus> collectAndWriteToScarDeploymentArtifacts(ZipOutputStream zip, Component component, List<ArtifactDefinition> aiiArtifactList) throws IOException {
288
289                 Collection<ArtifactDefinition> deploymentArtifactsToAdd = null;
290                 Collection<ArtifactDefinition> allArtifactsToAdd = new LinkedList<>();
291
292                 if (component.getComponentType() == ComponentTypeEnum.SERVICE) {
293                         Either<Service, StorageOperationStatus> getServiceResponse = serviceOperation.getService(component.getUniqueId());
294
295                         if (getServiceResponse.isLeft()) {
296                                 Service service = getServiceResponse.left().value();
297
298                                 if (!aiiArtifactList.isEmpty()) {
299                                         deploymentArtifactsToAdd = service.getDeploymentArtifacts().values().stream().filter(e -> e.getGenerated() == null || !e.getGenerated()).collect(Collectors.toList());
300                                         allArtifactsToAdd.addAll(aiiArtifactList);
301                                         allArtifactsToAdd.addAll(deploymentArtifactsToAdd);
302                                 } else {
303                                         allArtifactsToAdd.addAll(service.getDeploymentArtifacts().values());
304                                 }
305                         }
306                 }
307
308                 if (!allArtifactsToAdd.isEmpty()) {
309
310                         for (ArtifactDefinition deploymentArtifactDefinition : allArtifactsToAdd) {
311                                 String artifactFileName = deploymentArtifactDefinition.getArtifactName();
312                                 byte[] payloadData = deploymentArtifactDefinition.getPayloadData();
313
314                                 if (payloadData == null) {
315                                         String esId = deploymentArtifactDefinition.getEsId();
316                                         if (esId != null) {
317                                                 Either<byte[], ActionStatus> fromCassandra = getFromCassandra(esId);
318
319                                                 if (fromCassandra.isRight()) {
320                                                         return Either.right(fromCassandra.right().value());
321                                                 }
322                                                 payloadData = fromCassandra.left().value();
323                                         } else {
324                                                 log.debug("Artifact {} payload not supplied in ArtifactDefinition and not found in DB", artifactFileName);
325                                                 continue;
326                                         }
327                                 }
328
329                                 byte[] decodedPayload = null;
330
331                                 if (Base64.isBase64(payloadData)) {
332                                         // decodedPayload = Base64.getDecoder().decode(payloadData);
333                                         decodedPayload = Base64.decodeBase64(payloadData);
334                                 } else {
335                                         decodedPayload = payloadData;
336                                 }
337
338                                 zip.putNextEntry(new ZipEntry(ARTIFACTS_PATH + artifactFileName));
339                                 zip.write(decodedPayload);
340                         }
341                 }
342
343                 return Either.left(zip);
344         }
345
346         private Either<List<ArtifactDefinition>, ResponseFormat> handleAAIArtifacts(Component component, ZipOutputStream zip, boolean mockGenerator, boolean shouldLock, boolean inTransaction, List<ImmutablePair<Component, byte[]>> generatorInputs) {
347
348                 ComponentTypeEnum componentType = component.getComponentType();
349                 List<Artifact> generatedArtifacts = null;
350                 List<ArtifactDefinition> aaiArtifacts = null;
351
352                 if (componentType == ComponentTypeEnum.SERVICE && !generatorInputs.isEmpty()) {
353                         List<Artifact> convertedGeneratorInputs = convertToGeneratorArtifactsInput(generatorInputs);
354
355                         Either<List<Artifact>, ResponseFormat> generatorResponse;
356
357                         if (mockGenerator) {
358                                 generatorResponse = artifactGenerator(convertedGeneratorInputs, ArtifactType.OTHER, component);
359                         } else {
360                                 generatorResponse = artifactGenerator(convertedGeneratorInputs, ArtifactType.AAI, component);
361                         }
362
363                         if (generatorResponse.isRight()) {
364                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), generatorResponse.toString());
365                                 return Either.right(responseFormat);
366                         }
367
368                         generatedArtifacts = generatorResponse.left().value();
369
370                         aaiArtifacts = convertToArtifactDefinitionFromArtifactGeneratedData(generatedArtifacts);
371
372                 }
373
374                 return Either.left(aaiArtifacts);
375         }
376
377         private Either<ActionStatus, ResponseFormat> handleAllAAIArtifactsInDataModel(Component component, List<ArtifactDefinition> artifactsFromAAI, boolean shouldLock, boolean inTransaction) {
378
379                 Either<ActionStatus, ResponseFormat> handleAAIArtifactsResponse = null;
380                 User lastComponentUpdater = null;
381
382                 List<ArtifactDefinition> aaiArtifatcsToCreate = getAAIArtifatcsForCreate(artifactsFromAAI, component);
383                 List<ArtifactDefinition> aaiArtifatcsToDelete = getAAIArtifatcsForDelete(artifactsFromAAI, component);
384                 List<ArtifactDefinition> aaiArtifatcsToUpdate = getAAIArtifatcsForUpdate(artifactsFromAAI, component);
385
386                 String lastUpdaterUserId = component.getLastUpdaterUserId();
387                 Either<User, ResponseFormat> validateUserExists = artifactsBusinessLogic.validateUserExists(lastUpdaterUserId, "CSAR creation util", true);
388
389                 if (validateUserExists.isRight()) {
390                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), "User not found");
391                         return Either.right(responseFormat);
392                 }
393
394                 lastComponentUpdater = validateUserExists.left().value();
395
396                 handleAAIArtifactsResponse = handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToDelete, ArtifactOperation.Delete, lastComponentUpdater, shouldLock, inTransaction);
397
398                 if (handleAAIArtifactsResponse.isRight()) {
399                         return handleAAIArtifactsResponse;
400                 }
401
402                 handleAAIArtifactsResponse = handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToCreate, ArtifactOperation.Create, lastComponentUpdater, shouldLock, inTransaction);
403
404                 if (handleAAIArtifactsResponse.isRight()) {
405                         return handleAAIArtifactsResponse;
406                 }
407
408                 return handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToUpdate, ArtifactOperation.Update, lastComponentUpdater, shouldLock, inTransaction);
409         }
410
411         private List<ArtifactDefinition> getAAIArtifatcsForUpdate(List<ArtifactDefinition> artifactsFromAAI, Component component) {
412
413                 Set<String> componetDeploymentArtifactLables = component.getDeploymentArtifacts().keySet();
414                 Set<String> componetInformationalArtifactLables = component.getArtifacts().keySet();
415
416                 List<ArtifactDefinition> artifactsAaiUpdate = artifactsFromAAI.stream().filter(e -> (componetDeploymentArtifactLables.contains(e.getArtifactLabel()) || componetInformationalArtifactLables.contains(e.getArtifactLabel())))
417                                 .filter(e -> checkAaiForUpdate(component, e)).collect(Collectors.toList());
418
419                 return artifactsAaiUpdate;
420         }
421
422         private boolean checkAaiForUpdate(Component component, ArtifactDefinition artifactDefinition) {
423                 ArtifactDefinition artifactDefinitionComp = component.getDeploymentArtifacts().get(artifactDefinition.getArtifactLabel());
424
425                 if (artifactDefinitionComp == null) {
426                         log.warn("Failed to get {} artifact", artifactDefinition.getArtifactLabel());
427                         return false;
428                 }
429
430                 // Old Artifacts before the generated flag introduction if contains "aai" ignore case prefix updated
431                 if (artifactDefinitionComp.getGenerated() == null) {
432                         if (artifactDefinitionComp.getArtifactLabel().toLowerCase().startsWith("aai")) {
433                                 return true;
434                         } else {
435                                 log.warn("The artifact {} flag is null but AAI prefix is abssent Not updated", artifactDefinition.getArtifactLabel());
436                         }
437                 } else {
438                         if (artifactDefinition.getGenerated()) {
439                                 return true;
440                         } else {
441                                 log.warn("Generated artifact {} was already uploaded manually", artifactDefinition.getArtifactLabel());
442                         }
443                 }
444                 return false;
445         }
446
447         private List<ArtifactDefinition> getAAIArtifatcsForDelete(List<ArtifactDefinition> artifactsFromAAI, Component component) {
448
449                 Set<String> aaiLabels = artifactsFromAAI.stream().map(e -> e.getArtifactLabel()).collect(Collectors.toSet());
450
451                 List<ArtifactDefinition> artifactsForDeleteDeployment = component.getDeploymentArtifacts().values().stream().
452                 // Filter Out Artifacts that are not contained in artifacts returned
453                 // from AAI API
454                                 filter(e -> !aaiLabels.contains(e.getArtifactLabel())).collect(Collectors.toList());
455
456                 List<ArtifactDefinition> artifactsForDeleteInformational = component.getArtifacts().values().stream().
457                 // Filter Out Artifacts that are not contained in artifacts returned
458                 // from AAI API
459                                 filter(e -> !aaiLabels.contains(e.getArtifactLabel())).collect(Collectors.toList());
460
461                 artifactsForDeleteDeployment.addAll(artifactsForDeleteInformational);
462
463                 return artifactsForDeleteDeployment.stream().filter(e -> (e.getGenerated() != null && e.getGenerated().equals(Boolean.TRUE)) || (e.getGenerated() == null && e.getArtifactLabel().toLowerCase().startsWith("aai"))).collect(Collectors.toList());
464         }
465
466         private List<ArtifactDefinition> getAAIArtifatcsForCreate(List<ArtifactDefinition> artifactsFromAAI, Component component) {
467
468                 Set<String> componentDeploymentLabels = component.getDeploymentArtifacts().keySet();
469                 Set<String> componentInfoLabels = component.getArtifacts().keySet();
470
471                 // If the artifact label does not exist in the service -
472                 // store the artifact (generate uuid and version, "generated" flag is TRUE)
473                 return artifactsFromAAI.stream().filter(e -> !componentDeploymentLabels.contains(e.getArtifactLabel()) && !componentInfoLabels.contains(e.getArtifactLabel())).collect(Collectors.toList());
474         }
475
476         private Either<ActionStatus, ResponseFormat> handleAAIArtifactsInDataModelByOperationType(Component component, List<ArtifactDefinition> generatedArtifactsDefinitions, ArtifactOperation operationType, User user, boolean shouldLock,
477                         boolean inTransaction) {
478
479                 String componentUniqueId = component.getUniqueId();
480                 ComponentTypeEnum componentType = component.getComponentType();
481
482                 for (ArtifactDefinition artDef : generatedArtifactsDefinitions) {
483                         String data = gson.toJson(artDef);
484                         String dataMD5 = GeneralUtility.calculateMD5ByString(data);
485                         String artifactUniqueId = null;
486
487                         if (operationType.equals(ArtifactOperation.Update) || operationType.equals(ArtifactOperation.Delete)) {
488                                 String artifactLabel = artDef.getArtifactLabel();
489                                 ArtifactDefinition artifactDefinition = component.getDeploymentArtifacts().get(artifactLabel);
490                                 if (artifactDefinition != null) {
491                                         artifactUniqueId = artifactDefinition.getUniqueId();
492                                 }
493                         }
494
495                         Either<Either<ArtifactDefinition, Operation>, ResponseFormat> validateAndHandleArtifact = artifactsBusinessLogic.validateAndHandleArtifact(componentUniqueId, componentType, operationType, artifactUniqueId, artDef, dataMD5, data, null,
496                                         null, null, user, component, shouldLock, inTransaction);
497
498                         if (validateAndHandleArtifact.isRight()) {
499                                 if (ArtifactOperation.Create == operationType || ArtifactOperation.Update == operationType) {
500                                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, componentType.getValue(), component.getName(), validateAndHandleArtifact.right().value().toString());
501
502                                         Either.right(responseFormat);
503                                 } else {
504                                         log.warn("Generated artifact {} could not be deleted", artDef.getArtifactLabel());
505                                 }
506                         }
507                 }
508
509                 return Either.left(ActionStatus.OK);
510         }
511
512         private List<ArtifactDefinition> convertToArtifactDefinitionFromArtifactGeneratedData(List<Artifact> generatorOutput) {
513                 List<ArtifactDefinition> artifactDefList = new LinkedList<>();
514
515                 for (Artifact artifact : generatorOutput) {
516                         ArtifactDefinition newEntry = new ArtifactDefinition();
517                         newEntry.setArtifactName(artifact.getName());
518                         newEntry.setArtifactType(artifact.getType());
519                         newEntry.setArtifactGroupType(ArtifactGroupTypeEnum.findType(artifact.getGroupType()));
520                         newEntry.setDescription(artifact.getDescription());
521
522                         // Normalizing the artifact label to match those stored in DB
523                         String normalizeArtifactLabel = ValidationUtils.normalizeArtifactLabel(artifact.getLabel());
524                         newEntry.setArtifactLabel(normalizeArtifactLabel);
525                         newEntry.setPayload(artifact.getPayload());
526                         newEntry.setArtifactChecksum(artifact.getChecksum());
527                         // Flag that set to true in case that the artifact is generated by AI&I generator
528                         newEntry.setGenerated(Boolean.TRUE);
529
530                         artifactDefList.add(newEntry);
531                 }
532
533                 return artifactDefList;
534         }
535
536         // List<ImmutablePair<Component, byte[] artifactBytes>>
537         // artifact stored by label
538         private List<Artifact> convertToGeneratorArtifactsInput(List<ImmutablePair<Component, byte[]>> inputs) {
539                 List<Artifact> listOfArtifactsInput = new LinkedList<>();
540                 for (ImmutablePair<Component, byte[]> triple : inputs) {
541                         Component component = triple.getLeft();
542
543                         Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
544                         ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
545
546                         String artifactName = artifactDefinition.getArtifactName();
547                         String artifactType = artifactDefinition.getArtifactType();
548                         String artifactGroupType = artifactDefinition.getArtifactGroupType().getType();
549                         String artifactDescription = artifactDefinition.getDescription();
550                         String artifactLabel = artifactDefinition.getArtifactLabel();
551                         byte[] right = triple.getRight();
552                         // The md5 calculated on the uncoded data
553                         String md5Hex = DigestUtils.md5Hex(right);
554                         // byte[] payload = Base64.getEncoder().encode(right);
555                         byte[] payload = Base64.encodeBase64(right);
556                         String artifactVersion = artifactDefinition.getArtifactVersion();
557
558                         Artifact convertedArtifact = new Artifact(artifactType, artifactGroupType, md5Hex, payload);
559                         convertedArtifact.setName(artifactName);
560                         convertedArtifact.setDescription(artifactDescription);
561                         convertedArtifact.setLabel(artifactLabel);
562                         convertedArtifact.setVersion(artifactVersion);
563
564                         listOfArtifactsInput.add(convertedArtifact);
565                 }
566
567                 return listOfArtifactsInput;
568         }
569
570         private Either<byte[], ActionStatus> getEntryData(String esId, Component childComponent) {
571                 byte[] content;
572                 if (esId == null || esId.isEmpty()) {
573                         Either<ToscaRepresentation, ToscaError> exportRes = toscaExportUtils.exportComponent(childComponent);
574                         if (exportRes.isRight()) {
575                                 log.debug("Failed to export tosca template for child component {} error {}", childComponent.getUniqueId(), exportRes.right().value());
576                                 return Either.right(componentsUtils.convertFromToscaError(exportRes.right().value()));
577                         }
578                         content = exportRes.left().value().getMainYaml().getBytes();
579                 } else {
580                         Either<byte[], ActionStatus> fromCassandra = getFromCassandra(esId);
581                         if (fromCassandra.isRight()) {
582                                 return Either.right(fromCassandra.right().value());
583                         } else {
584                                 content = fromCassandra.left().value();
585                         }
586                 }
587                 return Either.left(content);
588         }
589
590         private Either<byte[], ActionStatus> getFromCassandra(String esId) {
591                 Either<ESArtifactData, CassandraOperationStatus> artifactResponse = artifactCassandraDao.getArtifact(esId);
592
593                 if (artifactResponse.isRight()) {
594                         log.debug("In createCsar fetching of artifact from CS failed");
595                         log.debug("Failed to fetch from Cassandra by id {} error {} ", esId, artifactResponse.right().value());
596
597                         StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactResponse.right().value());
598                         ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus);
599                         return Either.right(convertedFromStorageResponse);
600                 } else {
601                         ESArtifactData artifactData = artifactResponse.left().value();
602                         return Either.left(artifactData.getDataAsArray());
603
604                 }
605         }
606
607         private String createToscaBlock0(String metaFileVersion, String csarVersion, String createdBy, String entryDef) {
608                 final String BLOCK_0_TEMPLATE = "TOSCA-Meta-File-Version: %s\nCSAR-Version: %s\nCreated-By: %s\nEntry-Definitions: Definitions/%s\n";
609                 String readyBlock = String.format(BLOCK_0_TEMPLATE, metaFileVersion, csarVersion, createdBy, entryDef);
610                 return readyBlock;
611         }
612
613         private Either<List<Artifact>, ResponseFormat> artifactGenerator(List<Artifact> artifactList, ArtifactType type, Component component) {
614
615                 ArtifactGenerationServiceImpl artifactGenerationServiceImpl = new ArtifactGenerationServiceImpl();
616                 ArtifactTypes artifactTypes = new ArtifactTypes();
617                 List<ArtifactType> artifactTypesList = new LinkedList<>();
618                 ArtifactType otherType;
619
620                 if (type == null) {
621                         otherType = ArtifactType.OTHER;
622                 } else {
623                         otherType = type;
624                 }
625
626                 artifactTypesList.add(otherType);
627                 artifactTypes.setArtifactTypes(artifactTypesList);
628
629                 String configJson = gson.toJson(artifactTypes);
630                 GenerationData generatedArtifacts = artifactGenerationServiceImpl.generateArtifact(artifactList, configJson);
631
632                 Map<String, List<String>> errorData = generatedArtifacts.getErrorData();
633
634                 if (!errorData.isEmpty()) {
635                         Set<String> keySet = errorData.keySet();
636
637                         for (String key : keySet) {
638                                 List<String> errorList = errorData.get(key);
639                                 log.debug("The Artifact Generator Failed - {} with following: {}", key, errorList);
640                         }
641
642                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), errorData.toString());
643                         return Either.right(responseFormat);
644                 }
645
646                 return Either.left(generatedArtifacts.getResultData());
647         }
648
649 }