[sdc] update code of sdc
[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.BufferedOutputStream;
24 import java.io.ByteArrayInputStream;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.EnumMap;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.LinkedList;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Map.Entry;
35 import java.util.Set;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38 import java.util.stream.Collectors;
39 import java.util.zip.ZipEntry;
40 import java.util.zip.ZipInputStream;
41 import java.util.zip.ZipOutputStream;
42
43 import org.apache.commons.codec.binary.Base64;
44 import org.apache.commons.codec.digest.DigestUtils;
45 import org.apache.commons.io.output.ByteArrayOutputStream;
46 import org.apache.commons.lang.WordUtils;
47 import org.apache.commons.lang3.tuple.ImmutablePair;
48 import org.apache.commons.lang3.tuple.ImmutableTriple;
49 import org.apache.commons.lang3.tuple.Triple;
50 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic;
51 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum;
52 import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationInfo;
53 import org.openecomp.sdc.be.components.impl.ImportUtils;
54 import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
55 import org.openecomp.sdc.be.config.Configuration.ArtifactTypeConfig;
56 import org.openecomp.sdc.be.config.ConfigurationManager;
57 import org.openecomp.sdc.be.dao.api.ActionStatus;
58 import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
59 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
60 import org.openecomp.sdc.be.dao.cassandra.SdcSchemaFilesCassandraDao;
61 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
62 import org.openecomp.sdc.be.impl.ComponentsUtils;
63 import org.openecomp.sdc.be.model.ArtifactDefinition;
64 import org.openecomp.sdc.be.model.Component;
65 import org.openecomp.sdc.be.model.ComponentInstance;
66 import org.openecomp.sdc.be.model.LifecycleStateEnum;
67 import org.openecomp.sdc.be.model.Operation;
68 import org.openecomp.sdc.be.model.Resource;
69 import org.openecomp.sdc.be.model.Service;
70 import org.openecomp.sdc.be.model.User;
71 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
72 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
73 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
74 import org.openecomp.sdc.be.model.operations.impl.LifecycleOperation;
75 import org.openecomp.sdc.be.resources.data.ESArtifactData;
76 import org.openecomp.sdc.be.resources.data.SdcSchemaFilesData;
77 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
78 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
79 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
80 import org.openecomp.sdc.common.impl.ExternalConfiguration;
81 import org.openecomp.sdc.common.util.GeneralUtility;
82 import org.openecomp.sdc.common.util.ValidationUtils;
83 import org.openecomp.sdc.exception.ResponseFormat;
84 import org.openecomp.sdc.generator.data.AdditionalParams;
85 import org.openecomp.sdc.generator.data.Artifact;
86 import org.openecomp.sdc.generator.data.ArtifactType;
87 import org.openecomp.sdc.generator.data.GenerationData;
88 import org.openecomp.sdc.generator.impl.ArtifactGenerationServiceImpl;
89 import org.slf4j.Logger;
90 import org.slf4j.LoggerFactory;
91 import org.springframework.beans.factory.annotation.Autowired;
92
93 import com.google.gson.Gson;
94
95 import fj.data.Either;
96
97
98 /**
99  * @author tg851x
100  *
101  */
102 @org.springframework.stereotype.Component("csar-utils")
103 public class CsarUtils {
104         private static Logger log = LoggerFactory.getLogger(CsarUtils.class.getName());
105
106         @Autowired
107         private SdcSchemaFilesCassandraDao sdcSchemaFilesCassandraDao;
108         @Autowired
109         private ArtifactCassandraDao artifactCassandraDao;
110         @Autowired
111         private ComponentsUtils componentsUtils;
112         @Autowired
113         private ToscaExportHandler toscaExportUtils;
114         @Autowired
115         private ArtifactsBusinessLogic artifactsBusinessLogic;
116         @Autowired
117         protected ToscaOperationFacade toscaOperationFacade;
118
119
120         @javax.annotation.Resource
121         private ServiceBusinessLogic serviceBusinessLogic;
122
123         private Gson gson = new Gson();
124
125         public static final String CONFORMANCE_LEVEL = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel();
126         public static final String SDC_VERSION = ExternalConfiguration.getAppVersion();
127         
128         public static final Pattern UUID_NORMATIVE_NEW_VERSION = Pattern.compile("^\\d{1,}.0");
129         public static final String ARTIFACTS_PATH = "Artifacts/";
130         public static final String RESOURCES_PATH = "Resources/";
131         public static final String INFORMATIONAL_ARTIFACTS = "Informational/";
132         public static final String DEPLOYMENT_ARTIFACTS = "Deployment/";
133
134         public static final String DEFINITIONS_PATH = "Definitions/";
135         private static final String CSAR_META_VERSION = "1.0";
136         private static final String CSAR_META_PATH_FILE_NAME = "csar.meta";
137         private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta";
138         private static final String TOSCA_META_VERSION = "1.0";
139         private static final String CSAR_VERSION = "1.1";
140         private static String versionFirstThreeOctates;
141         
142         public static final String VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN = ARTIFACTS_PATH + ImportUtils.Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX + "([\\d\\w\\_\\-\\.\\s]+)(/)([\\d\\w\\_\\-\\.\\s]+)(/)([\\d\\w\\_\\-\\.\\s\\/]+)";
143
144         public static final String VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN = ARTIFACTS_PATH +
145         // Artifact Group (i.e Deployment/Informational)
146                         "([\\w\\_\\-\\.\\s]+)(/)" +
147                         // Artifact Type
148                         "([\\w\\_\\-\\.\\s]+)(/)" +
149                         // Artifact File Name
150                         "([\\w\\_\\-\\.\\s]+)";
151         public static final String ARTIFACT_CREATED_FROM_CSAR = "Artifact created from csar";
152
153         public CsarUtils() {
154                 if(SDC_VERSION != null && !SDC_VERSION.isEmpty()){
155                         Matcher matcher = Pattern.compile("(?!\\.)(\\d+(\\.\\d+)+)(?![\\d\\.])").matcher(SDC_VERSION);
156                         matcher.find();
157                         versionFirstThreeOctates = matcher.group(0);                    
158                 } else {
159                         versionFirstThreeOctates = "";
160                 }
161         }
162         
163         /**
164          * 
165          * @param component
166          * @param getFromCS
167          * @param isInCertificationRequest
168          * @return
169          */
170         public Either<byte[], ResponseFormat> createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest) {
171                 return createCsar(component, getFromCS, isInCertificationRequest, false);
172         }
173
174         private Either<byte[], ResponseFormat> createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest, boolean mockGenerator) {
175                 final String createdBy = component.getCreatorFullName();
176
177                 String fileName;
178                 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
179                 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
180                 fileName = artifactDefinition.getArtifactName();
181
182                 String toscaConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel();
183                 String csarBlock0 = createCsarBlock0(CSAR_META_VERSION, toscaConformanceLevel);
184                 byte[] csarBlock0Byte = csarBlock0.getBytes();
185                 
186                 final String toscaBlock0 = createToscaBlock0(TOSCA_META_VERSION, CSAR_VERSION, createdBy, fileName);
187                 byte[] toscaBlock0Byte = toscaBlock0.getBytes();
188
189                 Either<byte[], ResponseFormat> generateCsarZipResponse = generateCsarZip(csarBlock0Byte, toscaBlock0Byte, component, getFromCS, isInCertificationRequest, mockGenerator);
190
191                 if (generateCsarZipResponse.isRight()) {
192                         return Either.right(generateCsarZipResponse.right().value());
193                 }
194
195                 return Either.left(generateCsarZipResponse.left().value());
196         }
197
198         private Either<byte[], ResponseFormat> generateCsarZip(byte[] csarBlock0Byte, byte[] toscaBlock0Byte, Component component, boolean getFromCS, boolean isInCertificationRequest, boolean mockGenerator) {
199                 try (
200                                 ByteArrayOutputStream out = new ByteArrayOutputStream();
201                                 ZipOutputStream zip = new ZipOutputStream(out);
202                                 ){
203                         zip.putNextEntry(new ZipEntry(CSAR_META_PATH_FILE_NAME));
204                         zip.write(csarBlock0Byte);
205                         zip.putNextEntry(new ZipEntry(TOSCA_META_PATH_FILE_NAME));
206                         zip.write(toscaBlock0Byte);
207                         Either<ZipOutputStream, ResponseFormat> populateZip = populateZip(component, getFromCS, zip, isInCertificationRequest, mockGenerator);
208                         if (populateZip.isRight()) {
209                                 log.debug("Failed to populate CSAR zip file {}", populateZip.right().value());
210                                 return Either.right(populateZip.right().value());
211                         }
212
213                         zip.finish();
214                         byte[] byteArray = out.toByteArray();
215
216                         return Either.left(byteArray);
217                 } catch (IOException e) {
218                         log.debug("Failed with IOexception to create CSAR zip for component {}", component.getUniqueId(), e);
219
220                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
221                         return Either.right(responseFormat);
222                 }
223         }
224
225         private Either<ZipOutputStream, ResponseFormat> populateZip(Component component, boolean getFromCS, ZipOutputStream zip, boolean isInCertificationRequest, boolean mockGenerator) throws IOException {
226
227                 LifecycleStateEnum lifecycleState = component.getLifecycleState();
228                 String componentYaml;
229                 Either<ToscaRepresentation, ToscaError> exportComponent;
230                 byte[] mainYaml;
231                 // <file name, cassandraId, component>
232                 List<Triple<String, String, Component>> dependencies = null;
233                 List<ImmutablePair<Component, byte[]>> generatorInputs = new LinkedList<>();
234
235                 Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
236                 ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
237                 String fileName = artifactDefinition.getArtifactName();
238
239                 if (getFromCS || !(lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) {
240                         String cassandraId = artifactDefinition.getEsId();
241                         Either<byte[], ActionStatus> fromCassandra = getFromCassandra(cassandraId);
242                         if (fromCassandra.isRight()) {
243                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(fromCassandra.right().value());
244                                 return Either.right(responseFormat);
245                         }
246                         mainYaml = fromCassandra.left().value();
247
248                 } else {
249                         exportComponent = toscaExportUtils.exportComponent(component);
250                         if (exportComponent.isRight()) {
251                                 log.debug("exportComponent failed", exportComponent.right().value());
252                                 ActionStatus convertedFromToscaError = componentsUtils.convertFromToscaError(exportComponent.right().value());
253                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertedFromToscaError);
254                                 return Either.right(responseFormat);
255                         }
256                         ToscaRepresentation exportResult = exportComponent.left().value();
257                         componentYaml = exportResult.getMainYaml();
258                         mainYaml = componentYaml.getBytes();
259                         dependencies = exportResult.getDependencies();
260                 }
261
262                 zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName));
263                 zip.write(mainYaml);
264                         //US798487 - Abstraction of complex types
265                         if (!ToscaUtils.isAtomicType(component)){
266                                 log.debug("Component {} is complex - generating abstract type for it..", component.getName());
267                                 writeComponentInterface(component, zip, fileName);
268                         }
269
270                 generatorInputs.add(new ImmutablePair<Component, byte[]>(component, mainYaml));
271
272                 if (dependencies == null) {
273                         Either<ToscaTemplate, ToscaError> dependenciesRes = toscaExportUtils.getDependencies(component);
274                         if (dependenciesRes.isRight()) {
275                                 log.debug("Failed to retrieve dependencies for component {}, error {}", component.getUniqueId(),
276                                                 dependenciesRes.right().value());
277                                 ActionStatus convertFromToscaError = componentsUtils.convertFromToscaError(dependenciesRes.right().value());
278                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertFromToscaError);
279                                 return Either.right(responseFormat);
280                         }
281                         dependencies = dependenciesRes.left().value().getDependencies();
282                 }
283                         
284                         //UID <cassandraId,filename,component>
285                         Map<String, ImmutableTriple<String,String, Component>> innerComponentsCache = new HashMap<>();
286                         
287                 if (dependencies != null && !dependencies.isEmpty()) {
288                         for (Triple<String, String, Component> d : dependencies) {
289                                         String cassandraId = d.getMiddle();
290                                 Component childComponent = d.getRight();
291                                         Either<byte[], ActionStatus> entryData = getEntryData(cassandraId, childComponent);
292
293                                 if (entryData.isRight()) {
294                                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(entryData.right().value());
295                                         return Either.right(responseFormat);
296                                 }
297
298                                         //fill innerComponentsCache
299                                         fileName = d.getLeft();
300                                         innerComponentsCache.put(childComponent.getUniqueId(), 
301                                                         new ImmutableTriple<String, String, Component>(cassandraId, fileName, childComponent));
302                                         insertInnerComponentsToCache(innerComponentsCache, childComponent);
303                                         
304                                         byte[] content = entryData.left().value();
305                                         generatorInputs.add(new ImmutablePair<Component, byte[]>(childComponent, content));
306                                 }
307                                 
308                                 //add inner components to CSAR
309                         
310                         for (Entry<String, ImmutableTriple<String, String, Component>> innerComponentTripleEntry : innerComponentsCache.entrySet()) {
311                                 
312                                 ImmutableTriple<String, String, Component> innerComponentTriple = innerComponentTripleEntry.getValue();
313
314                                 Component innerComponent = innerComponentTriple.getRight();
315                                 String icFileName = innerComponentTriple.getMiddle();
316
317                                 // add component to zip
318                                 Either<byte[], ActionStatus> entryData = getEntryData(innerComponentTriple.getLeft(), innerComponent);
319                                 byte[] content = entryData.left().value();
320                                 zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + icFileName));
321                                 zip.write(content);
322
323                                 // add component interface to zip
324                                 if (!ToscaUtils.isAtomicType(innerComponent)) {
325                                         writeComponentInterface(innerComponent, zip, icFileName);
326                                 }
327                         }
328                 }
329                 
330                 //retrieve SDC.zip from Cassandra 
331                 Either<byte[], ResponseFormat> latestSchemaFilesFromCassandra = getLatestSchemaFilesFromCassandra();
332                 
333                 if(latestSchemaFilesFromCassandra.isRight()){
334                         log.error("Error retrieving SDC Schema files from cassandra" );
335                         return Either.right(latestSchemaFilesFromCassandra.right().value());
336                 }
337                 
338                 //add files from retireved SDC.zip to Definitions folder in CSAR
339                 Either<ZipOutputStream, ResponseFormat> addSchemaFilesFromCassandra = addSchemaFilesFromCassandra(zip, latestSchemaFilesFromCassandra.left().value());
340                 
341                 if(addSchemaFilesFromCassandra.isRight()){
342                         return addSchemaFilesFromCassandra;
343                 }
344                 
345                 // Artifact Generation
346                 if (component.getComponentType() == ComponentTypeEnum.SERVICE
347                                 && isInCertificationRequest) {
348                         
349                         List<ArtifactDefinition> aiiArtifactList;
350                         
351                         Either<List<ArtifactDefinition>, ResponseFormat> handleAAIArtifacts = handleAAIArtifacts(component, mockGenerator, generatorInputs);
352
353                         if (handleAAIArtifacts.isLeft()) {
354                                 aiiArtifactList = handleAAIArtifacts.left().value();
355                         } else {
356                                 log.debug("AAI Artifacts handling failed");
357                                 return Either.right(handleAAIArtifacts.right().value());
358                         }
359
360                         if (isInCertificationRequest) {
361                                 Either<ActionStatus, ResponseFormat> handleAllAAIArtifactsInDataModel = handleAllAAIArtifactsInDataModel(
362                                                 component, aiiArtifactList, false, true);
363
364                                 if (handleAllAAIArtifactsInDataModel.isRight()) {
365                                         log.debug("AAI Artifacts handling (create, update, delete) failed");
366                                         return Either.right(handleAllAAIArtifactsInDataModel.right().value());
367                                 }
368                         }
369
370                 }
371
372                 Either<CsarDefinition, ResponseFormat> collectedComponentCsarDefinition = collectComponentCsarDefinition(component);
373
374                 if (collectedComponentCsarDefinition.isRight()) {
375                         return Either.right(collectedComponentCsarDefinition.right().value());
376                 }
377                 
378                 return writeAllFilesToScar(component, collectedComponentCsarDefinition.left().value(), zip, isInCertificationRequest);
379         }
380         
381         private Either<ZipOutputStream, ResponseFormat> addSchemaFilesFromCassandra(ZipOutputStream zip, byte[] schemaFileZip){
382                 
383                 final int initSize = 2048;
384                 
385                 log.debug("Starting coppy from Schema file zip to CSAR zip");
386                 
387                 try (ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip));
388                                 ByteArrayOutputStream out = new ByteArrayOutputStream();
389                                 BufferedOutputStream bos = new BufferedOutputStream(out, initSize);) {
390                         
391                         ZipEntry entry = null;
392                         
393                         while ((entry = zipStream.getNextEntry()) != null) {
394                         
395                                 String entryName = entry.getName();
396                                 int readSize = initSize;
397                                 byte[] entryData = new byte[initSize];
398
399                                 while ((readSize = zipStream.read(entryData, 0, readSize)) != -1) {
400                                         bos.write(entryData, 0, readSize);
401                                 }
402
403                                 bos.flush();
404                                 out.flush();
405                                 zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + entryName));
406                                 zip.write(out.toByteArray());
407                                 zip.flush();
408                                 out.reset();
409                         }
410                 } catch (IOException e) {
411                         log.error("Error while writing the SDC schema file to the CSAR {}", e);
412                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
413                 }
414                 
415                 log.debug("Finished coppy from Schema file zip to CSAR zip");
416                 
417                 return Either.left(zip);
418         }
419
420         
421         private void insertInnerComponentsToCache(Map<String, ImmutableTriple<String, String, Component>> componentCache,
422                         Component childComponent) {
423                 
424                 List<ComponentInstance> instances = childComponent.getComponentInstances();
425                 
426                 if(instances != null) {
427                         instances.forEach(ci -> {
428                                 ImmutableTriple<String, String, Component> componentRecord = componentCache.get(ci.getComponentUid());
429                                 if (componentRecord == null) {
430                                         // all resource must be only once!
431                                         Either<Resource, StorageOperationStatus> resource = toscaOperationFacade.getToscaElement(ci.getComponentUid());
432                                         if (resource.isRight()) {
433                                                 log.debug("Failed to fetch resource with id {} for instance {}");
434                                         }
435                                         Component componentRI = resource.left().value();
436                                         
437                                         Map<String, ArtifactDefinition> childToscaArtifacts = componentRI.getToscaArtifacts();
438                                         ArtifactDefinition childArtifactDefinition = childToscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
439                                         if (childArtifactDefinition != null) {
440                                                 //add to cache
441                                                 componentCache.put(ci.getComponentUid(), 
442                                                         new ImmutableTriple<String, String, Component>(childArtifactDefinition.getEsId(), 
443                                                                         childArtifactDefinition.getArtifactName(), componentRI));
444                                         }
445
446                                         //if not atomic - insert inner components as well
447                                         if(!ToscaUtils.isAtomicType(componentRI)) {
448                                                 insertInnerComponentsToCache(componentCache, componentRI);
449                                         }
450                                 }
451                         });
452                 }
453         }
454         
455         private Either<ZipOutputStream, ResponseFormat> writeComponentInterface(Component component, ZipOutputStream zip, String fileName) {
456                 try {
457                         Either<ToscaRepresentation, ToscaError> componentInterface = toscaExportUtils.exportComponentInterface(component);
458                         ToscaRepresentation componentInterfaceYaml = componentInterface.left().value();
459                         String mainYaml = componentInterfaceYaml.getMainYaml();
460                         String interfaceFileName = DEFINITIONS_PATH + ToscaExportHandler.getInterfaceFilename(fileName);
461                         
462                         zip.putNextEntry(new ZipEntry(interfaceFileName));
463                         zip.write(mainYaml.getBytes());
464                 
465                 } catch (Exception e) {
466                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
467                 }
468                 
469                 return Either.left(zip);
470         }
471         
472         private Either<List<ArtifactDefinition>, ResponseFormat> handleAAIArtifacts(Component component, boolean mockGenerator, List<ImmutablePair<Component, byte[]>> generatorInputs) {
473
474                 ComponentTypeEnum componentType = component.getComponentType();
475                 List<Artifact> generatedArtifacts;
476                 List<ArtifactDefinition> aaiArtifacts = new LinkedList<>();
477
478                 if (componentType == ComponentTypeEnum.SERVICE && !generatorInputs.isEmpty()) {
479                         List<Artifact> convertedGeneratorInputs = convertToGeneratorArtifactsInput(generatorInputs);
480
481                         Either<List<Artifact>, String> generatorResponse;
482
483                         if (mockGenerator) {
484                                 generatorResponse = artifactGenerator(convertedGeneratorInputs, ArtifactType.OTHER, component);
485                         } else {
486                                 generatorResponse = artifactGenerator(convertedGeneratorInputs, ArtifactType.AAI, component);
487                         }
488
489                         if (generatorResponse.isRight()) {
490                                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), generatorResponse.right().value());
491                                 return Either.right(responseFormat);
492                         }
493
494                         generatedArtifacts = generatorResponse.left().value();
495
496                         aaiArtifacts = convertToArtifactDefinitionFromArtifactGeneratedData(generatedArtifacts);
497
498                 }
499
500                 return Either.left(aaiArtifacts);
501         }
502
503         private Either<ActionStatus, ResponseFormat> handleAllAAIArtifactsInDataModel(Component component, List<ArtifactDefinition> artifactsFromAAI, boolean shouldLock, boolean inTransaction) {
504
505                 Either<ActionStatus, ResponseFormat> handleAAIArtifactsResponse;
506                 User lastComponentUpdater;
507
508                 List<ArtifactDefinition> aaiArtifatcsToCreate = getAAIArtifatcsForCreate(artifactsFromAAI, component);
509                 List<ArtifactDefinition> aaiArtifatcsToDelete = getAAIArtifatcsForDelete(artifactsFromAAI, component);
510                 List<ArtifactDefinition> aaiArtifatcsToUpdate = getAAIArtifatcsForUpdate(artifactsFromAAI, component);
511
512                 String lastUpdaterUserId = component.getLastUpdaterUserId();
513                 Either<User, ResponseFormat> validateUserExists = artifactsBusinessLogic.validateUserExists(lastUpdaterUserId, "CSAR creation util", true);
514
515                 if (validateUserExists.isRight()) {
516                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), "User not found");
517                         return Either.right(responseFormat);
518                 }
519
520                 lastComponentUpdater = validateUserExists.left().value();
521
522                 handleAAIArtifactsResponse = handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToDelete, artifactsBusinessLogic.new ArtifactOperationInfo(false, false, ArtifactOperationEnum.Delete), lastComponentUpdater, shouldLock,
523                                 inTransaction);
524
525                 if (handleAAIArtifactsResponse.isRight()) {
526                         return handleAAIArtifactsResponse;
527                 }
528
529                 handleAAIArtifactsResponse = handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToCreate, artifactsBusinessLogic.new ArtifactOperationInfo(false, false, ArtifactOperationEnum.Create), lastComponentUpdater, shouldLock,
530                                 inTransaction);
531
532                 if (handleAAIArtifactsResponse.isRight()) {
533                         return handleAAIArtifactsResponse;
534                 }
535
536                 return handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToUpdate, artifactsBusinessLogic.new ArtifactOperationInfo(false, false, ArtifactOperationEnum.Update), lastComponentUpdater, shouldLock, inTransaction);
537         }
538
539         private List<ArtifactDefinition> getAAIArtifatcsForUpdate(List<ArtifactDefinition> artifactsFromAAI, Component component) {
540
541                 Set<String> componetDeploymentArtifactLables = component.getDeploymentArtifacts().keySet();
542                 Set<String> componetInformationalArtifactLables = component.getArtifacts().keySet();
543
544                 return artifactsFromAAI.stream()
545                                 .filter(e -> componetDeploymentArtifactLables.contains(e.getArtifactLabel()) || componetInformationalArtifactLables.contains(e.getArtifactLabel()))
546                                 .filter(e -> checkAaiForUpdate(component, e))
547                                 .collect(Collectors.toList());
548         }
549
550         private boolean checkAaiForUpdate(Component component, ArtifactDefinition artifactDefinition) {
551                 ArtifactDefinition artifactDefinitionComp = component.getDeploymentArtifacts().get(artifactDefinition.getArtifactLabel());
552
553                 if (artifactDefinitionComp == null) {
554                         log.warn("Failed to get {} artifact", artifactDefinition.getArtifactLabel());
555                         return false;
556                 }
557
558                 // Old Artifacts before the generated flag introduction if contains "aai" ignore case prefix updated
559                 if (artifactDefinitionComp.getGenerated() == null) {
560                         if (artifactDefinitionComp.getArtifactLabel().toLowerCase().startsWith("aai")) {
561                                 return true;
562                         } else {
563                                 log.warn("The artifact {} flag is null but AAI prefix is abssent Not updated", artifactDefinition.getArtifactLabel());
564                         }
565                 } else {
566                         if (artifactDefinition.getGenerated()) {
567                                 return true;
568                         } else {
569                                 log.warn("Generated artifact {} was already uploaded manually", artifactDefinition.getArtifactLabel());
570                         }
571                 }
572                 return false;
573         }
574
575         private List<ArtifactDefinition> getAAIArtifatcsForDelete(List<ArtifactDefinition> artifactsFromAAI, Component component) {
576
577                 Set<String> aaiLabels = artifactsFromAAI.stream()
578                                 .map(ArtifactDefinition::getArtifactLabel)
579                                 .collect(Collectors.toSet());
580
581                 List<ArtifactDefinition> artifactsForDeleteDeployment = component.getDeploymentArtifacts().values().stream()
582                 // Filter Out Artifacts that are not contained in artifacts returned
583                 // from AAI API
584                                 .filter(e -> !aaiLabels.contains(e.getArtifactLabel()))
585                                 .collect(Collectors.toList());
586
587                 List<ArtifactDefinition> artifactsForDeleteInformational = component.getArtifacts().values().stream()
588                 // Filter Out Artifacts that are not contained in artifacts returned
589                 // from AAI API
590                                 .filter(e -> !aaiLabels.contains(e.getArtifactLabel()))
591                                 .collect(Collectors.toList());
592
593                 artifactsForDeleteDeployment.addAll(artifactsForDeleteInformational);
594
595                 return artifactsForDeleteDeployment.stream()
596                                 .filter(e -> (e.getGenerated() != null && e.getGenerated().equals(Boolean.TRUE)) || (e.getGenerated() == null && e.getArtifactLabel().toLowerCase().startsWith("aai")))
597                                 .collect(Collectors.toList());
598         }
599
600         private List<ArtifactDefinition> getAAIArtifatcsForCreate(List<ArtifactDefinition> artifactsFromAAI, Component component) {
601
602                 Set<String> componentDeploymentLabels = component.getDeploymentArtifacts().keySet();
603                 Set<String> componentInfoLabels = component.getArtifacts().keySet();
604
605                 // If the artifact label does not exist in the service -
606                 // store the artifact (generate uuid and version, "generated" flag is TRUE)
607                 return artifactsFromAAI.stream()
608                                 .filter(e -> !componentDeploymentLabels.contains(e.getArtifactLabel()) && !componentInfoLabels.contains(e.getArtifactLabel()))
609                                 .collect(Collectors.toList());
610         }
611
612         private Either<ActionStatus, ResponseFormat> handleAAIArtifactsInDataModelByOperationType(Component component, List<ArtifactDefinition> generatedArtifactsDefinitions, ArtifactOperationInfo operationType, User user, boolean shouldLock,
613                         boolean inTransaction) {
614
615                 String componentUniqueId = component.getUniqueId();
616                 ComponentTypeEnum componentType = component.getComponentType();
617
618                 for (ArtifactDefinition artDef : generatedArtifactsDefinitions) {
619                         String data = gson.toJson(artDef);
620                         String dataMD5 = GeneralUtility.calculateMD5ByString(data);
621                         String artifactUniqueId = null;
622
623                         if ((operationType.getArtifactOperationEnum() == ArtifactOperationEnum.Update) || (operationType.getArtifactOperationEnum() == ArtifactOperationEnum.Delete)) {
624                                 String artifactLabel = artDef.getArtifactLabel();
625                                 ArtifactDefinition artifactDefinition = component.getDeploymentArtifacts().get(artifactLabel);
626                                 if (artifactDefinition != null) {
627                                         artifactUniqueId = artifactDefinition.getUniqueId();
628                                 }
629                         }
630
631                         Either<Either<ArtifactDefinition, Operation>, ResponseFormat> validateAndHandleArtifact = artifactsBusinessLogic.validateAndHandleArtifact(componentUniqueId, componentType, operationType, artifactUniqueId, artDef, dataMD5, data, null,
632                                         null, null, user, component, shouldLock, inTransaction, false);
633
634                         if (validateAndHandleArtifact.isRight()) {
635                                 if (ArtifactOperationEnum.Create == operationType.getArtifactOperationEnum() || ArtifactOperationEnum.Update == operationType.getArtifactOperationEnum()) {
636                                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, componentType.getValue(), component.getName(), validateAndHandleArtifact.right().value().toString());
637
638                                         Either.right(responseFormat);
639                                 } else {
640                                         log.warn("Generated artifact {} could not be deleted", artDef.getArtifactLabel());
641                                 }
642                         }
643                 }
644
645                 return Either.left(ActionStatus.OK);
646         }
647
648         private List<ArtifactDefinition> convertToArtifactDefinitionFromArtifactGeneratedData(List<Artifact> generatorOutput) {
649                 List<ArtifactDefinition> artifactDefList = new LinkedList<>();
650
651                 for (Artifact artifact : generatorOutput) {
652                         ArtifactDefinition newEntry = new ArtifactDefinition();
653                         newEntry.setArtifactName(artifact.getName());
654                         newEntry.setArtifactType(artifact.getType());
655                         newEntry.setArtifactGroupType(ArtifactGroupTypeEnum.findType(artifact.getGroupType()));
656                         newEntry.setDescription(artifact.getDescription());
657
658                         // Normalizing the artifact label to match those stored in DB
659                         String normalizeArtifactLabel = ValidationUtils.normalizeArtifactLabel(artifact.getLabel());
660                         newEntry.setArtifactLabel(normalizeArtifactLabel);
661                         newEntry.setPayload(Base64.decodeBase64(artifact.getPayload()));
662                         newEntry.setArtifactChecksum(artifact.getChecksum());
663                         // Flag that set to true in case that the artifact is generated by AI&I generator
664                         newEntry.setGenerated(Boolean.TRUE);
665
666                         artifactDefList.add(newEntry);
667                 }
668
669                 return artifactDefList;
670         }
671
672         // List<ImmutablePair<Component, byte[] artifactBytes>>
673         // artifact stored by label
674         private List<Artifact> convertToGeneratorArtifactsInput(List<ImmutablePair<Component, byte[]>> inputs) {
675                 List<Artifact> listOfArtifactsInput = new LinkedList<>();
676                 for (ImmutablePair<Component, byte[]> triple : inputs) {
677                         Component component = triple.getLeft();
678
679                         Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
680                         ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
681
682                         String artifactName = artifactDefinition.getArtifactName();
683                         String artifactType = artifactDefinition.getArtifactType();
684                         String artifactGroupType = artifactDefinition.getArtifactGroupType().getType();
685                         String artifactDescription = artifactDefinition.getDescription();
686                         String artifactLabel = artifactDefinition.getArtifactLabel();
687                         byte[] right = triple.getRight();
688                         // The md5 calculated on the uncoded data
689                         String md5Hex = DigestUtils.md5Hex(right);
690                         byte[] payload = Base64.encodeBase64(right);
691                         String artifactVersion = artifactDefinition.getArtifactVersion();
692
693                         Artifact convertedArtifact = new Artifact(artifactType, artifactGroupType, md5Hex, payload);
694                         convertedArtifact.setName(artifactName);
695                         convertedArtifact.setDescription(artifactDescription);
696                         convertedArtifact.setLabel(artifactLabel);
697                         convertedArtifact.setVersion(artifactVersion);
698
699                         listOfArtifactsInput.add(convertedArtifact);
700                 }
701
702                 return listOfArtifactsInput;
703         }
704
705         private Either<byte[], ActionStatus> getEntryData(String cassandraId, Component childComponent) {
706                 byte[] content;
707                 if (cassandraId == null || cassandraId.isEmpty()) {
708                         Either<ToscaRepresentation, ToscaError> exportRes = toscaExportUtils.exportComponent(childComponent);
709                         if (exportRes.isRight()) {
710                                 log.debug("Failed to export tosca template for child component {} error {}", childComponent.getUniqueId(), exportRes.right().value());
711                                 return Either.right(componentsUtils.convertFromToscaError(exportRes.right().value()));
712                         }
713                         content = exportRes.left().value().getMainYaml().getBytes();
714                 } else {
715                         Either<byte[], ActionStatus> fromCassandra = getFromCassandra(cassandraId);
716                         if (fromCassandra.isRight()) {
717                                 return Either.right(fromCassandra.right().value());
718                         } else {
719                                 content = fromCassandra.left().value();
720                         }
721                 }
722                 return Either.left(content);
723         }
724         
725         private Either<byte[], ResponseFormat> getLatestSchemaFilesFromCassandra() {
726                 Either<List<SdcSchemaFilesData>, CassandraOperationStatus> specificSchemaFiles = sdcSchemaFilesCassandraDao.getSpecificSchemaFiles(versionFirstThreeOctates, CONFORMANCE_LEVEL);
727                 
728                 if(specificSchemaFiles.isRight()){                      
729                         log.debug("Failed to get the schema files SDC-Version: {} Conformance-Level {}", versionFirstThreeOctates, CONFORMANCE_LEVEL);
730                         StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(specificSchemaFiles.right().value());
731                         ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus);
732                         return Either.right(componentsUtils.getResponseFormat(convertedFromStorageResponse)); 
733                 }
734                 
735                  List<SdcSchemaFilesData> listOfSchemas = specificSchemaFiles.left().value();
736                 
737                 if(listOfSchemas.isEmpty()){
738                         log.debug("Failed to get the schema files SDC-Version: {} Conformance-Level {}", versionFirstThreeOctates, CONFORMANCE_LEVEL);
739                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_SCHEMA_FILES_NOT_FOUND, versionFirstThreeOctates, CONFORMANCE_LEVEL));
740                 }
741                 
742                 SdcSchemaFilesData schemaFile = listOfSchemas.iterator().next();
743                 
744                 return Either.left(schemaFile.getPayloadAsArray());
745         }
746         
747         private Either<byte[], ActionStatus> getFromCassandra(String cassandraId) {
748                 Either<ESArtifactData, CassandraOperationStatus> artifactResponse = artifactCassandraDao.getArtifact(cassandraId);
749
750                 if (artifactResponse.isRight()) {
751                         log.debug("In createCsar fetching of artifact from CS failed");
752                         log.debug("Failed to fetch from Cassandra by id {} error {} ", cassandraId, artifactResponse.right().value());
753
754                         StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactResponse.right().value());
755                         ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus);
756                         return Either.right(convertedFromStorageResponse);
757                 } else {
758                         ESArtifactData artifactData = artifactResponse.left().value();
759                         return Either.left(artifactData.getDataAsArray());
760
761                 }
762         }
763         
764         private String createCsarBlock0(String metaFileVersion, String toscaConformanceLevel) {
765                 final String BLOCK_0_TEMPLATE = 
766                                 "SDC-TOSCA-Meta-File-Version: %s\nSDC-TOSCA-Definitions-Version: %s\n";
767                 String readyBlock = String.format(BLOCK_0_TEMPLATE, metaFileVersion, toscaConformanceLevel);
768                 return readyBlock;
769         }
770         
771         private String createToscaBlock0(String metaFileVersion, String csarVersion, String createdBy, String entryDef) {
772                 final String block0template = "TOSCA-Meta-File-Version: %s\nCSAR-Version: %s\nCreated-By: %s\nEntry-Definitions: Definitions/%s\n\nName: csar.meta\nContent-Type: text/plain\n";
773                 return String.format(block0template, metaFileVersion, csarVersion, createdBy, entryDef);
774         }
775
776         private Either<List<Artifact>, String> artifactGenerator(List<Artifact> artifactList, ArtifactType type, Component component) {
777
778                 ArtifactGenerationServiceImpl artifactGenerationServiceImpl = new ArtifactGenerationServiceImpl();
779                 ArtifactTypes artifactTypes = new ArtifactTypes();
780                 List<ArtifactType> artifactTypesList = new LinkedList<>();
781                 ArtifactType otherType;
782
783                 if (type == null) {
784                         otherType = ArtifactType.OTHER;
785                 } else {
786                         otherType = type;
787                 }
788
789                 artifactTypesList.add(otherType);
790                 artifactTypes.setArtifactTypes(artifactTypesList);
791
792                 String configJson = gson.toJson(artifactTypes);
793                 Map<String, String> additionalParams = new HashMap<>();
794                 String version;
795
796                 if (UUID_NORMATIVE_NEW_VERSION.matcher(component.getVersion()).matches() ) {
797                         version = component.getVersion();
798                 } else {
799                         String[] versionParts = component.getVersion().split(LifecycleOperation.VERSION_DELIMETER_REGEXP);
800                         Integer majorVersion = Integer.parseInt(versionParts[0]);
801
802                         version = (majorVersion + 1) + LifecycleOperation.VERSION_DELIMETER + "0";
803                 }
804
805                 additionalParams.put(AdditionalParams.ServiceVersion.getName(), version);
806                 GenerationData generatedArtifacts = artifactGenerationServiceImpl.generateArtifact(artifactList, configJson, additionalParams);
807
808                 Map<String, List<String>> errorData = generatedArtifacts.getErrorData();
809
810                 if (!errorData.isEmpty()) {
811                         Set<String> keySet = errorData.keySet();
812                         StringBuilder error = new StringBuilder();
813
814                         for (String key : keySet) {
815                                 List<String> errorList = errorData.get(key);
816                                 log.debug("The Artifact Generator Failed - {} with following: {}", key, errorList);
817                                 error.append(key + errorList);
818                         }
819
820                         return Either.right(error.toString());
821                 }
822
823                 return Either.left(generatedArtifacts.getResultData());
824         }
825
826         /**
827          * Extracts artifacts of VFCs from CSAR
828          * 
829          * @param csar
830          * @return Map of <String, List<ArtifactDefinition>> the contains Lists of artifacts according vfcToscaNamespace
831          */
832         public static Map<String, List<ArtifactDefinition>> extractVfcsArtifactsFromCsar(Map<String, byte[]> csar) {
833
834                 Map<String, List<ArtifactDefinition>> artifacts = new HashMap<>();
835                 if (csar != null) {
836                         log.debug("************* Going to extract VFCs artifacts from Csar. ");
837                         Map<String, Set<List<String>>> collectedWarningMessages = new HashMap<>();
838                         csar.entrySet().stream()
839                                         // filter CSAR entry by node type artifact path
840                                         .filter(e -> Pattern.compile(VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches())
841                                         // extract ArtifactDefinition from CSAR entry for each entry with matching artifact path
842                                         .forEach(e -> addExtractedVfcArtifact(extractVfcArtifact(e, collectedWarningMessages), artifacts));
843                         // add counter suffix to artifact labels
844                         handleWarningMessages(collectedWarningMessages);
845
846                 }
847                 return artifacts;
848         }
849
850         /**
851          * Print warnings to log
852          * 
853          * @param collectedWarningMessages
854          */
855         public static void handleWarningMessages(Map<String, Set<List<String>>> collectedWarningMessages) {
856                 collectedWarningMessages.entrySet().stream()
857                                 // for each vfc
858                                 .forEach(e -> e.getValue().stream()
859                                                 // add each warning message to log
860                                                 .forEach(args -> log.warn(e.getKey(), args.toArray())));
861
862         }
863
864         private static void addExtractedVfcArtifact(ImmutablePair<String, ArtifactDefinition> extractedVfcArtifact, Map<String, List<ArtifactDefinition>> artifacts) {
865                 if (extractedVfcArtifact != null) {
866                         List<ArtifactDefinition> currArtifactsList;
867                         String vfcToscaNamespace = extractedVfcArtifact.getKey();
868                         if (artifacts.containsKey(vfcToscaNamespace)) {
869                                 currArtifactsList = artifacts.get(vfcToscaNamespace);
870                         } else {
871                                 currArtifactsList = new ArrayList<>();
872                                 artifacts.put(vfcToscaNamespace, currArtifactsList);
873                         }
874                         currArtifactsList.add(extractedVfcArtifact.getValue());
875                 }
876         }
877
878         private static ImmutablePair<String, ArtifactDefinition> extractVfcArtifact(Entry<String, byte[]> entry, Map<String, Set<List<String>>> collectedWarningMessages) {
879                 ArtifactDefinition artifact;
880                 String[] parsedCsarArtifactPath = entry.getKey().split("/");
881                 Either<ArtifactGroupTypeEnum, Boolean> eitherArtifactGroupType = detectArtifactGroupType(parsedCsarArtifactPath[2].toUpperCase(), collectedWarningMessages);
882                 if (eitherArtifactGroupType.isLeft()) {
883                         artifact = buildArtifactDefinitionFromCsarArtifactPath(entry, collectedWarningMessages, parsedCsarArtifactPath, eitherArtifactGroupType.left().value());
884                 } else {
885                         return null;
886                 }
887                 return new ImmutablePair<>(parsedCsarArtifactPath[1], artifact);
888         }
889
890         private static Either<ArtifactGroupTypeEnum, Boolean> detectArtifactGroupType(String groupType, Map<String, Set<List<String>>> collectedWarningMessages) {
891                 Either<ArtifactGroupTypeEnum, Boolean> result;
892                 try {
893                         ArtifactGroupTypeEnum artifactGroupType = ArtifactGroupTypeEnum.findType(groupType.toUpperCase());
894                         if (artifactGroupType == null || (artifactGroupType != ArtifactGroupTypeEnum.INFORMATIONAL && artifactGroupType != ArtifactGroupTypeEnum.DEPLOYMENT)) {
895                                 String warningMessage = "Warning - unrecognized artifact group type {} was received.";
896                                 List<String> messageArguments = new ArrayList<>();
897                                 messageArguments.add(groupType);
898                                 if (!collectedWarningMessages.containsKey(warningMessage)) {
899                                         Set<List<String>> messageArgumentLists = new HashSet<>();
900                                         messageArgumentLists.add(messageArguments);
901                                         collectedWarningMessages.put(warningMessage, messageArgumentLists);
902                                 } else {
903                                         collectedWarningMessages.get(warningMessage).add(messageArguments);
904                                 }
905
906                                 result = Either.right(false);
907                         } else {
908
909                                 result = Either.left(artifactGroupType);
910                         }
911                 } catch (Exception e) {
912                         log.debug("detectArtifactGroupType failed with exception", e);
913                         result = Either.right(false);
914                 }
915                 return result;
916         }
917
918         private static ArtifactDefinition buildArtifactDefinitionFromCsarArtifactPath(Entry<String, byte[]> entry, Map<String, Set<List<String>>> collectedWarningMessages, String[] parsedCsarArtifactPath, ArtifactGroupTypeEnum artifactGroupType) {
919                 ArtifactDefinition artifact;
920                 artifact = new ArtifactDefinition();
921                 artifact.setArtifactGroupType(artifactGroupType);
922                 artifact.setArtifactType(detectArtifactTypeVFC(artifactGroupType, parsedCsarArtifactPath[3], parsedCsarArtifactPath[1], collectedWarningMessages));
923                 artifact.setArtifactName(ValidationUtils.normalizeFileName(parsedCsarArtifactPath[parsedCsarArtifactPath.length - 1]));
924                 artifact.setPayloadData(Base64.encodeBase64String(entry.getValue()));
925                 artifact.setArtifactDisplayName(artifact.getArtifactName().lastIndexOf('.') > 0 ? artifact.getArtifactName().substring(0, artifact.getArtifactName().lastIndexOf('.')) : artifact.getArtifactName());
926                 artifact.setArtifactLabel(ValidationUtils.normalizeArtifactLabel(artifact.getArtifactName()));
927                 artifact.setDescription(ARTIFACT_CREATED_FROM_CSAR);
928                 artifact.setArtifactChecksum(GeneralUtility.calculateMD5ByByteArray(entry.getValue()));
929                 return artifact;
930         }
931
932         public static final class NonMetaArtifactInfo {
933                 private final String path;
934                 private final String artifactName;
935                 private final String displayName;
936                 private final String artifactLabel;
937                 private final ArtifactTypeEnum artifactType;
938                 private final ArtifactGroupTypeEnum artifactGroupType;
939                 private String payloadData;
940                 private String artifactChecksum;
941                 private String artifactUniqueId;
942
943                 public NonMetaArtifactInfo(String artifactName, String path, ArtifactTypeEnum artifactType, ArtifactGroupTypeEnum artifactGroupType, byte[] payloadData, String artifactUniqueId) {
944                         super();
945                         this.path = path;
946                         this.artifactName = ValidationUtils.normalizeFileName(artifactName);
947                         this.artifactType = artifactType;
948                         this.artifactGroupType = artifactGroupType;
949                         final int pointIndex = artifactName.lastIndexOf('.');
950                         if (pointIndex > 0) {
951                                 displayName = artifactName.substring(0, pointIndex);
952                         } else {
953                                 displayName = artifactName;
954                         }
955                         this.artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactName);
956                         if (payloadData != null) {
957                                 this.payloadData = Base64.encodeBase64String(payloadData);
958                                 this.artifactChecksum = GeneralUtility.calculateMD5ByByteArray(payloadData);
959                         }
960                         this.artifactUniqueId = artifactUniqueId;
961                 }
962
963                 public String getPath() {
964                         return path;
965                 }
966
967                 public String getArtifactName() {
968                         return artifactName;
969                 }
970
971                 public ArtifactTypeEnum getArtifactType() {
972                         return artifactType;
973                 }
974
975                 public String getDisplayName() {
976                         return displayName;
977                 }
978
979                 public ArtifactGroupTypeEnum getArtifactGroupType() {
980                         return artifactGroupType;
981                 }
982
983                 public String getArtifactLabel() {
984                         return artifactLabel;
985                 }
986
987                 public String getPayloadData() {
988                         return payloadData;
989                 }
990
991                 public String getArtifactChecksum() {
992                         return artifactChecksum;
993                 }
994
995                 public String getArtifactUniqueId() {
996                         return artifactUniqueId;
997                 }
998
999                 public void setArtifactUniqueId(String artifactUniqueId) {
1000                         this.artifactUniqueId = artifactUniqueId;
1001                 }
1002
1003         }
1004
1005         /**
1006          * This method checks the artifact GroupType & Artifact Type. <br>
1007          * if there is any problem warning messages are added to collectedWarningMessages
1008          * 
1009          * @param artifactPath
1010          * @param collectedWarningMessages
1011          * @return
1012          */
1013         public static Either<NonMetaArtifactInfo, Boolean> validateNonMetaArtifact(String artifactPath, byte[] payloadData, Map<String, Set<List<String>>> collectedWarningMessages) {
1014                 Either<NonMetaArtifactInfo, Boolean> ret;
1015                 try {
1016                         String[] parsedArtifactPath = artifactPath.split("/");
1017                         // Validate Artifact Group Type
1018                         Either<ArtifactGroupTypeEnum, Boolean> eitherGroupType = detectArtifactGroupType(parsedArtifactPath[1], collectedWarningMessages);
1019                         if (eitherGroupType.isLeft()) {
1020                                 final ArtifactGroupTypeEnum groupTypeEnum = eitherGroupType.left().value();
1021
1022                                 // Validate Artifact Type
1023                                 String artifactType = parsedArtifactPath[2];
1024                                 artifactType = detectArtifactTypeVF(groupTypeEnum, artifactType, collectedWarningMessages);
1025
1026                                 String artifactFileNameType = parsedArtifactPath[3];
1027                                 ret = Either.left(new NonMetaArtifactInfo(artifactFileNameType, artifactPath, ArtifactTypeEnum.findType(artifactType), groupTypeEnum, payloadData, null));
1028
1029                         } else {
1030                                 ret = Either.right(eitherGroupType.right().value());
1031                         }
1032                 } catch (Exception e) {
1033                         log.debug("detectArtifactGroupType failed with exception", e);
1034                         ret = Either.right(false);
1035                 }
1036                 return ret;
1037
1038         }
1039
1040         private static String detectArtifactTypeVFC(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName, String parentVfName, Map<String, Set<List<String>>> collectedWarningMessages) {
1041                 String warningMessage = "Warning - artifact type {} that was provided for VFC {} is not recognized.";
1042                 return detectArtifactType(artifactGroupType, receivedTypeName, warningMessage, collectedWarningMessages, parentVfName);
1043         }
1044
1045         private static String detectArtifactTypeVF(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName, Map<String, Set<List<String>>> collectedWarningMessages) {
1046                 String warningMessage = "Warning - artifact type {} that was provided for VF is not recognized.";
1047                 return detectArtifactType(artifactGroupType, receivedTypeName, warningMessage, collectedWarningMessages);
1048         }
1049
1050         private static String detectArtifactType(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName, String warningMessage, Map<String, Set<List<String>>> collectedWarningMessages, String... arguments) {
1051
1052                 ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(receivedTypeName);
1053                 Map<String, ArtifactTypeConfig> resourceValidTypeArtifacts = null;
1054                 
1055                 if(artifactGroupType != null){
1056                         switch (artifactGroupType) {
1057                         case INFORMATIONAL:
1058                                 resourceValidTypeArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1059                                 .getResourceInformationalArtifacts();
1060                                 break;
1061                         case DEPLOYMENT:
1062                                 resourceValidTypeArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1063                                 .getResourceDeploymentArtifacts();
1064                                 break;
1065                         default:
1066                                 break;
1067                         }
1068                 }
1069                 
1070                 Set<String> validArtifactTypes = null;
1071                 if(resourceValidTypeArtifacts != null){
1072                         validArtifactTypes = resourceValidTypeArtifacts.keySet();                       
1073                 }
1074                 
1075                 if (validArtifactTypes == null || artifactType == null || !validArtifactTypes.contains(artifactType.getType())) {
1076                         List<String> messageArguments = new ArrayList<>();
1077                         messageArguments.add(receivedTypeName);
1078                         messageArguments.addAll(Arrays.asList(arguments));
1079                         if (!collectedWarningMessages.containsKey(warningMessage)) {
1080                                 Set<List<String>> messageArgumentLists = new HashSet<>();
1081                                 messageArgumentLists.add(messageArguments);
1082                                 collectedWarningMessages.put(warningMessage, messageArgumentLists);
1083                         } else {
1084                                 collectedWarningMessages.get(warningMessage).add(messageArguments);
1085                         }
1086                 }
1087
1088                 return artifactType == null ? ArtifactTypeEnum.OTHER.getType() : artifactType.getType();
1089         }
1090         
1091         private Either<ZipOutputStream, ResponseFormat> writeAllFilesToScar(Component mainComponent, CsarDefinition csarDefinition, ZipOutputStream zipstream, boolean isInCertificationRequest) throws IOException{
1092                 ComponentArtifacts componentArtifacts = csarDefinition.getComponentArtifacts(); 
1093                 
1094                 Either<ZipOutputStream, ResponseFormat> writeComponentArtifactsToSpecifiedtPath = writeComponentArtifactsToSpecifiedtPath(mainComponent, componentArtifacts, zipstream, ARTIFACTS_PATH, isInCertificationRequest);
1095                 
1096                 if(writeComponentArtifactsToSpecifiedtPath.isRight()){
1097                         return Either.right(writeComponentArtifactsToSpecifiedtPath.right().value());
1098                 }
1099                 
1100                 ComponentTypeArtifacts mainTypeAndCIArtifacts = componentArtifacts.getMainTypeAndCIArtifacts();
1101                 writeComponentArtifactsToSpecifiedtPath = writeArtifactsInfoToSpecifiedtPath(mainComponent, mainTypeAndCIArtifacts.getComponentArtifacts(), zipstream, ARTIFACTS_PATH, isInCertificationRequest);
1102                 
1103                 if(writeComponentArtifactsToSpecifiedtPath.isRight()){
1104                         return Either.right(writeComponentArtifactsToSpecifiedtPath.right().value());
1105                 }
1106                 
1107                 Map<String, ArtifactsInfo> componentInstancesArtifacts = mainTypeAndCIArtifacts.getComponentInstancesArtifacts();
1108                 Set<String> keySet = componentInstancesArtifacts.keySet();
1109                 
1110                 String currentPath = ARTIFACTS_PATH + RESOURCES_PATH;
1111                 for (String keyAssetName : keySet) {
1112                         ArtifactsInfo artifactsInfo = componentInstancesArtifacts.get(keyAssetName);
1113                         String pathWithAssetName = currentPath + keyAssetName + "/";
1114                         writeComponentArtifactsToSpecifiedtPath = writeArtifactsInfoToSpecifiedtPath(mainComponent, artifactsInfo, zipstream, pathWithAssetName, isInCertificationRequest);
1115                         
1116                         if(writeComponentArtifactsToSpecifiedtPath.isRight()){
1117                                 return Either.right(writeComponentArtifactsToSpecifiedtPath.right().value());
1118                         }
1119                 }
1120                 
1121                 return Either.left(zipstream);
1122         }
1123         
1124         private Either<ZipOutputStream, ResponseFormat> writeComponentArtifactsToSpecifiedtPath(Component mainComponent, ComponentArtifacts componentArtifacts, ZipOutputStream zipstream,
1125                         String currentPath, boolean isInCertificationRequest) throws IOException {
1126                 Map<String, ComponentTypeArtifacts> componentTypeArtifacts = componentArtifacts.getComponentTypeArtifacts();
1127                 //Keys are defined: 
1128                 //<Inner Asset TOSCA name (e.g. VFC name)> folder name: <Inner Asset TOSCA name (e.g. VFC name)>_v<version>. 
1129                 //E.g. "org.openecomp.resource.vf.vipr_atm_v1.0"
1130                 Set<String> componentTypeArtifactsKeys = componentTypeArtifacts.keySet();
1131                 for (String keyAssetName : componentTypeArtifactsKeys) {
1132                         ComponentTypeArtifacts componentInstanceArtifacts = componentTypeArtifacts.get(keyAssetName);
1133                         ArtifactsInfo componentArtifacts2 = componentInstanceArtifacts.getComponentArtifacts();
1134                         String pathWithAssetName = currentPath + keyAssetName + "/";
1135                         Either<ZipOutputStream, ResponseFormat> writeArtifactsInfoToSpecifiedtPath = writeArtifactsInfoToSpecifiedtPath(mainComponent, componentArtifacts2, zipstream, pathWithAssetName, isInCertificationRequest);
1136                         
1137                         if(writeArtifactsInfoToSpecifiedtPath.isRight()){
1138                                 return writeArtifactsInfoToSpecifiedtPath;
1139                         }
1140                 }
1141                 
1142                 return Either.left(zipstream);
1143         }
1144         
1145         private Either<ZipOutputStream, ResponseFormat> writeArtifactsInfoToSpecifiedtPath(Component mainComponent, ArtifactsInfo currArtifactsInfo, ZipOutputStream zip, String path, boolean isInCertificationRequest) throws IOException {
1146                 Map<ArtifactGroupTypeEnum, Map<ArtifactTypeEnum, List<ArtifactDefinition>>> artifactsInfo = currArtifactsInfo
1147                                 .getArtifactsInfo();
1148                 Set<ArtifactGroupTypeEnum> groupTypeEnumKeySet = artifactsInfo.keySet();
1149
1150                 for (ArtifactGroupTypeEnum artifactGroupTypeEnum : groupTypeEnumKeySet) {
1151                         String groupTypeFolder = path + WordUtils.capitalizeFully(artifactGroupTypeEnum.getType()) + "/";
1152
1153                         Map<ArtifactTypeEnum, List<ArtifactDefinition>> artifactTypesMap = artifactsInfo.get(artifactGroupTypeEnum);
1154                         Set<ArtifactTypeEnum> artifactTypeEnumKeySet = artifactTypesMap.keySet();
1155
1156                         for (ArtifactTypeEnum artifactTypeEnum : artifactTypeEnumKeySet) {
1157                                 List<ArtifactDefinition> artifactDefinitionList = artifactTypesMap.get(artifactTypeEnum);
1158                                 String artifactTypeFolder = groupTypeFolder + artifactTypeEnum.toString() + "/";
1159
1160                                 Either<ZipOutputStream, ResponseFormat> writeArtifactDefinition = writeArtifactDefinition(mainComponent, zip, artifactDefinitionList, artifactTypeFolder, isInCertificationRequest);
1161                                 
1162                                 if(writeArtifactDefinition.isRight()){
1163                                         return writeArtifactDefinition;
1164                                 }
1165                         }
1166                 }
1167                 
1168                 return Either.left(zip);
1169         }
1170
1171         private Either<ZipOutputStream, ResponseFormat> writeArtifactDefinition(Component mainComponent, ZipOutputStream zip, List<ArtifactDefinition> artifactDefinitionList,
1172                         String artifactPathAndFolder, boolean isInCertificationRequest) throws IOException {
1173                 
1174                 ComponentTypeEnum componentType = mainComponent.getComponentType();
1175                 String heatEnvType = ArtifactTypeEnum.HEAT_ENV.getType();
1176                 
1177                 for (ArtifactDefinition artifactDefinition : artifactDefinitionList) {
1178                         if (!isInCertificationRequest && componentType == ComponentTypeEnum.SERVICE
1179                                         && artifactDefinition.getArtifactType().equals(heatEnvType)){
1180                                 continue;
1181                         }
1182                         
1183                         String esId = artifactDefinition.getEsId();
1184                         byte[] payloadData = artifactDefinition.getPayloadData();
1185                         String artifactFileName = artifactDefinition.getArtifactName();
1186                         
1187                         if (payloadData == null) {
1188                                 Either<byte[], ActionStatus> fromCassandra = getFromCassandra(esId);
1189
1190                                 if (fromCassandra.isRight()) {
1191                                         log.debug("Failed to get {} payload from DB reason: {}", artifactFileName, fromCassandra.right().value());
1192                                         continue;
1193                                 }
1194                                 payloadData = fromCassandra.left().value();
1195                         }
1196                         zip.putNextEntry(new ZipEntry(artifactPathAndFolder + artifactFileName));
1197                         zip.write(payloadData);
1198                 }
1199                 
1200                 return Either.left(zip);
1201         }
1202         
1203         /************************************ Artifacts Structure ******************************************************************/
1204         /**
1205          * The artifacts Definition saved by their structure
1206          */
1207         private class ArtifactsInfo {
1208                 //Key is the type of artifacts(Informational/Deployment)
1209                 //Value is a map between an artifact type and a list of all artifacts of this type
1210                 private Map<ArtifactGroupTypeEnum, Map<ArtifactTypeEnum, List<ArtifactDefinition>>> artifactsInfoField;
1211                 
1212                 public ArtifactsInfo() {
1213                         this.artifactsInfoField = new EnumMap<>(ArtifactGroupTypeEnum.class);
1214                 }
1215                 
1216                 public Map<ArtifactGroupTypeEnum, Map<ArtifactTypeEnum, List<ArtifactDefinition>>> getArtifactsInfo() {
1217                         return artifactsInfoField;
1218                 }
1219                 
1220                 public List<ArtifactDefinition> getFlatArtifactsListByType(ArtifactTypeEnum artifactType){
1221                         List<ArtifactDefinition> artifacts = new ArrayList<>();
1222                         for (List<ArtifactDefinition> artifactsByType:artifactsInfoField.get(artifactType).values()){
1223                                 artifacts.addAll(artifactsByType);
1224                         }
1225                         return artifacts;
1226                 }
1227                 
1228                 public void addArtifactsToGroup(ArtifactGroupTypeEnum artifactGroup,Map<ArtifactTypeEnum, List<ArtifactDefinition>> artifactsDefinition){
1229                         artifactsInfoField.put(artifactGroup, artifactsDefinition);
1230                 }
1231
1232                 public boolean isEmpty() {
1233                         return artifactsInfoField.isEmpty(); 
1234                 }
1235                 
1236         }
1237         
1238         /**
1239          * The artifacts of the component and of all its composed instances
1240          *
1241          */
1242         private class ComponentTypeArtifacts {
1243                 private ArtifactsInfo componentArtifacts;       //component artifacts (describes the Informational Deployment folders)
1244                 private Map<String, ArtifactsInfo> componentInstancesArtifacts;         //artifacts of the composed instances mapped by the resourceInstance normalized name (describes the Resources folder) 
1245                 
1246                 public ComponentTypeArtifacts() {
1247                         componentArtifacts = new ArtifactsInfo();
1248                         componentInstancesArtifacts = new HashMap<>();
1249                 }
1250                 
1251                 public ArtifactsInfo getComponentArtifacts() {
1252                         return componentArtifacts;
1253                 }
1254                 public void setComponentArtifacts(ArtifactsInfo artifactsInfo) {
1255                         this.componentArtifacts = artifactsInfo;
1256                 }
1257                 public Map<String, ArtifactsInfo> getComponentInstancesArtifacts() {
1258                         return componentInstancesArtifacts;
1259                 }
1260                 public void setComponentInstancesArtifacts(Map<String, ArtifactsInfo> componentInstancesArtifacts) {
1261                         this.componentInstancesArtifacts = componentInstancesArtifacts;
1262                 }
1263
1264                 public void addComponentInstancesArtifacts(String normalizedName, ArtifactsInfo artifactsInfo) {
1265                         componentInstancesArtifacts.put(normalizedName, artifactsInfo);                 
1266                 }
1267                 
1268         }
1269         
1270         private class ComponentArtifacts {
1271                 //artifacts of the component and CI's artifacts contained in it's composition (represents Informational, Deployment & Resource folders of main component)
1272                 private ComponentTypeArtifacts mainTypeAndCIArtifacts;
1273                 //artifacts of all component types mapped by their tosca name
1274                 private Map<String, ComponentTypeArtifacts> componentTypeArtifacts;     
1275                 
1276                 public ComponentArtifacts(){
1277                         mainTypeAndCIArtifacts = new ComponentTypeArtifacts();
1278                         componentTypeArtifacts = new HashMap<>();
1279                 }
1280
1281                 public ComponentTypeArtifacts getMainTypeAndCIArtifacts() {
1282                         return mainTypeAndCIArtifacts;
1283                 }
1284
1285                 public void setMainTypeAndCIArtifacts(ComponentTypeArtifacts componentInstanceArtifacts) {
1286                         this.mainTypeAndCIArtifacts = componentInstanceArtifacts;
1287                 }
1288
1289                 public Map<String, ComponentTypeArtifacts> getComponentTypeArtifacts() {
1290                         return componentTypeArtifacts;
1291                 }
1292
1293                 public void setComponentTypeArtifacts(Map<String, ComponentTypeArtifacts> componentTypeArtifacts) {
1294                         this.componentTypeArtifacts = componentTypeArtifacts;
1295                 }
1296         }
1297         
1298         private class CsarDefinition {
1299                 private ComponentArtifacts componentArtifacts;
1300                 
1301                 // add list of tosca artifacts and meta describes CSAR zip root
1302                 
1303                 public CsarDefinition(ComponentArtifacts componentArtifacts) {
1304                         this.componentArtifacts = componentArtifacts;
1305                 }
1306         
1307                 public ComponentArtifacts getComponentArtifacts() {
1308                         return componentArtifacts;
1309                 }       
1310         }
1311
1312         /************************************ Artifacts Structure END******************************************************************/
1313         
1314         private Either<CsarDefinition,ResponseFormat> collectComponentCsarDefinition(Component component){
1315                 ComponentArtifacts componentArtifacts = new ComponentArtifacts();
1316                 Component updatedComponent = component;
1317                 
1318                 //get service to receive the AII artifacts uploaded to the service
1319                 if (updatedComponent.getComponentType() == ComponentTypeEnum.SERVICE) {
1320                         Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(updatedComponent.getUniqueId());
1321                         
1322                         if(getServiceResponse.isRight()){
1323                                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getServiceResponse.right().value());
1324                                 return Either.right(componentsUtils.getResponseFormat(actionStatus));
1325                         }
1326                         
1327                         updatedComponent = getServiceResponse.left().value();
1328                 }
1329                 
1330                 //find the artifacts of the main component, it would have its composed instances artifacts in a separate folder 
1331                 ComponentTypeArtifacts componentInstanceArtifacts = new ComponentTypeArtifacts();
1332                 ArtifactsInfo artifactsInfo = collectComponentArtifacts(updatedComponent);
1333                 componentInstanceArtifacts.setComponentArtifacts(artifactsInfo);
1334                 componentArtifacts.setMainTypeAndCIArtifacts(componentInstanceArtifacts);
1335
1336                 Map<String,ComponentTypeArtifacts> resourceTypeArtifacts = componentArtifacts.getComponentTypeArtifacts();      //artifacts mapped by the component type(tosca name+version)
1337                 //get the component instances
1338                 List<ComponentInstance> componentInstances = updatedComponent.getComponentInstances();
1339                 if (componentInstances!=null){
1340                         for (ComponentInstance componentInstance:componentInstances){                                           
1341                                 //call recursive to find artifacts for all the path
1342                                 Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts = collectComponentInstanceArtifacts(
1343                                                 updatedComponent, componentInstance, resourceTypeArtifacts, componentInstanceArtifacts);
1344                                 if (collectComponentInstanceArtifacts.isRight()){
1345                                         return Either.right(collectComponentInstanceArtifacts.right().value());
1346                                 }
1347                         }                       
1348                 }
1349                 
1350                 if(log.isDebugEnabled()){
1351                         printResult(componentArtifacts,updatedComponent.getName());                     
1352                 }
1353                 
1354                 return Either.left(new CsarDefinition(componentArtifacts));
1355         }
1356
1357         private void printResult(ComponentArtifacts componentArtifacts, String name) {
1358                 StringBuilder result = new StringBuilder();
1359                 result.append("Artifacts of main component " + name + "\n");
1360                 ComponentTypeArtifacts componentInstanceArtifacts = componentArtifacts.getMainTypeAndCIArtifacts();
1361                 printArtifacts(componentInstanceArtifacts);
1362                 result.append("Type Artifacts\n");
1363                 for (Map.Entry<String, ComponentTypeArtifacts> typeArtifacts:componentArtifacts.getComponentTypeArtifacts().entrySet()){
1364                         result.append("Folder " + typeArtifacts.getKey() + "\n");
1365                         result.append(printArtifacts(typeArtifacts.getValue()));
1366                 }
1367                 
1368                 if(log.isDebugEnabled()){
1369                         log.debug(result.toString());
1370                 }
1371         }
1372
1373         private String printArtifacts(ComponentTypeArtifacts componentInstanceArtifacts) {
1374                 StringBuilder result = new StringBuilder();
1375                 ArtifactsInfo artifactsInfo = componentInstanceArtifacts.getComponentArtifacts();
1376                 Map<ArtifactGroupTypeEnum, Map<ArtifactTypeEnum, List<ArtifactDefinition>>> componetArtifacts = artifactsInfo.getArtifactsInfo();
1377                 printArtifacts(componetArtifacts);
1378                 result = result.append("Resources\n");
1379                 for (Map.Entry<String, ArtifactsInfo> resourceInstance:componentInstanceArtifacts.getComponentInstancesArtifacts().entrySet()){
1380                         result.append("Folder" + resourceInstance.getKey() + "\n");
1381                         result.append(printArtifacts(resourceInstance.getValue().getArtifactsInfo()));
1382                 }
1383                 
1384                 return result.toString();
1385         }
1386
1387         private String  printArtifacts(Map<ArtifactGroupTypeEnum, Map<ArtifactTypeEnum, List<ArtifactDefinition>>> componetArtifacts) {
1388                 StringBuilder result = new StringBuilder();
1389                 for (Map.Entry<ArtifactGroupTypeEnum, Map<ArtifactTypeEnum, List<ArtifactDefinition>>> artifactGroup:componetArtifacts.entrySet()){
1390                         result.append(" " + artifactGroup.getKey().getType());
1391                         for (Map.Entry<ArtifactTypeEnum, List<ArtifactDefinition>> groupArtifacts:artifactGroup.getValue().entrySet()){
1392                                 result.append("         " + groupArtifacts.getKey().getType());
1393                                 for (ArtifactDefinition artifact:groupArtifacts.getValue()){
1394                                         result.append("                 " + artifact.getArtifactDisplayName());
1395                                 }
1396                         }
1397                 }
1398                 
1399                 return result.toString();
1400         }
1401
1402         private ComponentTypeArtifacts collectComponentTypeArtifacts(Map<String, ComponentTypeArtifacts> resourcesArtifacts, ComponentInstance componentInstance,
1403                         Resource fetchedComponent) {
1404                 String toscaComponentName = componentInstance.getToscaComponentName() + "_v" + componentInstance.getComponentVersion();
1405                 
1406                 ComponentTypeArtifacts componentArtifactsInfo = resourcesArtifacts.get(toscaComponentName);
1407                 //if there are no artifacts for this component type we need to fetch and build them
1408                 if (componentArtifactsInfo==null){
1409                         ArtifactsInfo componentArtifacts = collectComponentArtifacts(fetchedComponent);
1410                         componentArtifactsInfo = new ComponentTypeArtifacts();
1411                         if (!componentArtifacts.isEmpty()){
1412                                 componentArtifactsInfo.setComponentArtifacts(componentArtifacts);                               
1413                                 resourcesArtifacts.put(toscaComponentName, componentArtifactsInfo);
1414                         }
1415                 }       
1416                 return componentArtifactsInfo;
1417         }
1418
1419         private Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts(Component parentComponent,ComponentInstance componentInstance,
1420                         Map<String, ComponentTypeArtifacts> resourcesTypeArtifacts,ComponentTypeArtifacts instanceArtifactsLocation) {
1421                 //1. get the component instance component
1422                 String componentUid = componentInstance.getComponentUid();
1423                 Either<Resource, StorageOperationStatus> resource = toscaOperationFacade.getToscaElement(componentUid);
1424                 if (resource.isRight()) {
1425                         log.error("Failed to fetch resource with id {} for instance {}",componentUid, parentComponent.getUUID());
1426                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.ASSET_NOT_FOUND_DURING_CSAR_CREATION, 
1427                                         parentComponent.getComponentType().getValue(), parentComponent.getUUID(), 
1428                                         componentInstance.getOriginType().getComponentType().getValue(), componentUid));                        
1429                 }
1430                 Resource fetchedComponent = resource.left().value();
1431                         
1432                 //2. fill the artifacts for the current component parent type
1433                 ComponentTypeArtifacts componentParentArtifacts = collectComponentTypeArtifacts(resourcesTypeArtifacts, componentInstance, fetchedComponent);
1434                 
1435                 //3. find the artifacts specific to the instance
1436                 Map<ArtifactTypeEnum, List<ArtifactDefinition>> componentInstanceSpecificInformationalArtifacts = 
1437                                 getComponentInstanceSpecificArtifacts(componentInstance.getArtifacts(), 
1438                                                 componentParentArtifacts.getComponentArtifacts().getArtifactsInfo(), ArtifactGroupTypeEnum.INFORMATIONAL);
1439                 Map<ArtifactTypeEnum, List<ArtifactDefinition>> componentInstanceSpecificDeploymentArtifacts = 
1440                                 getComponentInstanceSpecificArtifacts(componentInstance.getDeploymentArtifacts(), 
1441                                                 componentParentArtifacts.getComponentArtifacts().getArtifactsInfo(), ArtifactGroupTypeEnum.DEPLOYMENT);
1442                 
1443                 //4. add the instances artifacts to the component type
1444                 ArtifactsInfo artifactsInfo = new ArtifactsInfo();
1445                 if (!componentInstanceSpecificInformationalArtifacts.isEmpty()){
1446                         artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.INFORMATIONAL, componentInstanceSpecificInformationalArtifacts);                        
1447                 }
1448                 if (!componentInstanceSpecificDeploymentArtifacts.isEmpty()){
1449                         artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, componentInstanceSpecificDeploymentArtifacts);                      
1450                 }
1451                 if (!artifactsInfo.isEmpty()){
1452                         instanceArtifactsLocation.addComponentInstancesArtifacts(componentInstance.getNormalizedName(), artifactsInfo);
1453                 }
1454                 
1455                 //5. do the same for all the component instances
1456                 List<ComponentInstance> componentInstances = fetchedComponent.getComponentInstances();
1457                 if (componentInstances!=null){
1458                         for (ComponentInstance childComponentInstance:componentInstances){
1459                                 Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts = collectComponentInstanceArtifacts(
1460                                                 fetchedComponent, childComponentInstance, resourcesTypeArtifacts, componentParentArtifacts);
1461                                 if (collectComponentInstanceArtifacts.isRight()){
1462                                         return collectComponentInstanceArtifacts;
1463                                 }
1464                         }
1465                 }
1466                 
1467                 return Either.left(true);
1468         }
1469
1470         private Map<ArtifactTypeEnum, List<ArtifactDefinition>> getComponentInstanceSpecificArtifacts(Map<String, ArtifactDefinition> componentArtifacts,
1471                         Map<ArtifactGroupTypeEnum, Map<ArtifactTypeEnum, List<ArtifactDefinition>>> componentTypeArtifacts, ArtifactGroupTypeEnum artifactGroupTypeEnum) {
1472                 Map<ArtifactTypeEnum, List<ArtifactDefinition>> parentArtifacts = componentTypeArtifacts.get(artifactGroupTypeEnum);    //the artfiacts of the component itself and not the instance
1473                 
1474                 Map<ArtifactTypeEnum, List<ArtifactDefinition>> artifactsByTypeOfComponentInstance = new EnumMap<>(ArtifactTypeEnum.class);
1475                 if (componentArtifacts!=null){
1476                         for (ArtifactDefinition artifact:componentArtifacts.values()){
1477                                 ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifact.getArtifactType());
1478                                 List<ArtifactDefinition> parentArtifactsByType = null;
1479                                 if (parentArtifacts!=null){
1480                                         parentArtifactsByType = parentArtifacts.get(artifactType);                              
1481                                 }
1482                                 //the artifact is of instance
1483                                 if (parentArtifactsByType == null || !parentArtifactsByType.contains(artifact)){                                
1484                                         List<ArtifactDefinition> typeArtifacts = artifactsByTypeOfComponentInstance.get(artifactType);
1485                                         if (typeArtifacts == null){
1486                                                 typeArtifacts = new ArrayList<>();
1487                                                 artifactsByTypeOfComponentInstance.put(artifactType, typeArtifacts);
1488                                         }
1489                                         typeArtifacts.add(artifact);
1490                                 }
1491                         }
1492                 }
1493                 
1494                 return artifactsByTypeOfComponentInstance;
1495         }
1496
1497         private ArtifactsInfo collectComponentArtifacts(Component component) {
1498                 Map<String, ArtifactDefinition> informationalArtifacts = component.getArtifacts();
1499                 Map<ArtifactTypeEnum, List<ArtifactDefinition>> informationalArtifactsByType = collectGroupArtifacts(informationalArtifacts);
1500                 Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
1501                 Map<ArtifactTypeEnum, List<ArtifactDefinition>> deploymentArtifactsByType = collectGroupArtifacts(deploymentArtifacts);
1502                 ArtifactsInfo artifactsInfo = new ArtifactsInfo();
1503                 if (!informationalArtifactsByType.isEmpty()){
1504                         artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.INFORMATIONAL, informationalArtifactsByType);                   
1505                 }
1506                 if (!deploymentArtifactsByType.isEmpty() ){
1507                         artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, deploymentArtifactsByType);
1508                 }
1509                 
1510                 return artifactsInfo;
1511         }
1512
1513         private Map<ArtifactTypeEnum, List<ArtifactDefinition>> collectGroupArtifacts(Map<String, ArtifactDefinition> componentArtifacts) {
1514                 Map<ArtifactTypeEnum, List<ArtifactDefinition>> artifactsByType = new EnumMap<>(ArtifactTypeEnum.class);
1515                 for (ArtifactDefinition artifact:componentArtifacts.values()){
1516                         if (artifact.getArtifactUUID()!=null){
1517                                 ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifact.getArtifactType());
1518                                 List<ArtifactDefinition> typeArtifacts = artifactsByType.get(artifactType);
1519                                 if (typeArtifacts==null){
1520                                         typeArtifacts = new ArrayList<>();
1521                                         artifactsByType.put(artifactType, typeArtifacts);
1522                                 }
1523                                 typeArtifacts.add(artifact);
1524                         }
1525                 }
1526                 return artifactsByType;
1527         }
1528 }