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