2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.openecomp.sdc.be.tosca;
23 import fj.data.Either;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.EnumMap;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.List;
32 import java.util.Map.Entry;
33 import java.util.Optional;
35 import java.util.regex.Pattern;
36 import java.util.zip.ZipEntry;
37 import java.util.zip.ZipOutputStream;
40 import org.apache.commons.codec.binary.Base64;
41 import org.apache.commons.collections.MapUtils;
42 import org.apache.commons.io.output.ByteArrayOutputStream;
43 import org.apache.commons.lang3.tuple.ImmutablePair;
44 import org.openecomp.sdc.be.components.impl.ImportUtils;
45 import org.openecomp.sdc.be.config.ArtifactConfigManager;
46 import org.openecomp.sdc.be.config.ArtifactConfiguration;
47 import org.openecomp.sdc.be.config.ComponentType;
48 import org.openecomp.sdc.be.config.ConfigurationManager;
49 import org.openecomp.sdc.be.dao.api.ActionStatus;
50 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
51 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
52 import org.openecomp.sdc.be.impl.ComponentsUtils;
53 import org.openecomp.sdc.be.model.ArtifactDefinition;
54 import org.openecomp.sdc.be.model.Component;
55 import org.openecomp.sdc.be.model.ComponentInstance;
56 import org.openecomp.sdc.be.model.Service;
57 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
58 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
59 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
60 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
61 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
62 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
63 import org.openecomp.sdc.common.log.enums.StatusCode;
64 import org.openecomp.sdc.common.log.wrappers.Logger;
65 import org.openecomp.sdc.common.util.GeneralUtility;
66 import org.openecomp.sdc.common.util.ValidationUtils;
67 import org.openecomp.sdc.exception.ResponseFormat;
68 import org.springframework.beans.factory.annotation.Autowired;
70 @org.springframework.stereotype.Component("csar-utils")
71 public class CsarUtils {
73 public static final String ARTIFACTS_PATH = "Artifacts/";
74 public static final String ARTIFACTS = "Artifacts";
75 public static final String ARTIFACT_CREATED_FROM_CSAR = "Artifact created from csar";
76 private static final Logger log = Logger.getLogger(CsarUtils.class);
77 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(CsarUtils.class.getName());
78 private static final String PATH_DELIMITER = "/";
79 private static final String CSAR_META_VERSION = "1.0";
80 private static final String CSAR_META_PATH_FILE_NAME = "csar.meta";
81 private static final String DEFINITION = "Definitions";
82 private static final String DEL_PATTERN = "([/\\\\]+)";
83 private static final String WORD_PATTERN = "\\w\\_\\@\\-\\.\\s]+)";
84 public static final String VALID_ENGLISH_ARTIFACT_NAME = "([" + WORD_PATTERN;
85 public static final String VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN = ARTIFACTS + DEL_PATTERN +
86 // Artifact Group (i.e Deployment/Informational)
87 VALID_ENGLISH_ARTIFACT_NAME + DEL_PATTERN +
89 VALID_ENGLISH_ARTIFACT_NAME + DEL_PATTERN +
90 // Artifact Any File Name
92 public static final String SERVICE_TEMPLATE_PATH_PATTERN = DEFINITION + DEL_PATTERN +
93 // Service Template File Name
94 VALID_ENGLISH_ARTIFACT_NAME;
95 private static final String VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS = "([\\d" + WORD_PATTERN;
96 private static final String VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN =
97 ARTIFACTS + DEL_PATTERN + ImportUtils.Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX + VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN
98 + VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN + VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN
99 + VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS;
100 private static final String BLOCK_0_TEMPLATE = "SDC-TOSCA-Meta-File-Version: %s\nSDC-TOSCA-Definitions-Version: %s\n";
102 private final ToscaOperationFacade toscaOperationFacade;
103 private final ComponentsUtils componentsUtils;
104 private final MapFromModelCsarGeneratorService mapFromModelCsarGeneratorService;
107 public CsarUtils(final ToscaOperationFacade toscaOperationFacade,
108 final ComponentsUtils componentsUtils,
109 final MapFromModelCsarGeneratorService mapFromModelCsarGeneratorService) {
110 this.toscaOperationFacade = toscaOperationFacade;
111 this.componentsUtils = componentsUtils;
112 this.mapFromModelCsarGeneratorService = mapFromModelCsarGeneratorService;
116 * Extracts artifacts of VFCs from CSAR
119 * @return Map of <String, List<ArtifactDefinition>> the contains Lists of artifacts according vfcToscaNamespace
121 public static Map<String, List<ArtifactDefinition>> extractVfcsArtifactsFromCsar(Map<String, byte[]> csar) {
122 Map<String, List<ArtifactDefinition>> artifacts = new HashMap<>();
124 log.debug("************* Going to extract VFCs artifacts from Csar. ");
125 Map<String, Set<List<String>>> collectedWarningMessages = new HashMap<>();
126 csar.entrySet().stream()
127 // filter CSAR entry by node type artifact path
128 .filter(e -> Pattern.compile(VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches())
129 // extract ArtifactDefinition from CSAR entry for each entry with matching artifact path
130 .forEach(e -> extractVfcArtifact(e, collectedWarningMessages).ifPresent(ip -> addExtractedVfcArtifact(ip, artifacts)));
131 // add counter suffix to artifact labels
132 handleWarningMessages(collectedWarningMessages);
138 * Print warnings to log
140 * @param collectedWarningMessages
142 public static void handleWarningMessages(Map<String, Set<List<String>>> collectedWarningMessages) {
143 collectedWarningMessages.entrySet().stream()
145 .forEach(e -> e.getValue().stream()
146 // add each warning message to log
147 .forEach(args -> log.warn(e.getKey(), args.toArray())));
150 private static void addExtractedVfcArtifact(ImmutablePair<String, ArtifactDefinition> extractedVfcArtifact,
151 Map<String, List<ArtifactDefinition>> artifacts) {
152 String vfcToscaNamespace = extractedVfcArtifact.getKey();
153 artifacts.computeIfAbsent(vfcToscaNamespace, k -> new ArrayList<>());
154 artifacts.get(vfcToscaNamespace).add(extractedVfcArtifact.getValue());
157 private static Optional<ImmutablePair<String, ArtifactDefinition>> extractVfcArtifact(Entry<String, byte[]> entry,
158 Map<String, Set<List<String>>> collectedWarningMessages) {
159 String[] parsedCsarArtifactPath = entry.getKey().split(PATH_DELIMITER);
160 String groupType = parsedCsarArtifactPath[2].toUpperCase();
161 return detectArtifactGroupType(groupType, collectedWarningMessages).left()
162 .map(buildArtifactDefinitionFromCsarArtifactPath(entry, collectedWarningMessages, parsedCsarArtifactPath))
163 .either(ad -> Optional.of(new ImmutablePair<>(parsedCsarArtifactPath[1], ad)), b -> Optional.empty());
166 private static Either<ArtifactGroupTypeEnum, Boolean> detectArtifactGroupType(String groupType,
167 Map<String, Set<List<String>>> collectedWarningMessages) {
168 Either<ArtifactGroupTypeEnum, Boolean> result;
170 ArtifactGroupTypeEnum artifactGroupType = ArtifactGroupTypeEnum.findType(groupType.toUpperCase());
171 if (artifactGroupType == null || (artifactGroupType != ArtifactGroupTypeEnum.INFORMATIONAL
172 && artifactGroupType != ArtifactGroupTypeEnum.DEPLOYMENT)) {
173 String warningMessage = "Warning - unrecognized artifact group type {} was received.";
174 List<String> messageArguments = new ArrayList<>();
175 messageArguments.add(groupType);
176 if (!collectedWarningMessages.containsKey(warningMessage)) {
177 Set<List<String>> messageArgumentLists = new HashSet<>();
178 messageArgumentLists.add(messageArguments);
179 collectedWarningMessages.put(warningMessage, messageArgumentLists);
181 collectedWarningMessages.get(warningMessage).add(messageArguments);
183 result = Either.right(false);
185 result = Either.left(artifactGroupType);
187 } catch (Exception e) {
188 log.debug("detectArtifactGroupType failed with exception", e);
189 result = Either.right(false);
194 private static F<ArtifactGroupTypeEnum, ArtifactDefinition> buildArtifactDefinitionFromCsarArtifactPath(Entry<String, byte[]> entry,
195 Map<String, Set<List<String>>> collectedWarningMessages,
196 String[] parsedCsarArtifactPath) {
197 return artifactGroupType -> {
198 ArtifactDefinition artifact;
199 artifact = new ArtifactDefinition();
200 artifact.setArtifactGroupType(artifactGroupType);
201 artifact.setArtifactType(
202 detectArtifactTypeVFC(artifactGroupType, parsedCsarArtifactPath[3], parsedCsarArtifactPath[1], collectedWarningMessages));
203 artifact.setArtifactName(ValidationUtils.normalizeFileName(parsedCsarArtifactPath[parsedCsarArtifactPath.length - 1]));
204 artifact.setPayloadData(Base64.encodeBase64String(entry.getValue()));
205 artifact.setArtifactDisplayName(
206 artifact.getArtifactName().lastIndexOf('.') > 0 ? artifact.getArtifactName().substring(0, artifact.getArtifactName().lastIndexOf('.'))
207 : artifact.getArtifactName());
208 artifact.setArtifactLabel(ValidationUtils.normalizeArtifactLabel(artifact.getArtifactName()));
209 artifact.setDescription(ARTIFACT_CREATED_FROM_CSAR);
210 artifact.setIsFromCsar(true);
211 artifact.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(entry.getValue()));
217 * This method checks the artifact GroupType & Artifact Type. <br> if there is any problem warning messages are added to collectedWarningMessages
219 * @param artifactPath
220 * @param collectedWarningMessages
223 public static Either<NonMetaArtifactInfo, Boolean> validateNonMetaArtifact(String artifactPath, byte[] payloadData,
224 Map<String, Set<List<String>>> collectedWarningMessages) {
226 String[] parsedArtifactPath = artifactPath.split(PATH_DELIMITER);
227 String groupType = parsedArtifactPath[1];
228 String receivedTypeName = parsedArtifactPath[2];
229 String artifactFileNameType = parsedArtifactPath[3];
230 return detectArtifactGroupType(groupType, collectedWarningMessages).left().bind(artifactGroupType -> {
231 String artifactType = detectArtifactTypeVF(artifactGroupType, receivedTypeName, collectedWarningMessages);
233 .left(new NonMetaArtifactInfo(artifactFileNameType, artifactPath, artifactType, artifactGroupType, payloadData, null, true));
235 } catch (Exception e) {
236 log.debug("detectArtifactGroupType failed with exception", e);
237 return Either.right(false);
241 private static String detectArtifactTypeVFC(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName, String parentVfName,
242 Map<String, Set<List<String>>> collectedWarningMessages) {
243 String warningMessage = "Warning - artifact type {} that was provided for VFC {} is not recognized.";
244 return detectArtifactType(artifactGroupType, receivedTypeName, warningMessage, collectedWarningMessages, parentVfName);
247 private static String detectArtifactTypeVF(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName,
248 Map<String, Set<List<String>>> collectedWarningMessages) {
249 String warningMessage = "Warning - artifact type {} that was provided for VF is not recognized.";
250 return detectArtifactType(artifactGroupType, receivedTypeName, warningMessage, collectedWarningMessages);
253 private static String detectArtifactType(final ArtifactGroupTypeEnum artifactGroupType, final String receivedTypeName,
254 final String warningMessage, final Map<String, Set<List<String>>> collectedWarningMessages,
255 final String... arguments) {
256 final ArtifactConfiguration artifactConfiguration = ArtifactConfigManager.getInstance()
257 .find(receivedTypeName, artifactGroupType, ComponentType.RESOURCE).orElse(null);
258 if (artifactConfiguration == null) {
259 final List<String> messageArguments = new ArrayList<>();
260 messageArguments.add(receivedTypeName);
261 messageArguments.addAll(Arrays.asList(arguments));
262 if (!collectedWarningMessages.containsKey(warningMessage)) {
263 final Set<List<String>> messageArgumentLists = new HashSet<>();
264 messageArgumentLists.add(messageArguments);
265 collectedWarningMessages.put(warningMessage, messageArgumentLists);
267 collectedWarningMessages.get(warningMessage).add(messageArguments);
270 return artifactConfiguration == null ? ArtifactTypeEnum.OTHER.getType() : receivedTypeName;
276 * @param isInCertificationRequest
279 public Either<byte[], ResponseFormat> createCsar(final Component component, final boolean getFromCS, final boolean isInCertificationRequest) {
281 .log(LoggerSupportabilityActions.GENERATE_CSAR, StatusCode.STARTED, "Starting to create Csar for component {} ", component.getName());
282 final String toscaConformanceLevel = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel();
283 final byte[] csarBlock0Byte = createCsarBlock0(CSAR_META_VERSION, toscaConformanceLevel).getBytes();
285 return generateCsarZip(csarBlock0Byte,
286 isAsdPackage(component), component, getFromCS, isInCertificationRequest).left().map(responseFormat -> {
288 .log(LoggerSupportabilityActions.GENERATE_CSAR, StatusCode.COMPLETE, "Ended create Csar for component {} ", component.getName());
289 return responseFormat;
293 private boolean isAsdPackage(final Component component) {
294 final Either<CsarDefinition, ResponseFormat> collectedComponentCsarDefinition = collectComponentCsarDefinition(component);
295 if (collectedComponentCsarDefinition.isLeft()) {
296 final ComponentArtifacts componentArtifacts = collectedComponentCsarDefinition.left().value().getComponentArtifacts();
297 if (componentArtifacts != null) {
298 final ComponentTypeArtifacts mainTypeAndCIArtifacts = componentArtifacts.getMainTypeAndCIArtifacts();
299 if (mainTypeAndCIArtifacts != null) {
300 final ArtifactsInfo artifactsInfo = mainTypeAndCIArtifacts.getComponentArtifacts();
301 if (artifactsInfo != null) {
302 final Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactsInfosMap = artifactsInfo.getArtifactsInfo();
303 if (MapUtils.isNotEmpty(artifactsInfosMap) && artifactsInfosMap.containsKey(ArtifactGroupTypeEnum.DEPLOYMENT)) {
304 return artifactsInfosMap.get(ArtifactGroupTypeEnum.DEPLOYMENT).containsKey(ArtifactTypeEnum.ASD_PACKAGE.getType());
313 private Either<byte[], ResponseFormat> generateCsarZip(byte[] csarBlock0Byte,
314 boolean isAsdPackage,
317 boolean isInCertificationRequest) {
318 try (final ByteArrayOutputStream out = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(out)) {
319 zip.putNextEntry(new ZipEntry(CSAR_META_PATH_FILE_NAME));
320 zip.write(csarBlock0Byte);
321 Either<ZipOutputStream, ResponseFormat> populateZip = mapFromModelCsarGeneratorService.generateCsarZip(
322 component, getFromCS, zip, isInCertificationRequest, isAsdPackage);
323 if (populateZip.isRight()) {
324 log.debug("Failed to populate CSAR zip file {}. Please fix DB table accordingly ", populateZip.right().value());
325 return Either.right(populateZip.right().value());
328 return Either.left(out.toByteArray());
329 } catch (IOException e) {
330 log.debug("Failed with IOexception to create CSAR zip for component {}. Please fix DB table accordingly ", component.getUniqueId(), e);
331 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
332 return Either.right(responseFormat);
336 private String createCsarBlock0(String metaFileVersion, String toscaConformanceLevel) {
337 return String.format(BLOCK_0_TEMPLATE, metaFileVersion, toscaConformanceLevel);
340 /************************************ Artifacts Structure END******************************************************************/
342 private Either<CsarDefinition, ResponseFormat> collectComponentCsarDefinition(Component component) {
343 ComponentArtifacts componentArtifacts = new ComponentArtifacts();
344 Component updatedComponent = component;
346 //get service to receive the AII artifacts uploaded to the service
347 if (updatedComponent.getComponentType() == ComponentTypeEnum.SERVICE) {
348 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(updatedComponent.getUniqueId());
350 if (getServiceResponse.isRight()) {
351 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getServiceResponse.right().value());
352 return Either.right(componentsUtils.getResponseFormat(actionStatus));
355 updatedComponent = getServiceResponse.left().value();
358 //find the artifacts of the main component, it would have its composed instances artifacts in a separate folder
359 ComponentTypeArtifacts componentInstanceArtifacts = new ComponentTypeArtifacts();
360 ArtifactsInfo artifactsInfo = collectComponentArtifacts(updatedComponent);
361 componentInstanceArtifacts.setComponentArtifacts(artifactsInfo);
362 componentArtifacts.setMainTypeAndCIArtifacts(componentInstanceArtifacts);
364 Map<String, ComponentTypeArtifacts> resourceTypeArtifacts = componentArtifacts
365 .getComponentTypeArtifacts(); //artifacts mapped by the component type(tosca name+version)
366 //get the component instances
367 List<ComponentInstance> componentInstances = updatedComponent.getComponentInstances();
368 if (componentInstances != null) {
369 for (ComponentInstance componentInstance : componentInstances) {
370 //call recursive to find artifacts for all the path
371 Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts = collectComponentInstanceArtifacts(
372 updatedComponent, componentInstance, resourceTypeArtifacts, componentInstanceArtifacts);
373 if (collectComponentInstanceArtifacts.isRight()) {
374 return Either.right(collectComponentInstanceArtifacts.right().value());
379 if (log.isDebugEnabled()) {
380 printResult(componentArtifacts, updatedComponent.getName());
383 return Either.left(new CsarDefinition(componentArtifacts));
386 private void printResult(ComponentArtifacts componentArtifacts, String name) {
387 StringBuilder result = new StringBuilder();
388 result.append("Artifacts of main component " + name + "\n");
389 ComponentTypeArtifacts componentInstanceArtifacts = componentArtifacts.getMainTypeAndCIArtifacts();
390 printArtifacts(componentInstanceArtifacts);
391 result.append("Type Artifacts\n");
392 for (Entry<String, ComponentTypeArtifacts> typeArtifacts : componentArtifacts.getComponentTypeArtifacts().entrySet()) {
393 result.append("Folder " + typeArtifacts.getKey() + "\n");
394 result.append(printArtifacts(typeArtifacts.getValue()));
397 if (log.isDebugEnabled()) {
398 log.debug(result.toString());
402 /************************************ Artifacts Structure ******************************************************************/
404 private String printArtifacts(ComponentTypeArtifacts componentInstanceArtifacts) {
405 StringBuilder result = new StringBuilder();
406 ArtifactsInfo artifactsInfo = componentInstanceArtifacts.getComponentArtifacts();
407 Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componentArtifacts = artifactsInfo.getArtifactsInfo();
408 printArtifacts(componentArtifacts);
409 result = result.append("Resources\n");
410 for (Entry<String, ArtifactsInfo> resourceInstance : componentInstanceArtifacts.getComponentInstancesArtifacts().entrySet()) {
411 result.append("Folder" + resourceInstance.getKey() + "\n");
412 result.append(printArtifacts(resourceInstance.getValue().getArtifactsInfo()));
415 return result.toString();
418 private String printArtifacts(Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componetArtifacts) {
419 StringBuilder result = new StringBuilder();
420 for (Entry<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactGroup : componetArtifacts.entrySet()) {
421 result.append(" " + artifactGroup.getKey().getType());
422 for (Entry<String, List<ArtifactDefinition>> groupArtifacts : artifactGroup.getValue().entrySet()) {
423 result.append(" " + groupArtifacts.getKey());
424 for (ArtifactDefinition artifact : groupArtifacts.getValue()) {
425 result.append(" " + artifact.getArtifactDisplayName());
430 return result.toString();
433 private ComponentTypeArtifacts collectComponentTypeArtifacts(Component fetchedComponent) {
434 ArtifactsInfo componentArtifacts = collectComponentArtifacts(fetchedComponent);
435 ComponentTypeArtifacts componentArtifactsInfo = new ComponentTypeArtifacts();
436 if (componentArtifacts.isNotEmpty()) {
437 componentArtifactsInfo.setComponentArtifacts(componentArtifacts);
439 return componentArtifactsInfo;
442 private Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts(Component parentComponent, ComponentInstance componentInstance,
443 Map<String, ComponentTypeArtifacts> resourcesTypeArtifacts,
444 ComponentTypeArtifacts instanceArtifactsLocation) {
445 //1. get the component instance component
447 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
448 componentUid = componentInstance.getSourceModelUid();
450 componentUid = componentInstance.getComponentUid();
452 Either<Component, StorageOperationStatus> component = toscaOperationFacade.getToscaElement(componentUid);
453 if (component.isRight()) {
454 log.error("Failed to fetch resource with id {} for instance {}", componentUid, parentComponent.getUUID());
455 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ASSET_NOT_FOUND_DURING_CSAR_CREATION,
456 parentComponent.getComponentType().getValue(), parentComponent.getUUID(),
457 componentInstance.getOriginType().getComponentType().getValue(), componentUid));
459 Component fetchedComponent = component.left().value();
461 //2. fill the artifacts for the current component parent type
462 String toscaComponentName =
463 componentInstance.getToscaComponentName() + "_v" + componentInstance.getComponentVersion();
465 // if there are no artifacts for this component type we need to fetch and build them
466 ComponentTypeArtifacts componentParentArtifacts = Optional
467 .ofNullable(resourcesTypeArtifacts.get(toscaComponentName))
468 .orElseGet(() -> collectComponentTypeArtifacts(fetchedComponent));
470 if (componentParentArtifacts.getComponentArtifacts().isNotEmpty()) {
471 resourcesTypeArtifacts.put(toscaComponentName, componentParentArtifacts);
474 //3. find the artifacts specific to the instance
475 Map<String, List<ArtifactDefinition>> componentInstanceSpecificInformationalArtifacts =
476 getComponentInstanceSpecificArtifacts(componentInstance.getArtifacts(),
477 componentParentArtifacts.getComponentArtifacts().getArtifactsInfo(), ArtifactGroupTypeEnum.INFORMATIONAL);
478 Map<String, List<ArtifactDefinition>> componentInstanceSpecificDeploymentArtifacts =
479 getComponentInstanceSpecificArtifacts(componentInstance.getDeploymentArtifacts(),
480 componentParentArtifacts.getComponentArtifacts().getArtifactsInfo(), ArtifactGroupTypeEnum.DEPLOYMENT);
482 //4. add the instances artifacts to the component type
483 ArtifactsInfo artifactsInfo = new ArtifactsInfo();
484 if (!componentInstanceSpecificInformationalArtifacts.isEmpty()) {
485 artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.INFORMATIONAL, componentInstanceSpecificInformationalArtifacts);
487 if (!componentInstanceSpecificDeploymentArtifacts.isEmpty()) {
488 artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, componentInstanceSpecificDeploymentArtifacts);
490 if (!artifactsInfo.isEmpty()) {
491 instanceArtifactsLocation.addComponentInstancesArtifacts(componentInstance.getNormalizedName(), artifactsInfo);
494 //5. do the same for all the component instances
495 List<ComponentInstance> componentInstances = fetchedComponent.getComponentInstances();
496 if (componentInstances != null) {
497 for (ComponentInstance childComponentInstance : componentInstances) {
498 Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts = collectComponentInstanceArtifacts(
499 fetchedComponent, childComponentInstance, resourcesTypeArtifacts, componentParentArtifacts);
500 if (collectComponentInstanceArtifacts.isRight()) {
501 return collectComponentInstanceArtifacts;
506 return Either.left(true);
509 private Map<String, List<ArtifactDefinition>> getComponentInstanceSpecificArtifacts(Map<String, ArtifactDefinition> componentArtifacts,
510 Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componentTypeArtifacts,
511 ArtifactGroupTypeEnum artifactGroupTypeEnum) {
512 Map<String, List<ArtifactDefinition>> parentArtifacts = componentTypeArtifacts
513 .get(artifactGroupTypeEnum); //the artfiacts of the component itself and not the instance
515 Map<String, List<ArtifactDefinition>> artifactsByTypeOfComponentInstance = new HashMap<>();
516 if (componentArtifacts != null) {
517 for (ArtifactDefinition artifact : componentArtifacts.values()) {
518 List<ArtifactDefinition> parentArtifactsByType = null;
519 if (parentArtifacts != null) {
520 parentArtifactsByType = parentArtifacts.get(artifact.getArtifactType());
522 //the artifact is of instance
523 if (parentArtifactsByType == null || !parentArtifactsByType.contains(artifact)) {
524 List<ArtifactDefinition> typeArtifacts = artifactsByTypeOfComponentInstance.get(artifact.getArtifactType());
525 if (typeArtifacts == null) {
526 typeArtifacts = new ArrayList<>();
527 artifactsByTypeOfComponentInstance.put(artifact.getArtifactType(), typeArtifacts);
529 typeArtifacts.add(artifact);
534 return artifactsByTypeOfComponentInstance;
537 private ArtifactsInfo collectComponentArtifacts(Component component) {
538 Map<String, ArtifactDefinition> informationalArtifacts = component.getArtifacts();
539 Map<String, List<ArtifactDefinition>> informationalArtifactsByType = collectGroupArtifacts(informationalArtifacts);
540 Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
541 Map<String, List<ArtifactDefinition>> deploymentArtifactsByType = collectGroupArtifacts(deploymentArtifacts);
542 ArtifactsInfo artifactsInfo = new ArtifactsInfo();
543 if (!informationalArtifactsByType.isEmpty()) {
544 artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.INFORMATIONAL, informationalArtifactsByType);
546 if (!deploymentArtifactsByType.isEmpty()) {
547 artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, deploymentArtifactsByType);
550 return artifactsInfo;
553 private Map<String, List<ArtifactDefinition>> collectGroupArtifacts(
554 final Map<String, ArtifactDefinition> componentArtifacts) {
555 final Map<String, List<ArtifactDefinition>> artifactsByType = new HashMap<>();
556 for (final ArtifactDefinition artifact : componentArtifacts.values()) {
557 if (artifact.getArtifactUUID() != null) {
558 artifactsByType.putIfAbsent(artifact.getArtifactType(), new ArrayList<>());
559 final List<ArtifactDefinition> typeArtifacts = artifactsByType.get(artifact.getArtifactType());
560 typeArtifacts.add(artifact);
563 return artifactsByType;
568 public static final class NonMetaArtifactInfo {
570 private final String path;
571 private final String artifactName;
572 private final String displayName;
573 private final String artifactLabel;
574 private final String artifactType;
575 private final ArtifactGroupTypeEnum artifactGroupType;
576 private final String payloadData;
577 private final String artifactChecksum;
578 private final boolean isFromCsar;
580 private String artifactUniqueId;
582 public NonMetaArtifactInfo(final String artifactName, final String path, final String artifactType,
583 final ArtifactGroupTypeEnum artifactGroupType, final byte[] payloadData, final String artifactUniqueId,
584 final boolean isFromCsar) {
586 this.isFromCsar = isFromCsar;
587 this.artifactName = ValidationUtils.normalizeFileName(artifactName);
588 this.artifactType = artifactType;
589 this.artifactGroupType = artifactGroupType;
590 final int pointIndex = artifactName.lastIndexOf('.');
591 if (pointIndex > 0) {
592 displayName = artifactName.substring(0, pointIndex);
594 displayName = artifactName;
596 this.artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactName);
597 if (payloadData == null) {
598 this.payloadData = null;
599 this.artifactChecksum = null;
601 this.payloadData = Base64.encodeBase64String(payloadData);
602 this.artifactChecksum = GeneralUtility.calculateMD5Base64EncodedByByteArray(payloadData);
604 this.artifactUniqueId = artifactUniqueId;
609 * The artifacts Definition saved by their structure
611 private class ArtifactsInfo {
612 //Key is the type of artifacts(Informational/Deployment)
614 //Value is a map between an artifact type and a list of all artifacts of this type
615 private Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactsInfoField;
617 public ArtifactsInfo() {
618 this.artifactsInfoField = new EnumMap<>(ArtifactGroupTypeEnum.class);
621 public Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> getArtifactsInfo() {
622 return artifactsInfoField;
625 public void addArtifactsToGroup(ArtifactGroupTypeEnum artifactGroup, Map<String, List<ArtifactDefinition>> artifactsDefinition) {
626 if (artifactsInfoField.get(artifactGroup) == null) {
627 artifactsInfoField.put(artifactGroup, artifactsDefinition);
629 Map<String, List<ArtifactDefinition>> artifactTypeEnumListMap = artifactsInfoField.get(artifactGroup);
630 artifactTypeEnumListMap.putAll(artifactsDefinition);
631 artifactsInfoField.put(artifactGroup, artifactTypeEnumListMap);
635 public boolean isEmpty() {
636 return artifactsInfoField.isEmpty();
639 public boolean isNotEmpty() {
645 * The artifacts of the component and of all its composed instances
647 private class ComponentTypeArtifacts {
649 private ArtifactsInfo componentArtifacts; //component artifacts (describes the Informational Deployment folders)
651 private Map<String, ArtifactsInfo> componentInstancesArtifacts; //artifacts of the composed instances mapped by the resourceInstance normalized name (describes the Resources folder)
653 public ComponentTypeArtifacts() {
654 componentArtifacts = new ArtifactsInfo();
655 componentInstancesArtifacts = new HashMap<>();
658 public ArtifactsInfo getComponentArtifacts() {
659 return componentArtifacts;
662 public void setComponentArtifacts(ArtifactsInfo artifactsInfo) {
663 this.componentArtifacts = artifactsInfo;
666 public Map<String, ArtifactsInfo> getComponentInstancesArtifacts() {
667 return componentInstancesArtifacts;
670 public void addComponentInstancesArtifacts(String normalizedName, ArtifactsInfo artifactsInfo) {
671 componentInstancesArtifacts.put(normalizedName, artifactsInfo);
675 private class ComponentArtifacts {
677 //artifacts of the component and CI's artifacts contained in it's composition (represents Informational, Deployment & Resource folders of main component)
678 private ComponentTypeArtifacts mainTypeAndCIArtifacts;
679 //artifacts of all component types mapped by their tosca name
680 private Map<String, ComponentTypeArtifacts> componentTypeArtifacts;
682 public ComponentArtifacts() {
683 mainTypeAndCIArtifacts = new ComponentTypeArtifacts();
684 componentTypeArtifacts = new HashMap<>();
687 public ComponentTypeArtifacts getMainTypeAndCIArtifacts() {
688 return mainTypeAndCIArtifacts;
691 public void setMainTypeAndCIArtifacts(ComponentTypeArtifacts componentInstanceArtifacts) {
692 this.mainTypeAndCIArtifacts = componentInstanceArtifacts;
695 public Map<String, ComponentTypeArtifacts> getComponentTypeArtifacts() {
696 return componentTypeArtifacts;
700 private class CsarDefinition {
702 private ComponentArtifacts componentArtifacts;
704 // add list of tosca artifacts and meta describes CSAR zip root
705 public CsarDefinition(ComponentArtifacts componentArtifacts) {
706 this.componentArtifacts = componentArtifacts;
709 public ComponentArtifacts getComponentArtifacts() {
710 return componentArtifacts;