Refactor CsarUtil::getFromCassandra
[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
24 import fj.F;
25 import fj.data.Either;
26 import java.io.BufferedOutputStream;
27 import java.io.ByteArrayInputStream;
28 import java.io.File;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.EnumMap;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Map.Entry;
38 import java.util.Objects;
39 import java.util.Optional;
40 import java.util.Set;
41 import java.util.function.Function;
42 import java.util.function.Supplier;
43 import java.util.regex.Matcher;
44 import java.util.regex.Pattern;
45 import java.util.zip.ZipEntry;
46 import java.util.zip.ZipInputStream;
47 import java.util.zip.ZipOutputStream;
48 import lombok.Getter;
49 import lombok.Setter;
50 import org.apache.commons.codec.binary.Base64;
51 import org.apache.commons.collections.CollectionUtils;
52 import org.apache.commons.collections.MapUtils;
53 import org.apache.commons.io.output.ByteArrayOutputStream;
54 import org.apache.commons.lang.WordUtils;
55 import org.apache.commons.lang3.tuple.ImmutablePair;
56 import org.apache.commons.lang3.tuple.ImmutableTriple;
57 import org.apache.commons.lang3.tuple.Triple;
58 import org.onap.sdc.tosca.services.YamlUtil;
59 import org.openecomp.sdc.be.config.ArtifactConfigManager;
60 import org.openecomp.sdc.be.components.impl.ImportUtils;
61 import org.openecomp.sdc.be.components.impl.ImportUtils.Constants;
62 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
63 import org.openecomp.sdc.be.config.ArtifactConfiguration;
64 import org.openecomp.sdc.be.config.ComponentType;
65 import org.openecomp.sdc.be.config.ConfigurationManager;
66 import org.openecomp.sdc.be.dao.api.ActionStatus;
67 import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
68 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
69 import org.openecomp.sdc.be.dao.cassandra.SdcSchemaFilesCassandraDao;
70 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
71 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
72 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
73 import org.openecomp.sdc.be.impl.ComponentsUtils;
74 import org.openecomp.sdc.be.model.ArtifactDefinition;
75 import org.openecomp.sdc.be.model.Component;
76 import org.openecomp.sdc.be.model.ComponentInstance;
77 import org.openecomp.sdc.be.model.InterfaceDefinition;
78 import org.openecomp.sdc.be.model.LifecycleStateEnum;
79 import org.openecomp.sdc.be.model.Resource;
80 import org.openecomp.sdc.be.model.Service;
81 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
82 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
83 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
84 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
85 import org.openecomp.sdc.be.plugins.CsarEntryGenerator;
86 import org.openecomp.sdc.be.resources.data.DAOArtifactData;
87 import org.openecomp.sdc.be.resources.data.SdcSchemaFilesData;
88 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
89 import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil;
90 import org.openecomp.sdc.be.utils.CommonBeUtils;
91 import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum;
92 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
93 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
94 import org.openecomp.sdc.common.impl.ExternalConfiguration;
95 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
96 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
97 import org.openecomp.sdc.common.log.enums.StatusCode;
98 import org.openecomp.sdc.common.log.wrappers.Logger;
99 import org.openecomp.sdc.common.util.GeneralUtility;
100 import org.openecomp.sdc.common.util.ValidationUtils;
101 import org.openecomp.sdc.common.zip.ZipUtils;
102 import org.openecomp.sdc.exception.ResponseFormat;
103 import org.springframework.beans.factory.annotation.Autowired;
104 import org.yaml.snakeyaml.Yaml;
105
106 /**
107  * @author tg851x
108  *
109  */
110 @org.springframework.stereotype.Component("csar-utils")
111 public class CsarUtils {
112     private static final Logger log = Logger.getLogger(CsarUtils.class);
113     private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(CsarUtils.class.getName());
114     private static final String PATH_DELIMITER = "/";
115     @Autowired
116     private SdcSchemaFilesCassandraDao sdcSchemaFilesCassandraDao;
117     @Autowired
118     private ArtifactCassandraDao artifactCassandraDao;
119     @Autowired
120     private ComponentsUtils componentsUtils;
121     @Autowired
122     private ToscaExportHandler toscaExportUtils;
123     @Autowired
124     protected ToscaOperationFacade toscaOperationFacade;
125
126     @Autowired(required = false)
127     private List<CsarEntryGenerator> generators;
128
129     private static final String CONFORMANCE_LEVEL = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel();
130     private static final String SDC_VERSION = ExternalConfiguration.getAppVersion();
131     public static final String ARTIFACTS_PATH = "Artifacts/";
132     private static final String RESOURCES_PATH = "Resources/";
133     private static final String DEFINITIONS_PATH = "Definitions/";
134     public static final String WORKFLOW_ARTIFACT_DIR = "Workflows"+File.separator+"BPMN"+File.separator;
135     public static final String DEPLOYMENT_ARTIFACTS_DIR = "Deployment"+File.separator;
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     private static final String DEFINITION = "Definitions";
143     private static final String DEL_PATTERN = "([/\\\\]+)";
144     private static final String WORD_PATTERN = "\\w\\_\\-\\.\\s]+)";
145     public static final String VALID_ENGLISH_ARTIFACT_NAME = "([" + WORD_PATTERN;
146     private static final String VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS = "([\\d" + WORD_PATTERN;
147     private static final String ARTIFACT_NAME_UNIQUE_ID = "ArtifactName {}, unique ID {}";
148
149     private static final String VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN = ARTIFACTS + DEL_PATTERN +
150                                                                               ImportUtils.Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX +
151                                                                               VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN +
152                                                                               VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN +
153                                                                               VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN +
154                                                                               VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS;
155
156     public static final String VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN = ARTIFACTS + DEL_PATTERN+
157                                                                              // Artifact Group (i.e Deployment/Informational)
158                                                                              VALID_ENGLISH_ARTIFACT_NAME + DEL_PATTERN +
159                                                                              // Artifact Type
160                                                                              VALID_ENGLISH_ARTIFACT_NAME  + DEL_PATTERN +
161                                                                              // Artifact Any File Name
162                                                                              ".+";
163
164     public static final String SERVICE_TEMPLATE_PATH_PATTERN = DEFINITION + DEL_PATTERN+
165                                                                        // Service Template File Name
166                                                                        VALID_ENGLISH_ARTIFACT_NAME;
167
168     public static final String ARTIFACT_CREATED_FROM_CSAR = "Artifact created from csar";
169     private static final String BLOCK_0_TEMPLATE = "SDC-TOSCA-Meta-File-Version: %s\nSDC-TOSCA-Definitions-Version: %s\n";
170
171     private String versionFirstThreeOctets;
172
173     public CsarUtils() {
174         if(SDC_VERSION != null && !SDC_VERSION.isEmpty()){
175             Matcher matcher = Pattern.compile("(?!\\.)(\\d+(\\.\\d+)+)(?![\\d\\.])").matcher(SDC_VERSION);
176             matcher.find();
177             setVersionFirstThreeOctets(matcher.group(0));
178         } else {
179             setVersionFirstThreeOctets("");
180         }
181     }
182
183     /**
184      *
185      * @param component
186      * @param getFromCS
187      * @param isInCertificationRequest
188      * @return
189      */
190     public Either<byte[], ResponseFormat> createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest) {
191         loggerSupportability.log(LoggerSupportabilityActions.GENERATE_CSAR, StatusCode.STARTED,"Starting to create Csar for component {} ",component.getName());
192         final String createdBy = component.getCreatorFullName();
193         String fileName;
194         Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts();
195         ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
196         fileName = artifactDefinition.getArtifactName();
197
198         String toscaConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel();
199         String csarBlock0 = createCsarBlock0(CSAR_META_VERSION, toscaConformanceLevel);
200         byte[] csarBlock0Byte = csarBlock0.getBytes();
201
202         final String toscaBlock0 = createToscaBlock0(TOSCA_META_VERSION, CSAR_VERSION, createdBy, fileName);
203         byte[] toscaBlock0Byte = toscaBlock0.getBytes();
204
205         return generateCsarZip(csarBlock0Byte, toscaBlock0Byte, component, getFromCS, isInCertificationRequest)
206             .left().map(responseFormat -> {
207             loggerSupportability.log(LoggerSupportabilityActions.GENERATE_CSAR, StatusCode.COMPLETE,
208                 "Ended create Csar for component {} ", component.getName());
209             return responseFormat;
210         });
211     }
212
213     private Either<byte[], ResponseFormat> generateCsarZip(byte[] csarBlock0Byte, byte[] toscaBlock0Byte, Component component, boolean getFromCS, boolean isInCertificationRequest) {
214         try (ByteArrayOutputStream out = new ByteArrayOutputStream();
215              ZipOutputStream zip = new ZipOutputStream(out)) {
216             zip.putNextEntry(new ZipEntry(CSAR_META_PATH_FILE_NAME));
217             zip.write(csarBlock0Byte);
218             zip.putNextEntry(new ZipEntry(TOSCA_META_PATH_FILE_NAME));
219             zip.write(toscaBlock0Byte);
220             Either<ZipOutputStream, ResponseFormat> populateZip = populateZip(component, getFromCS, zip, isInCertificationRequest);
221             if (populateZip.isRight()) {
222                 log.debug("Failed to populate CSAR zip file {}. Please fix DB table accordingly ", populateZip.right().value());
223                 return Either.right(populateZip.right().value());
224             }
225
226             zip.finish();
227             byte[] byteArray = out.toByteArray();
228
229             return Either.left(byteArray);
230         } catch (IOException e) {
231             log.debug("Failed with IOexception to create CSAR zip for component {}. Please fix DB table accordingly ", component.getUniqueId(), e);
232
233             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
234             return Either.right(responseFormat);
235         }
236 }
237
238     private Either<ZipOutputStream, ResponseFormat> populateZip(Component component, boolean getFromCS, ZipOutputStream zip, boolean isInCertificationRequest) throws IOException {
239
240         ArtifactDefinition artifactDef = component
241             .getToscaArtifacts()
242             .get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
243
244         LifecycleStateEnum lifecycleState = component.getLifecycleState();
245         // Assigning to null is a bad practice but in order to keep the refactoring small enough we keep this for now.
246         Either<MainYamlWithDependencies, ResponseFormat> result = null;
247         if (getFromCS || !(lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) {
248             result = getArtifactFromCassandra(artifactDef);
249         } else {
250             result = exportComponent(component);
251         }
252
253         // TODO: Refactor the rest of this function
254         byte[] mainYaml;
255         List<Triple<String, String, Component>> dependencies = null;
256         // This should not be done but in order to keep the refactoring small enough we stop here.
257         if(result.isLeft()) {
258             mainYaml = result.left().value().mainYaml;
259             dependencies = result.left().value().dependencies.orElse(null);
260         } else {
261             return Either.right(result.right().value());
262         }
263
264         String fileName = artifactDef.getArtifactName();
265         zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName));
266         zip.write(mainYaml);
267         //US798487 - Abstraction of complex types
268         if (!ModelConverter.isAtomicComponent(component)){
269             log.debug("Component {} is complex - generating abstract type for it..", component.getName());
270                               writeComponentInterface(component, zip, fileName, false);
271         }
272
273         if (dependencies == null) {
274             Either<ToscaTemplate, ToscaError> dependenciesRes = toscaExportUtils.getDependencies(component);
275             if (dependenciesRes.isRight()) {
276                 log.debug("Failed to retrieve dependencies for component {}, error {}", component.getUniqueId(),
277                         dependenciesRes.right().value());
278                 ActionStatus convertFromToscaError = componentsUtils.convertFromToscaError(dependenciesRes.right().value());
279                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertFromToscaError);
280                 return Either.right(responseFormat);
281             }
282             dependencies = dependenciesRes.left().value().getDependencies();
283         }
284
285         //UID <cassandraId,filename,component>
286         Map<String, ImmutableTriple<String,String, Component>> innerComponentsCache = new HashMap<>();
287
288         Either<ZipOutputStream, ResponseFormat> responseFormat = getZipOutputStreamResponseFormatEither(zip, dependencies, innerComponentsCache);
289         if (responseFormat != null) return responseFormat;
290
291         //retrieve SDC.zip from Cassandra
292         Either<byte[], ResponseFormat> latestSchemaFilesFromCassandra = getLatestSchemaFilesFromCassandra();
293
294         if(latestSchemaFilesFromCassandra.isRight()){
295             log.error("Error retrieving SDC Schema files from cassandra");
296             return Either.right(latestSchemaFilesFromCassandra.right().value());
297         }
298
299         final byte[] schemaFileZip = latestSchemaFilesFromCassandra.left().value();
300
301         final List<String> nodesFromPackage = findNonRootNodesFromPackage(dependencies);
302
303         //add files from retrieved SDC.zip to Definitions folder in CSAR
304         addSchemaFilesFromCassandra(zip, schemaFileZip, nodesFromPackage);
305
306         Either<CsarDefinition, ResponseFormat> collectedComponentCsarDefinition = collectComponentCsarDefinition(component);
307
308         if (collectedComponentCsarDefinition.isRight()) {
309             return Either.right(collectedComponentCsarDefinition.right().value());
310         }
311
312         if (generators != null) {
313                 for (CsarEntryGenerator generator: generators) {
314                     log.debug("Invoking CsarEntryGenerator: {}", generator.getClass().getName());
315                         for (Entry<String, byte[]> pluginGeneratedFile : generator.generateCsarEntries(component).entrySet()) {
316                     zip.putNextEntry(new ZipEntry(pluginGeneratedFile.getKey()));
317                     zip.write(pluginGeneratedFile.getValue());
318                         }
319                 }
320         }
321
322         return writeAllFilesToCsar(component, collectedComponentCsarDefinition.left().value(), zip, isInCertificationRequest);
323     }
324
325     private Either<MainYamlWithDependencies, ResponseFormat> exportComponent(Component component) {
326         return toscaExportUtils.exportComponent(component).right().map(toscaError -> {
327             log.debug("exportComponent failed", toscaError);
328             return componentsUtils.getResponseFormat(componentsUtils.convertFromToscaError(toscaError));
329         }).left().map(MainYamlWithDependencies::make);
330     }
331
332     private Either<MainYamlWithDependencies, ResponseFormat> getArtifactFromCassandra(ArtifactDefinition artifactDef) {
333         return getFromCassandra(artifactDef.getEsId()).right().map(as -> {
334             log.debug(ARTIFACT_NAME_UNIQUE_ID, artifactDef.getArtifactName(), artifactDef.getUniqueId());
335             return componentsUtils.getResponseFormat(as);
336         }).left().map(MainYamlWithDependencies::make);
337     }
338
339     private static class MainYamlWithDependencies {
340
341         private final byte[] mainYaml;
342         private final Optional<List<Triple<String, String, Component>>> dependencies;
343
344         private MainYamlWithDependencies(byte[] mainYaml,
345             Optional<List<Triple<String, String, Component>>> dependencies) {
346             this.mainYaml = mainYaml;
347             this.dependencies = dependencies;
348         }
349
350         static public MainYamlWithDependencies make(byte[] mainYaml) {
351             return new MainYamlWithDependencies(mainYaml, Optional.empty());
352         }
353
354         static public MainYamlWithDependencies make(ToscaRepresentation tr) {
355             return new MainYamlWithDependencies(tr.getMainYaml().getBytes(), Optional.ofNullable(tr.getDependencies()));
356         }
357     }
358
359     /**
360      * Create a list of all derived nodes found on the package
361      *
362      * @param dependencies all node dependencies
363      * @return a list of nodes
364      */
365     private List<String> findNonRootNodesFromPackage(final List<Triple<String, String, Component>> dependencies) {
366         final List<String> nodes = new ArrayList<>();
367         if (CollectionUtils.isNotEmpty(dependencies)) {
368             final String NATIVE_ROOT = "tosca.nodes.Root";
369             dependencies.forEach(dependency -> {
370                 if (dependency.getRight() instanceof Resource) {
371                     final Resource resource = (Resource) dependency.getRight();
372                     if (CollectionUtils.isNotEmpty(resource.getDerivedList())) {
373                         resource.getDerivedList().stream()
374                             .filter(node -> !nodes.contains(node) && !NATIVE_ROOT.equalsIgnoreCase(node))
375                             .forEach(node -> nodes.add(node));
376                     }
377                 }
378             });
379         }
380         return nodes;
381     }
382
383     /**
384      * Writes a new zip entry
385      *
386      * @param zipInputStream the zip entry to be read
387      * @return a map of the given zip entry
388      */
389     private Map<String, Object> readYamlZipEntry(final ZipInputStream zipInputStream) throws IOException {
390         final int initSize = 2048;
391         final StringBuilder zipEntry = new StringBuilder();
392         final byte[] buffer = new byte[initSize];
393         int read = 0;
394         while ((read = zipInputStream.read(buffer, 0, initSize)) >= 0) {
395             zipEntry.append(new String(buffer, 0, read));
396         }
397
398         return (Map<String, Object>) new Yaml().load(zipEntry.toString());
399     }
400
401     /**
402      * Filters and removes all duplicated nodes found
403      *
404      * @param nodesFromPackage a List of all derived nodes found on the given package
405      * @param nodesFromArtifactFile represents the nodes.yml file stored in Cassandra
406      * @return a nodes Map updated
407      */
408     private Map<String, Object> updateNodeYml(final List<String> nodesFromPackage,
409                                               final Map<String, Object> nodesFromArtifactFile) {
410
411         if (MapUtils.isNotEmpty(nodesFromArtifactFile)) {
412             final String nodeTypeBlock = ToscaTagNamesEnum.NODE_TYPES.getElementName();
413             final Map<String, Object> nodeTypes = (Map<String, Object>) nodesFromArtifactFile.get(nodeTypeBlock);
414             nodesFromPackage.stream()
415                 .filter(nodeTypes::containsKey)
416                 .forEach(nodeTypes::remove);
417
418             nodesFromArtifactFile.replace(nodeTypeBlock, nodeTypes);
419         }
420
421         return nodesFromArtifactFile;
422     }
423
424     /**
425      * Updates the zip entry from the given parameters
426      *
427      * @param byteArrayOutputStream an output stream in which the data is written into a byte array.
428      * @param nodesYaml a Map of nodes to be written
429      */
430     private void updateZipEntry(final ByteArrayOutputStream byteArrayOutputStream,
431                                 final Map<String, Object> nodesYaml) throws IOException {
432         if (MapUtils.isNotEmpty(nodesYaml)) {
433             byteArrayOutputStream.write(new YamlUtil().objectToYaml(nodesYaml).getBytes());
434         }
435     }
436
437     private Either<ZipOutputStream, ResponseFormat> getZipOutputStreamResponseFormatEither(ZipOutputStream zip, List<Triple<String, String, Component>> dependencies, Map<String, ImmutableTriple<String, String, Component>> innerComponentsCache) throws IOException {
438         String fileName;
439         if (dependencies != null && !dependencies.isEmpty()) {
440             for (Triple<String, String, Component> d : dependencies) {
441                 String cassandraId = d.getMiddle();
442                 Component childComponent = d.getRight();
443                 Either<byte[], ActionStatus> entryData = getEntryData(cassandraId, childComponent);
444
445                 if (entryData.isRight()) {
446                     ResponseFormat responseFormat = componentsUtils.getResponseFormat(entryData.right().value());
447                     return Either.right(responseFormat);
448                 }
449
450                 //fill innerComponentsCache
451                 fileName = d.getLeft();
452                 addComponentToCache(innerComponentsCache, cassandraId, fileName, childComponent);
453                 addInnerComponentsToCache(innerComponentsCache, childComponent);
454             }
455
456             //add inner components to CSAR
457             Either<ZipOutputStream, ResponseFormat> responseFormat = addInnerComponentsToCSAR(zip, innerComponentsCache);
458             if (responseFormat != null) return responseFormat;
459         }
460         return null;
461     }
462
463     private Either<ZipOutputStream, ResponseFormat> addInnerComponentsToCSAR(ZipOutputStream zip, Map<String, ImmutableTriple<String, String, Component>> innerComponentsCache) throws IOException {
464         for (Entry<String, ImmutableTriple<String, String, Component>> innerComponentTripleEntry : innerComponentsCache.entrySet()) {
465
466             ImmutableTriple<String, String, Component> innerComponentTriple = innerComponentTripleEntry.getValue();
467
468             Component innerComponent = innerComponentTriple.getRight();
469             String icFileName = innerComponentTriple.getMiddle();
470
471             // add component to zip
472             Either<byte[], ActionStatus> entryData = getEntryData(innerComponentTriple.getLeft(), innerComponent);
473             if (entryData.isRight()) {
474                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(entryData.right().value());
475                 log.debug("Failed adding to zip component {}, error {}", innerComponentTriple.getLeft(),
476                         entryData.right().value());
477                 return Either.right(responseFormat);
478             }
479             byte[] content = entryData.left().value();
480             zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + icFileName));
481             zip.write(content);
482
483             // add component interface to zip
484             if (!ModelConverter.isAtomicComponent(innerComponent)) {
485                                         writeComponentInterface(innerComponent, zip, icFileName, true);
486             }
487         }
488         return null;
489     }
490
491     private void addSchemaFilesFromCassandra(final ZipOutputStream zip,
492                                              final byte[] schemaFileZip,
493                                              final List<String> nodesFromPackage) {
494         final int initSize = 2048;
495         log.debug("Starting copy from Schema file zip to CSAR zip");
496         try (final ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(schemaFileZip));
497             final ByteArrayOutputStream out = new ByteArrayOutputStream();
498             final BufferedOutputStream bos = new BufferedOutputStream(out, initSize)) {
499
500             ZipEntry entry;
501             while ((entry = zipStream.getNextEntry()) != null) {
502                 ZipUtils.checkForZipSlipInRead(entry);
503                 final String entryName = entry.getName();
504                 int readSize = initSize;
505                 final byte[] entryData = new byte[initSize];
506                 if (entryName.equalsIgnoreCase("nodes.yml")) {
507                     handleNode(zipStream, out, nodesFromPackage);
508                 } else {
509                     while ((readSize = zipStream.read(entryData, 0, readSize)) != -1) {
510                         bos.write(entryData, 0, readSize);
511                     }
512                     bos.flush();
513                 }
514                 out.flush();
515                 zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + entryName));
516                 zip.write(out.toByteArray());
517                 zip.flush();
518                 out.reset();
519             }
520         } catch (final Exception e) {
521             log.error("Error while writing the SDC schema file to the CSAR", e);
522             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
523         }
524         log.debug("Finished copy from Schema file zip to CSAR zip");
525     }
526
527     /**
528      * Handles the nodes.yml zip entry, updating the nodes.yml to avoid duplicated nodes on it.
529      *
530      * @param zipInputStream the zip entry to be read
531      * @param byteArrayOutputStream an output stream in which the data is written into a byte array.
532      * @param nodesFromPackage list of all nodes found on the onboarded package
533      */
534     private void handleNode(final ZipInputStream zipInputStream,
535                             final ByteArrayOutputStream byteArrayOutputStream,
536                             final List<String> nodesFromPackage) throws IOException {
537
538         final Map<String, Object> nodesFromArtifactFile = readYamlZipEntry(zipInputStream);
539         final Map<String, Object> nodesYaml = updateNodeYml(nodesFromPackage, nodesFromArtifactFile);
540         updateZipEntry(byteArrayOutputStream, nodesYaml);
541     }
542
543     private void addInnerComponentsToCache(Map<String, ImmutableTriple<String, String, Component>> componentCache,
544             Component childComponent) {
545
546         List<ComponentInstance> instances = childComponent.getComponentInstances();
547
548         if(instances != null) {
549             instances.forEach(ci -> {
550                 ImmutableTriple<String, String, Component> componentRecord = componentCache.get(ci.getComponentUid());
551                 if (componentRecord == null) {
552                     // all resource must be only once!
553                     Either<Resource, StorageOperationStatus> resource = toscaOperationFacade.getToscaElement(ci.getComponentUid());
554                     Component componentRI = checkAndAddComponent(componentCache, ci, resource);
555
556                     //if not atomic - insert inner components as well
557                     if(!ModelConverter.isAtomicComponent(componentRI)) {
558                         addInnerComponentsToCache(componentCache, componentRI);
559                     }
560                 }
561             });
562         }
563     }
564
565     private Component checkAndAddComponent(Map<String, ImmutableTriple<String, String, Component>> componentCache, ComponentInstance ci, Either<Resource, StorageOperationStatus> resource) {
566         if (resource.isRight()) {
567             log.debug("Failed to fetch resource with id {} for instance {}", ci.getComponentUid(), ci.getName());
568         }
569         Component componentRI = resource.left().value();
570
571         Map<String, ArtifactDefinition> childToscaArtifacts = componentRI.getToscaArtifacts();
572         ArtifactDefinition childArtifactDefinition = childToscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE);
573         if (childArtifactDefinition != null) {
574             //add to cache
575             addComponentToCache(componentCache, childArtifactDefinition.getEsId(), childArtifactDefinition.getArtifactName(), componentRI);
576         }
577         return componentRI;
578     }
579
580     private void addComponentToCache(Map<String, ImmutableTriple<String, String, Component>> componentCache,
581             String id, String fileName, Component component) {
582
583         ImmutableTriple<String, String, Component> cachedComponent = componentCache.get(component.getInvariantUUID());
584         if (cachedComponent == null || CommonBeUtils.compareAsdcComponentVersions(component.getVersion(), cachedComponent.getRight().getVersion())) {
585             componentCache.put(component.getInvariantUUID(),
586                     new ImmutableTriple<>(id, fileName, component));
587
588             if(cachedComponent != null) {
589                 //overwriting component with newer version
590                 log.warn("Overwriting component invariantID {} of version {} with a newer version {}", id, cachedComponent.getRight().getVersion(), component.getVersion());
591             }
592         }
593     }
594         private Either<ZipOutputStream, ResponseFormat> writeComponentInterface(Component component, ZipOutputStream zip,
595                         String fileName, boolean isAssociatedComponent) {
596                 try {
597                         Either<ToscaRepresentation, ToscaError> componentInterface = toscaExportUtils
598                                         .exportComponentInterface(component, isAssociatedComponent);
599                         ToscaRepresentation componentInterfaceYaml = componentInterface.left().value();
600                         String mainYaml = componentInterfaceYaml.getMainYaml();
601                         String interfaceFileName = DEFINITIONS_PATH + ToscaExportHandler.getInterfaceFilename(fileName);
602
603                         zip.putNextEntry(new ZipEntry(interfaceFileName));
604                         zip.write(mainYaml.getBytes());
605
606                 } catch (Exception e) {
607                         log.error("#writeComponentInterface - zip writing failed with error: ", e);
608                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
609                 }
610
611                 return Either.left(zip);
612         }
613
614     private Either<byte[], ActionStatus> getEntryData(String cassandraId, Component childComponent) {
615         if (cassandraId == null || cassandraId.isEmpty()) {
616             return toscaExportUtils.exportComponent(childComponent)
617                 .right().map(toscaErrorToActionStatus(childComponent))
618                 .left().map(toscaRepresentation -> toscaRepresentation.getMainYaml().getBytes());
619         } else {
620             return getFromCassandra(cassandraId);
621         }
622     }
623
624     private F<ToscaError, ActionStatus> toscaErrorToActionStatus(Component childComponent) {
625         return toscaError -> {
626             log.debug("Failed to export tosca template for child component {} error {}",
627                 childComponent.getUniqueId(), toscaError);
628             return componentsUtils.convertFromToscaError(toscaError);
629         };
630     }
631
632     private Either<byte[], ResponseFormat> getLatestSchemaFilesFromCassandra() {
633         Either<List<SdcSchemaFilesData>, CassandraOperationStatus> specificSchemaFiles = sdcSchemaFilesCassandraDao.getSpecificSchemaFiles(getVersionFirstThreeOctets(), CONFORMANCE_LEVEL);
634
635         if(specificSchemaFiles.isRight()){
636             log.debug("Failed to get the schema files SDC-Version: {} Conformance-Level {}. Please fix DB table accordingly.", getVersionFirstThreeOctets(), CONFORMANCE_LEVEL);
637             StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(specificSchemaFiles.right().value());
638             ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus);
639             return Either.right(componentsUtils.getResponseFormat(convertedFromStorageResponse));
640         }
641
642         List<SdcSchemaFilesData> listOfSchemas = specificSchemaFiles.left().value();
643
644         if(listOfSchemas.isEmpty()){
645             log.debug("Failed to get the schema files SDC-Version: {} Conformance-Level {}", getVersionFirstThreeOctets(), CONFORMANCE_LEVEL);
646             return Either.right(componentsUtils.getResponseFormat(ActionStatus.TOSCA_SCHEMA_FILES_NOT_FOUND, getVersionFirstThreeOctets(), CONFORMANCE_LEVEL));
647         }
648
649         SdcSchemaFilesData schemaFile = listOfSchemas.iterator().next();
650
651         return Either.left(schemaFile.getPayloadAsArray());
652     }
653
654     private Either<byte[], ActionStatus> getFromCassandra(String cassandraId) {
655         return artifactCassandraDao.getArtifact(cassandraId)
656             .right().map(cos -> {
657                 log.debug("Failed to fetch artifact from Cassandra by id {} error {} ", cassandraId, cos);
658                 StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(cos);
659                 return componentsUtils.convertFromStorageResponse(storageStatus);
660             }).left().map(DAOArtifactData::getDataAsArray);
661     }
662
663     private String createCsarBlock0(String metaFileVersion, String toscaConformanceLevel) {
664         return String.format(BLOCK_0_TEMPLATE, metaFileVersion, toscaConformanceLevel);
665     }
666
667     private String createToscaBlock0(String metaFileVersion, String csarVersion, String createdBy, String entryDef) {
668         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";
669         return String.format(block0template, metaFileVersion, csarVersion, createdBy, entryDef);
670     }
671
672     /**
673      * Extracts artifacts of VFCs from CSAR
674      *
675      * @param csar
676      * @return Map of <String, List<ArtifactDefinition>> the contains Lists of artifacts according vfcToscaNamespace
677      */
678     public static Map<String, List<ArtifactDefinition>> extractVfcsArtifactsFromCsar(Map<String, byte[]> csar) {
679
680         Map<String, List<ArtifactDefinition>> artifacts = new HashMap<>();
681         if (csar != null) {
682             log.debug("************* Going to extract VFCs artifacts from Csar. ");
683             Map<String, Set<List<String>>> collectedWarningMessages = new HashMap<>();
684             csar.entrySet().stream()
685                 // filter CSAR entry by node type artifact path
686                 .filter(e -> Pattern.compile(VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches())
687                 // extract ArtifactDefinition from CSAR entry for each entry with matching artifact path
688                 .forEach(e -> addExtractedVfcArtifact(extractVfcArtifact(e, collectedWarningMessages), artifacts));
689             // add counter suffix to artifact labels
690             handleWarningMessages(collectedWarningMessages);
691
692         }
693         return artifacts;
694     }
695
696     /**
697      * Print warnings to log
698      *
699      * @param collectedWarningMessages
700      */
701     public static void handleWarningMessages(Map<String, Set<List<String>>> collectedWarningMessages) {
702         collectedWarningMessages.entrySet().stream()
703                                 // for each vfc
704                                 .forEach(e -> e.getValue().stream()
705                                                // add each warning message to log
706                                                .forEach(args -> log.warn(e.getKey(), args.toArray())));
707
708     }
709
710     private static void addExtractedVfcArtifact(ImmutablePair<String, ArtifactDefinition> extractedVfcArtifact, Map<String, List<ArtifactDefinition>> artifacts) {
711         if (extractedVfcArtifact != null) {
712             List<ArtifactDefinition> currArtifactsList;
713             String vfcToscaNamespace = extractedVfcArtifact.getKey();
714             if (artifacts.containsKey(vfcToscaNamespace)) {
715                 currArtifactsList = artifacts.get(vfcToscaNamespace);
716             } else {
717                 currArtifactsList = new ArrayList<>();
718                 artifacts.put(vfcToscaNamespace, currArtifactsList);
719             }
720             currArtifactsList.add(extractedVfcArtifact.getValue());
721         }
722     }
723
724     private static ImmutablePair<String, ArtifactDefinition> extractVfcArtifact(Entry<String, byte[]> entry, Map<String, Set<List<String>>> collectedWarningMessages) {
725         ArtifactDefinition artifact;
726         String[] parsedCsarArtifactPath = entry.getKey().split(PATH_DELIMITER);
727         Either<ArtifactGroupTypeEnum, Boolean> eitherArtifactGroupType = detectArtifactGroupType(parsedCsarArtifactPath[2].toUpperCase(), collectedWarningMessages);
728         if (eitherArtifactGroupType.isLeft()) {
729             artifact = buildArtifactDefinitionFromCsarArtifactPath(entry, collectedWarningMessages, parsedCsarArtifactPath, eitherArtifactGroupType.left().value());
730         } else {
731             return null;
732         }
733         return new ImmutablePair<>(parsedCsarArtifactPath[1], artifact);
734     }
735
736     private static Either<ArtifactGroupTypeEnum, Boolean> detectArtifactGroupType(String groupType, Map<String, Set<List<String>>> collectedWarningMessages) {
737         Either<ArtifactGroupTypeEnum, Boolean> result;
738         try {
739             ArtifactGroupTypeEnum artifactGroupType = ArtifactGroupTypeEnum.findType(groupType.toUpperCase());
740             if (artifactGroupType == null || (artifactGroupType != ArtifactGroupTypeEnum.INFORMATIONAL && artifactGroupType != ArtifactGroupTypeEnum.DEPLOYMENT)) {
741                 String warningMessage = "Warning - unrecognized artifact group type {} was received.";
742                 List<String> messageArguments = new ArrayList<>();
743                 messageArguments.add(groupType);
744                 if (!collectedWarningMessages.containsKey(warningMessage)) {
745                     Set<List<String>> messageArgumentLists = new HashSet<>();
746                     messageArgumentLists.add(messageArguments);
747                     collectedWarningMessages.put(warningMessage, messageArgumentLists);
748                 } else {
749                     collectedWarningMessages.get(warningMessage).add(messageArguments);
750                 }
751
752                 result = Either.right(false);
753             } else {
754
755                 result = Either.left(artifactGroupType);
756             }
757         } catch (Exception e) {
758             log.debug("detectArtifactGroupType failed with exception", e);
759             result = Either.right(false);
760         }
761         return result;
762     }
763
764     private static ArtifactDefinition buildArtifactDefinitionFromCsarArtifactPath(Entry<String, byte[]> entry, Map<String, Set<List<String>>> collectedWarningMessages, String[] parsedCsarArtifactPath, ArtifactGroupTypeEnum artifactGroupType) {
765         ArtifactDefinition artifact;
766         artifact = new ArtifactDefinition();
767         artifact.setArtifactGroupType(artifactGroupType);
768         artifact.setArtifactType(detectArtifactTypeVFC(artifactGroupType, parsedCsarArtifactPath[3], parsedCsarArtifactPath[1], collectedWarningMessages));
769         artifact.setArtifactName(ValidationUtils.normalizeFileName(parsedCsarArtifactPath[parsedCsarArtifactPath.length - 1]));
770         artifact.setPayloadData(Base64.encodeBase64String(entry.getValue()));
771         artifact.setArtifactDisplayName(artifact.getArtifactName().lastIndexOf('.') > 0 ? artifact.getArtifactName().substring(0, artifact.getArtifactName().lastIndexOf('.')) : artifact.getArtifactName());
772         artifact.setArtifactLabel(ValidationUtils.normalizeArtifactLabel(artifact.getArtifactName()));
773         artifact.setDescription(ARTIFACT_CREATED_FROM_CSAR);
774         artifact.setIsFromCsar(true);
775         artifact.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(entry.getValue()));
776         return artifact;
777     }
778
779     @Getter
780     public static final class NonMetaArtifactInfo {
781         @Setter
782         private String artifactUniqueId;
783         private final String path;
784         private final String artifactName;
785         private final String displayName;
786         private final String artifactLabel;
787         private final String artifactType;
788         private final ArtifactGroupTypeEnum artifactGroupType;
789         private final String payloadData;
790         private final String artifactChecksum;
791         private final boolean isFromCsar;
792
793         public NonMetaArtifactInfo(final String artifactName, final String path, final String artifactType,
794                                    final ArtifactGroupTypeEnum artifactGroupType, final byte[] payloadData,
795                                    final String artifactUniqueId, final boolean isFromCsar) {
796             super();
797             this.path = path;
798             this.isFromCsar = isFromCsar;
799             this.artifactName = ValidationUtils.normalizeFileName(artifactName);
800             this.artifactType = artifactType;
801             this.artifactGroupType = artifactGroupType;
802             final int pointIndex = artifactName.lastIndexOf('.');
803             if (pointIndex > 0) {
804                 displayName = artifactName.substring(0, pointIndex);
805             } else {
806                 displayName = artifactName;
807             }
808             this.artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactName);
809             if (payloadData == null) {
810                 this.payloadData = null;
811                 this.artifactChecksum = null;
812             } else {
813                 this.payloadData = Base64.encodeBase64String(payloadData);
814                 this.artifactChecksum = GeneralUtility.calculateMD5Base64EncodedByByteArray(payloadData);
815             }
816             this.artifactUniqueId = artifactUniqueId;
817         }
818
819     }
820
821     /**
822      * This method checks the artifact GroupType & Artifact Type. <br>
823      * if there is any problem warning messages are added to collectedWarningMessages
824      *
825      * @param artifactPath
826      * @param collectedWarningMessages
827      * @return
828      */
829     public static Either<NonMetaArtifactInfo, Boolean> validateNonMetaArtifact(
830         String artifactPath,
831         byte[] payloadData,
832         Map<String, Set<List<String>>> collectedWarningMessages
833     ) {
834         try {
835             String[] parsedArtifactPath = artifactPath.split(PATH_DELIMITER);
836             String groupType = parsedArtifactPath[1];
837             String receivedTypeName = parsedArtifactPath[2];
838             String artifactFileNameType = parsedArtifactPath[3];
839
840             return detectArtifactGroupType(groupType, collectedWarningMessages)
841                 .left().bind(artifactGroupType -> {
842                     String artifactType =
843                         detectArtifactTypeVF(artifactGroupType, receivedTypeName, collectedWarningMessages);
844
845                     return Either.left(new NonMetaArtifactInfo(
846                         artifactFileNameType, artifactPath, artifactType,
847                         artifactGroupType, payloadData, null, true
848                     ));
849                 });
850         } catch (Exception e) {
851             log.debug("detectArtifactGroupType failed with exception", e);
852             return Either.right(false);
853         }
854     }
855
856     private static String detectArtifactTypeVFC(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName, String parentVfName, Map<String, Set<List<String>>> collectedWarningMessages) {
857         String warningMessage = "Warning - artifact type {} that was provided for VFC {} is not recognized.";
858         return detectArtifactType(artifactGroupType, receivedTypeName, warningMessage, collectedWarningMessages, parentVfName);
859     }
860
861     private static String detectArtifactTypeVF(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName, Map<String, Set<List<String>>> collectedWarningMessages) {
862         String warningMessage = "Warning - artifact type {} that was provided for VF is not recognized.";
863         return detectArtifactType(artifactGroupType, receivedTypeName, warningMessage, collectedWarningMessages);
864     }
865
866     private static String detectArtifactType(final ArtifactGroupTypeEnum artifactGroupType,
867                                              final String receivedTypeName, final String warningMessage,
868                                              final Map<String, Set<List<String>>> collectedWarningMessages,
869                                              final String... arguments) {
870         final ArtifactConfiguration artifactConfiguration =
871             ArtifactConfigManager.getInstance()
872                 .find(receivedTypeName, artifactGroupType, ComponentType.RESOURCE)
873                 .orElse(null);
874
875         if (artifactConfiguration == null) {
876             final List<String> messageArguments = new ArrayList<>();
877             messageArguments.add(receivedTypeName);
878             messageArguments.addAll(Arrays.asList(arguments));
879             if (!collectedWarningMessages.containsKey(warningMessage)) {
880                 final Set<List<String>> messageArgumentLists = new HashSet<>();
881                 messageArgumentLists.add(messageArguments);
882                 collectedWarningMessages.put(warningMessage, messageArgumentLists);
883             } else {
884                 collectedWarningMessages.get(warningMessage).add(messageArguments);
885             }
886         }
887
888         return artifactConfiguration == null ? ArtifactTypeEnum.OTHER.getType() : receivedTypeName;
889     }
890
891     private Either<ZipOutputStream, ResponseFormat> writeAllFilesToCsar(Component mainComponent, CsarDefinition csarDefinition, ZipOutputStream zipstream, boolean isInCertificationRequest) throws IOException{
892         ComponentArtifacts componentArtifacts = csarDefinition.getComponentArtifacts();
893
894         Either<ZipOutputStream, ResponseFormat> writeComponentArtifactsToSpecifiedPath = writeComponentArtifactsToSpecifiedPath(mainComponent, componentArtifacts, zipstream, ARTIFACTS_PATH, isInCertificationRequest);
895
896         if(writeComponentArtifactsToSpecifiedPath.isRight()){
897             return Either.right(writeComponentArtifactsToSpecifiedPath.right().value());
898         }
899
900         ComponentTypeArtifacts mainTypeAndCIArtifacts = componentArtifacts.getMainTypeAndCIArtifacts();
901         writeComponentArtifactsToSpecifiedPath = writeArtifactsInfoToSpecifiedPath(mainComponent, mainTypeAndCIArtifacts.getComponentArtifacts(), zipstream, ARTIFACTS_PATH, isInCertificationRequest);
902
903         if(writeComponentArtifactsToSpecifiedPath.isRight()){
904             return Either.right(writeComponentArtifactsToSpecifiedPath.right().value());
905         }
906
907         Map<String, ArtifactsInfo> componentInstancesArtifacts = mainTypeAndCIArtifacts.getComponentInstancesArtifacts();
908         Set<String> keySet = componentInstancesArtifacts.keySet();
909
910         String currentPath = ARTIFACTS_PATH + RESOURCES_PATH;
911         for (String keyAssetName : keySet) {
912             ArtifactsInfo artifactsInfo = componentInstancesArtifacts.get(keyAssetName);
913             String pathWithAssetName = currentPath + keyAssetName + PATH_DELIMITER;
914             writeComponentArtifactsToSpecifiedPath = writeArtifactsInfoToSpecifiedPath(mainComponent, artifactsInfo, zipstream, pathWithAssetName, isInCertificationRequest);
915
916             if(writeComponentArtifactsToSpecifiedPath.isRight()){
917                 return Either.right(writeComponentArtifactsToSpecifiedPath.right().value());
918             }
919         }
920         writeComponentArtifactsToSpecifiedPath = writeOperationsArtifactsToCsar(mainComponent, zipstream);
921
922         if (writeComponentArtifactsToSpecifiedPath.isRight()) {
923             return Either.right(writeComponentArtifactsToSpecifiedPath.right().value());
924         }
925         return Either.left(zipstream);
926     }
927
928     private Either<ZipOutputStream, ResponseFormat> writeOperationsArtifactsToCsar(Component component,
929             ZipOutputStream zipstream) {
930         if (checkComponentBeforeOperation(component)) return Either.left(zipstream);
931         final Map<String, InterfaceDefinition> interfaces = ((Resource) component).getInterfaces();
932         for (Map.Entry<String, InterfaceDefinition> interfaceEntry : interfaces.entrySet()) {
933             for (OperationDataDefinition operation : interfaceEntry.getValue().getOperations().values()) {
934                 try {
935                     if (checkComponentBeforeWrite(component, interfaceEntry, operation)) continue;
936                     final String artifactUUID = operation.getImplementation().getArtifactUUID();
937                     final Either<byte[], ActionStatus> artifactFromCassandra = getFromCassandra(artifactUUID);
938                     final String artifactName = operation.getImplementation().getArtifactName();
939                     if (artifactFromCassandra.isRight()) {
940                         log.error(ARTIFACT_NAME_UNIQUE_ID, artifactName, artifactUUID);
941                         log.error("Failed to get {} payload from DB reason: {}", artifactName,
942                                 artifactFromCassandra.right().value());
943                         return Either.right(componentsUtils.getResponseFormat(
944                                 ActionStatus.ARTIFACT_PAYLOAD_NOT_FOUND_DURING_CSAR_CREATION, "Resource",
945                                 component.getUniqueId(), artifactName, artifactUUID));
946                     }
947                     final byte[] payloadData = artifactFromCassandra.left().value();
948                     zipstream.putNextEntry(new ZipEntry(OperationArtifactUtil.createOperationArtifactPath(
949                             component, null, operation,true)));
950                     zipstream.write(payloadData);
951                 } catch (IOException e) {
952                     log.error("Component Name {},  Interface Name {}, Operation Name {}", component.getNormalizedName(),
953                             interfaceEntry.getKey(), operation.getName());
954                     log.error("Error while writing the operation's artifacts to the CSAR " + "{}", e);
955                     return Either.right(componentsUtils
956                                                 .getResponseFormat(ActionStatus.ERROR_DURING_CSAR_CREATION, "Resource",
957                                                         component.getUniqueId()));
958                 }
959             }
960         }
961         return Either.left(zipstream);
962     }
963
964     private boolean checkComponentBeforeWrite(Component component, Entry<String, InterfaceDefinition> interfaceEntry, OperationDataDefinition operation) {
965         if (Objects.isNull(operation.getImplementation())) {
966             log.debug("Component Name {}, Interface Id {}, Operation Name {} - no Operation Implementation found",
967                     component.getNormalizedName(), interfaceEntry.getValue().getUniqueId(),
968                     operation.getName());
969             return true;
970         }
971         if (Objects.isNull(operation.getImplementation().getArtifactName())) {
972             log.debug("Component Name {}, Interface Id {}, Operation Name {} - no artifact found",
973                     component.getNormalizedName(), interfaceEntry.getValue().getUniqueId(),
974                     operation.getName());
975             return true;
976         }
977         if (operation.getImplementation().getArtifactName().startsWith(Constants.ESCAPED_DOUBLE_QUOTE) && operation.getImplementation().getArtifactName().endsWith(Constants.ESCAPED_DOUBLE_QUOTE)) {
978             log.debug("Component Name {}, Interface Id {}, Operation Name {} - artifact name is a literal value rather than an SDC artifact",
979                     component.getNormalizedName(), interfaceEntry.getValue().getUniqueId(),
980                     operation.getName());
981             return true;
982         }
983         return false;
984     }
985
986     private boolean checkComponentBeforeOperation(Component component) {
987         if (component instanceof Service) {
988             return true;
989         }
990         if (Objects.isNull(((Resource) component).getInterfaces())) {
991             log.debug("Component Name {}- no interfaces found", component.getNormalizedName());
992             return true;
993         }
994         return false;
995     }
996
997     private Either<ZipOutputStream, ResponseFormat> writeComponentArtifactsToSpecifiedPath(Component mainComponent, ComponentArtifacts componentArtifacts, ZipOutputStream zipstream,
998             String currentPath, boolean isInCertificationRequest) throws IOException {
999         Map<String, ComponentTypeArtifacts> componentTypeArtifacts = componentArtifacts.getComponentTypeArtifacts();
1000         //Keys are defined:
1001         //<Inner Asset TOSCA name (e.g. VFC name)> folder name: <Inner Asset TOSCA name (e.g. VFC name)>_v<version>.
1002         //E.g. "org.openecomp.resource.vf.vipr_atm_v1.0"
1003         Set<String> componentTypeArtifactsKeys = componentTypeArtifacts.keySet();
1004         for (String keyAssetName : componentTypeArtifactsKeys) {
1005             ComponentTypeArtifacts componentInstanceArtifacts = componentTypeArtifacts.get(keyAssetName);
1006             ArtifactsInfo componentArtifacts2 = componentInstanceArtifacts.getComponentArtifacts();
1007             String pathWithAssetName = currentPath + keyAssetName + PATH_DELIMITER;
1008             Either<ZipOutputStream, ResponseFormat> writeArtifactsInfoToSpecifiedPath = writeArtifactsInfoToSpecifiedPath(mainComponent, componentArtifacts2, zipstream, pathWithAssetName, isInCertificationRequest);
1009
1010             if(writeArtifactsInfoToSpecifiedPath.isRight()){
1011                 return writeArtifactsInfoToSpecifiedPath;
1012             }
1013         }
1014
1015         return Either.left(zipstream);
1016     }
1017
1018     private Either<ZipOutputStream, ResponseFormat> writeArtifactsInfoToSpecifiedPath(final Component mainComponent,
1019                                                                                       final ArtifactsInfo currArtifactsInfo,
1020                                                                                       final ZipOutputStream zip,
1021                                                                                       final String path,
1022                                                                                       final boolean isInCertificationRequest) throws IOException {
1023         final Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactsInfo =
1024             currArtifactsInfo.getArtifactsInfo();
1025         for (final ArtifactGroupTypeEnum artifactGroupTypeEnum : artifactsInfo.keySet()) {
1026             final String groupTypeFolder = path + WordUtils.capitalizeFully(artifactGroupTypeEnum.getType()) + PATH_DELIMITER;
1027
1028             final Map<String, List<ArtifactDefinition>> artifactTypesMap = artifactsInfo.get(artifactGroupTypeEnum);
1029
1030             for (final String artifactType : artifactTypesMap.keySet()) {
1031                 final List<ArtifactDefinition> artifactDefinitionList = artifactTypesMap.get(artifactType);
1032                                 String artifactTypeFolder = groupTypeFolder + artifactType + PATH_DELIMITER;
1033
1034                                 if(ArtifactTypeEnum.WORKFLOW.getType().equals(artifactType) && path.contains(ARTIFACTS_PATH + RESOURCES_PATH)){
1035                                         // Ignore this packaging as BPMN artifacts needs to be packaged in different manner
1036                                         continue;
1037                                 }
1038                                 if (ArtifactTypeEnum.WORKFLOW.getType().equals(artifactType)) {
1039                                         artifactTypeFolder += OperationArtifactUtil.BPMN_ARTIFACT_PATH + File.separator;
1040                                 }
1041
1042                 Either<ZipOutputStream, ResponseFormat> writeArtifactDefinition =
1043                     writeArtifactDefinition(mainComponent, zip, artifactDefinitionList, artifactTypeFolder, isInCertificationRequest);
1044
1045                 if (writeArtifactDefinition.isRight()) {
1046                     return writeArtifactDefinition;
1047                 }
1048             }
1049         }
1050
1051         return Either.left(zip);
1052     }
1053
1054     private Either<ZipOutputStream, ResponseFormat> writeArtifactDefinition(Component mainComponent, ZipOutputStream zip, List<ArtifactDefinition> artifactDefinitionList,
1055             String artifactPathAndFolder, boolean isInCertificationRequest) throws IOException {
1056
1057         ComponentTypeEnum componentType = mainComponent.getComponentType();
1058         String heatEnvType = ArtifactTypeEnum.HEAT_ENV.getType();
1059
1060         for (ArtifactDefinition artifactDefinition : artifactDefinitionList) {
1061             if (!isInCertificationRequest && componentType == ComponentTypeEnum.SERVICE
1062                         && artifactDefinition.getArtifactType().equals(heatEnvType) ||
1063                         //this is placeholder
1064                         (artifactDefinition.getEsId() == null && artifactDefinition.getMandatory())){
1065                 continue;
1066             }
1067
1068             byte[] payloadData = artifactDefinition.getPayloadData();
1069             String artifactFileName = artifactDefinition.getArtifactName();
1070
1071             if (payloadData == null) {
1072                 Either<byte[], ActionStatus> fromCassandra = getFromCassandra(artifactDefinition.getEsId());
1073
1074                 if (fromCassandra.isRight()) {
1075                     log.debug(ARTIFACT_NAME_UNIQUE_ID, artifactDefinition.getArtifactName(), artifactDefinition.getUniqueId());
1076                     log.debug("Failed to get {} payload from DB reason: {}", artifactFileName, fromCassandra.right().value());
1077                     continue;
1078                 }
1079                 payloadData = fromCassandra.left().value();
1080             }
1081             zip.putNextEntry(new ZipEntry(artifactPathAndFolder + artifactFileName));
1082             zip.write(payloadData);
1083         }
1084
1085         return Either.left(zip);
1086     }
1087
1088     /************************************ Artifacts Structure ******************************************************************/
1089     /**
1090      * The artifacts Definition saved by their structure
1091      */
1092     private class ArtifactsInfo {
1093         //Key is the type of artifacts(Informational/Deployment)
1094         //Value is a map between an artifact type and a list of all artifacts of this type
1095         private Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactsInfoField;
1096
1097         public ArtifactsInfo() {
1098             this.artifactsInfoField = new EnumMap<>(ArtifactGroupTypeEnum.class);
1099         }
1100
1101         public Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> getArtifactsInfo() {
1102             return artifactsInfoField;
1103         }
1104
1105         public void addArtifactsToGroup(ArtifactGroupTypeEnum artifactGroup,
1106                                         Map<String, List<ArtifactDefinition>> artifactsDefinition) {
1107                         if (artifactsInfoField.get(artifactGroup) == null) {
1108                                 artifactsInfoField.put(artifactGroup, artifactsDefinition);
1109                         } else {
1110                                 Map<String, List<ArtifactDefinition>> artifactTypeEnumListMap =
1111                                                 artifactsInfoField.get(artifactGroup);
1112                                 artifactTypeEnumListMap.putAll(artifactsDefinition);
1113                                 artifactsInfoField.put(artifactGroup, artifactTypeEnumListMap);
1114                         }
1115
1116         }
1117
1118         public boolean isEmpty() {
1119             return artifactsInfoField.isEmpty();
1120         }
1121
1122         public boolean isNotEmpty() {
1123             return !isEmpty();
1124         }
1125
1126     }
1127
1128     /**
1129      * The artifacts of the component and of all its composed instances
1130      *
1131      */
1132     private class ComponentTypeArtifacts {
1133         private ArtifactsInfo componentArtifacts;    //component artifacts (describes the Informational Deployment folders)
1134         private Map<String, ArtifactsInfo> componentInstancesArtifacts;        //artifacts of the composed instances mapped by the resourceInstance normalized name (describes the Resources folder)
1135
1136         public ComponentTypeArtifacts() {
1137             componentArtifacts = new ArtifactsInfo();
1138             componentInstancesArtifacts = new HashMap<>();
1139         }
1140
1141         public ArtifactsInfo getComponentArtifacts() {
1142             return componentArtifacts;
1143         }
1144         public void setComponentArtifacts(ArtifactsInfo artifactsInfo) {
1145             this.componentArtifacts = artifactsInfo;
1146         }
1147         public Map<String, ArtifactsInfo> getComponentInstancesArtifacts() {
1148             return componentInstancesArtifacts;
1149         }
1150         public void setComponentInstancesArtifacts(Map<String, ArtifactsInfo> componentInstancesArtifacts) {
1151             this.componentInstancesArtifacts = componentInstancesArtifacts;
1152         }
1153
1154         public void addComponentInstancesArtifacts(String normalizedName, ArtifactsInfo artifactsInfo) {
1155             componentInstancesArtifacts.put(normalizedName, artifactsInfo);
1156         }
1157
1158     }
1159
1160     private class ComponentArtifacts {
1161         //artifacts of the component and CI's artifacts contained in it's composition (represents Informational, Deployment & Resource folders of main component)
1162         private ComponentTypeArtifacts mainTypeAndCIArtifacts;
1163         //artifacts of all component types mapped by their tosca name
1164         private Map<String, ComponentTypeArtifacts> componentTypeArtifacts;
1165
1166         public ComponentArtifacts(){
1167             mainTypeAndCIArtifacts = new ComponentTypeArtifacts();
1168             componentTypeArtifacts = new HashMap<>();
1169         }
1170
1171         public ComponentTypeArtifacts getMainTypeAndCIArtifacts() {
1172             return mainTypeAndCIArtifacts;
1173         }
1174
1175         public void setMainTypeAndCIArtifacts(ComponentTypeArtifacts componentInstanceArtifacts) {
1176             this.mainTypeAndCIArtifacts = componentInstanceArtifacts;
1177         }
1178
1179         public Map<String, ComponentTypeArtifacts> getComponentTypeArtifacts() {
1180             return componentTypeArtifacts;
1181         }
1182
1183         public void setComponentTypeArtifacts(Map<String, ComponentTypeArtifacts> componentTypeArtifacts) {
1184             this.componentTypeArtifacts = componentTypeArtifacts;
1185         }
1186     }
1187
1188     private class CsarDefinition {
1189         private ComponentArtifacts componentArtifacts;
1190
1191         // add list of tosca artifacts and meta describes CSAR zip root
1192
1193         public CsarDefinition(ComponentArtifacts componentArtifacts) {
1194             this.componentArtifacts = componentArtifacts;
1195         }
1196
1197         public ComponentArtifacts getComponentArtifacts() {
1198             return componentArtifacts;
1199         }
1200     }
1201
1202     /************************************ Artifacts Structure END******************************************************************/
1203
1204     private Either<CsarDefinition,ResponseFormat> collectComponentCsarDefinition(Component component){
1205         ComponentArtifacts componentArtifacts = new ComponentArtifacts();
1206         Component updatedComponent = component;
1207
1208         //get service to receive the AII artifacts uploaded to the service
1209         if (updatedComponent.getComponentType() == ComponentTypeEnum.SERVICE) {
1210             Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(updatedComponent.getUniqueId());
1211
1212             if(getServiceResponse.isRight()){
1213                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getServiceResponse.right().value());
1214                 return Either.right(componentsUtils.getResponseFormat(actionStatus));
1215             }
1216
1217             updatedComponent = getServiceResponse.left().value();
1218         }
1219
1220         //find the artifacts of the main component, it would have its composed instances artifacts in a separate folder
1221         ComponentTypeArtifacts componentInstanceArtifacts = new ComponentTypeArtifacts();
1222         ArtifactsInfo artifactsInfo = collectComponentArtifacts(updatedComponent);
1223         componentInstanceArtifacts.setComponentArtifacts(artifactsInfo);
1224         componentArtifacts.setMainTypeAndCIArtifacts(componentInstanceArtifacts);
1225
1226         Map<String,ComponentTypeArtifacts> resourceTypeArtifacts = componentArtifacts.getComponentTypeArtifacts();    //artifacts mapped by the component type(tosca name+version)
1227         //get the component instances
1228         List<ComponentInstance> componentInstances = updatedComponent.getComponentInstances();
1229         if (componentInstances!=null){
1230             for (ComponentInstance componentInstance:componentInstances){
1231                 //call recursive to find artifacts for all the path
1232                 Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts = collectComponentInstanceArtifacts(
1233                         updatedComponent, componentInstance, resourceTypeArtifacts, componentInstanceArtifacts);
1234                 if (collectComponentInstanceArtifacts.isRight()){
1235                     return Either.right(collectComponentInstanceArtifacts.right().value());
1236                 }
1237             }
1238         }
1239
1240         if(log.isDebugEnabled()){
1241             printResult(componentArtifacts,updatedComponent.getName());
1242         }
1243
1244         return Either.left(new CsarDefinition(componentArtifacts));
1245     }
1246
1247     private void printResult(ComponentArtifacts componentArtifacts, String name) {
1248         StringBuilder result = new StringBuilder();
1249         result.append("Artifacts of main component " + name + "\n");
1250         ComponentTypeArtifacts componentInstanceArtifacts = componentArtifacts.getMainTypeAndCIArtifacts();
1251         printArtifacts(componentInstanceArtifacts);
1252         result.append("Type Artifacts\n");
1253         for (Map.Entry<String, ComponentTypeArtifacts> typeArtifacts:componentArtifacts.getComponentTypeArtifacts().entrySet()){
1254             result.append("Folder " + typeArtifacts.getKey() + "\n");
1255             result.append(printArtifacts(typeArtifacts.getValue()));
1256         }
1257
1258         if(log.isDebugEnabled()){
1259             log.debug(result.toString());
1260         }
1261     }
1262
1263     private String printArtifacts(ComponentTypeArtifacts componentInstanceArtifacts) {
1264         StringBuilder result = new StringBuilder();
1265         ArtifactsInfo artifactsInfo = componentInstanceArtifacts.getComponentArtifacts();
1266         Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componentArtifacts = artifactsInfo.getArtifactsInfo();
1267         printArtifacts(componentArtifacts);
1268         result = result.append("Resources\n");
1269         for (Map.Entry<String, ArtifactsInfo> resourceInstance:componentInstanceArtifacts.getComponentInstancesArtifacts().entrySet()){
1270             result.append("Folder" + resourceInstance.getKey() + "\n");
1271             result.append(printArtifacts(resourceInstance.getValue().getArtifactsInfo()));
1272         }
1273
1274         return result.toString();
1275     }
1276
1277     private String printArtifacts(Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componetArtifacts) {
1278         StringBuilder result = new StringBuilder();
1279         for (Map.Entry<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactGroup:componetArtifacts.entrySet()){
1280             result.append("    " + artifactGroup.getKey().getType());
1281             for (Map.Entry<String, List<ArtifactDefinition>> groupArtifacts:artifactGroup.getValue().entrySet()){
1282                 result.append("        " + groupArtifacts.getKey());
1283                 for (ArtifactDefinition artifact:groupArtifacts.getValue()){
1284                     result.append("            " + artifact.getArtifactDisplayName());
1285                 }
1286             }
1287         }
1288
1289         return result.toString();
1290     }
1291
1292     private ComponentTypeArtifacts collectComponentTypeArtifacts(
1293         Component fetchedComponent
1294     ) {
1295         ArtifactsInfo componentArtifacts = collectComponentArtifacts(fetchedComponent);
1296         ComponentTypeArtifacts componentArtifactsInfo = new ComponentTypeArtifacts();
1297         if (componentArtifacts.isNotEmpty()) {
1298             componentArtifactsInfo.setComponentArtifacts(componentArtifacts);
1299         }
1300         return componentArtifactsInfo;
1301     }
1302
1303     private Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts(Component parentComponent,ComponentInstance componentInstance,
1304             Map<String, ComponentTypeArtifacts> resourcesTypeArtifacts,ComponentTypeArtifacts instanceArtifactsLocation) {
1305         //1. get the component instance component
1306         String componentUid;
1307         if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
1308                         componentUid = componentInstance.getSourceModelUid();
1309                 }
1310                 else {
1311                         componentUid = componentInstance.getComponentUid();
1312                 }
1313         Either<Component, StorageOperationStatus> component = toscaOperationFacade.getToscaElement(componentUid);
1314                 if (component.isRight()) {
1315             log.error("Failed to fetch resource with id {} for instance {}",componentUid, parentComponent.getUUID());
1316             return Either.right(componentsUtils.getResponseFormat(ActionStatus.ASSET_NOT_FOUND_DURING_CSAR_CREATION,
1317                     parentComponent.getComponentType().getValue(), parentComponent.getUUID(),
1318                     componentInstance.getOriginType().getComponentType().getValue(), componentUid));
1319         }
1320                 Component fetchedComponent = component.left().value();
1321
1322         //2. fill the artifacts for the current component parent type
1323         String toscaComponentName =
1324             componentInstance.getToscaComponentName() + "_v" + componentInstance.getComponentVersion();
1325
1326         // if there are no artifacts for this component type we need to fetch and build them
1327         ComponentTypeArtifacts componentParentArtifacts = Optional
1328             .ofNullable(resourcesTypeArtifacts.get(toscaComponentName))
1329             .orElseGet(() -> collectComponentTypeArtifacts(fetchedComponent));
1330
1331         if (componentParentArtifacts.getComponentArtifacts().isNotEmpty()) {
1332             resourcesTypeArtifacts.put(toscaComponentName, componentParentArtifacts);
1333         }
1334
1335         //3. find the artifacts specific to the instance
1336         Map<String, List<ArtifactDefinition>> componentInstanceSpecificInformationalArtifacts =
1337                 getComponentInstanceSpecificArtifacts(componentInstance.getArtifacts(),
1338                         componentParentArtifacts.getComponentArtifacts().getArtifactsInfo(), ArtifactGroupTypeEnum.INFORMATIONAL);
1339         Map<String, List<ArtifactDefinition>> componentInstanceSpecificDeploymentArtifacts =
1340                 getComponentInstanceSpecificArtifacts(componentInstance.getDeploymentArtifacts(),
1341                         componentParentArtifacts.getComponentArtifacts().getArtifactsInfo(), ArtifactGroupTypeEnum.DEPLOYMENT);
1342
1343         //4. add the instances artifacts to the component type
1344         ArtifactsInfo artifactsInfo = new ArtifactsInfo();
1345         if (!componentInstanceSpecificInformationalArtifacts.isEmpty()){
1346             artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.INFORMATIONAL, componentInstanceSpecificInformationalArtifacts);
1347         }
1348         if (!componentInstanceSpecificDeploymentArtifacts.isEmpty()){
1349             artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, componentInstanceSpecificDeploymentArtifacts);
1350         }
1351         if (!artifactsInfo.isEmpty()){
1352             instanceArtifactsLocation.addComponentInstancesArtifacts(componentInstance.getNormalizedName(), artifactsInfo);
1353         }
1354
1355         //5. do the same for all the component instances
1356         List<ComponentInstance> componentInstances = fetchedComponent.getComponentInstances();
1357         if (componentInstances!=null){
1358             for (ComponentInstance childComponentInstance:componentInstances){
1359                 Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts = collectComponentInstanceArtifacts(
1360                         fetchedComponent, childComponentInstance, resourcesTypeArtifacts, componentParentArtifacts);
1361                 if (collectComponentInstanceArtifacts.isRight()){
1362                     return collectComponentInstanceArtifacts;
1363                 }
1364             }
1365         }
1366
1367         return Either.left(true);
1368     }
1369
1370     public String getVersionFirstThreeOctets() {
1371         return versionFirstThreeOctets;
1372     }
1373
1374     public void setVersionFirstThreeOctets(String versionFirstThreeOctetes) {
1375         this.versionFirstThreeOctets = versionFirstThreeOctetes;
1376     }
1377     private Map<String, List<ArtifactDefinition>> getComponentInstanceSpecificArtifacts(Map<String, ArtifactDefinition> componentArtifacts,
1378             Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componentTypeArtifacts, ArtifactGroupTypeEnum artifactGroupTypeEnum) {
1379         Map<String, List<ArtifactDefinition>> parentArtifacts = componentTypeArtifacts.get(artifactGroupTypeEnum);    //the artfiacts of the component itself and not the instance
1380
1381         Map<String, List<ArtifactDefinition>> artifactsByTypeOfComponentInstance = new HashMap<>();
1382         if (componentArtifacts!=null){
1383             for (ArtifactDefinition artifact:componentArtifacts.values()){
1384                 List<ArtifactDefinition> parentArtifactsByType = null;
1385                 if (parentArtifacts!=null){
1386                     parentArtifactsByType = parentArtifacts.get(artifact.getArtifactType());
1387                 }
1388                 //the artifact is of instance
1389                 if (parentArtifactsByType == null || !parentArtifactsByType.contains(artifact)){
1390                     List<ArtifactDefinition> typeArtifacts = artifactsByTypeOfComponentInstance.get(artifact.getArtifactType());
1391                     if (typeArtifacts == null){
1392                         typeArtifacts = new ArrayList<>();
1393                         artifactsByTypeOfComponentInstance.put(artifact.getArtifactType(), typeArtifacts);
1394                     }
1395                     typeArtifacts.add(artifact);
1396                 }
1397             }
1398         }
1399
1400         return artifactsByTypeOfComponentInstance;
1401     }
1402
1403     private ArtifactsInfo collectComponentArtifacts(Component component) {
1404         Map<String, ArtifactDefinition> informationalArtifacts = component.getArtifacts();
1405         Map<String, List<ArtifactDefinition>> informationalArtifactsByType = collectGroupArtifacts(informationalArtifacts);
1406         Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
1407         Map<String, List<ArtifactDefinition>> deploymentArtifactsByType = collectGroupArtifacts(deploymentArtifacts);
1408                 Map<String, ArtifactDefinition> interfaceOperationArtifacts =
1409                                 OperationArtifactUtil.getDistinctInterfaceOperationArtifactsByName(component);
1410                 Map<String, List<ArtifactDefinition>> interfaceOperationArtifactsByType = collectGroupArtifacts(
1411                                 interfaceOperationArtifacts);
1412         ArtifactsInfo artifactsInfo = new ArtifactsInfo();
1413         if (!informationalArtifactsByType.isEmpty()){
1414             artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.INFORMATIONAL, informationalArtifactsByType);
1415         }
1416         if (!deploymentArtifactsByType.isEmpty() ){
1417             artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, deploymentArtifactsByType);
1418                 }
1419                 //Add component interface operation artifacts
1420                 if(MapUtils.isNotEmpty(interfaceOperationArtifacts)) {
1421                         artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, interfaceOperationArtifactsByType);
1422         }
1423
1424         return artifactsInfo;
1425     }
1426
1427     private Map<String, List<ArtifactDefinition>> collectGroupArtifacts(
1428             final Map<String, ArtifactDefinition> componentArtifacts) {
1429         final Map<String, List<ArtifactDefinition>> artifactsByType = new HashMap<>();
1430         for (final ArtifactDefinition artifact : componentArtifacts.values()) {
1431             if (artifact.getArtifactUUID() != null) {
1432                 artifactsByType.putIfAbsent(artifact.getArtifactType(), new ArrayList<>());
1433                 final List<ArtifactDefinition> typeArtifacts = artifactsByType.get(artifact.getArtifactType());
1434                 typeArtifacts.add(artifact);
1435             }
1436         }
1437         return artifactsByType;
1438     }
1439 }