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