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