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.ZipOutputStream;
39 import org.apache.commons.codec.binary.Base64;
40 import org.apache.commons.collections.MapUtils;
41 import org.apache.commons.io.output.ByteArrayOutputStream;
42 import org.apache.commons.lang3.tuple.ImmutablePair;
43 import org.openecomp.sdc.be.components.impl.ImportUtils;
44 import org.openecomp.sdc.be.config.ArtifactConfigManager;
45 import org.openecomp.sdc.be.config.ArtifactConfiguration;
46 import org.openecomp.sdc.be.config.ComponentType;
47 import org.openecomp.sdc.be.dao.api.ActionStatus;
48 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
49 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
50 import org.openecomp.sdc.be.impl.ComponentsUtils;
51 import org.openecomp.sdc.be.model.ArtifactDefinition;
52 import org.openecomp.sdc.be.model.Component;
53 import org.openecomp.sdc.be.model.ComponentInstance;
54 import org.openecomp.sdc.be.model.Service;
55 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
56 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
57 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
58 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
59 import org.openecomp.sdc.common.log.elements.LoggerSupportability;
60 import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions;
61 import org.openecomp.sdc.common.log.enums.StatusCode;
62 import org.openecomp.sdc.common.log.wrappers.Logger;
63 import org.openecomp.sdc.common.util.GeneralUtility;
64 import org.openecomp.sdc.common.util.ValidationUtils;
65 import org.openecomp.sdc.exception.ResponseFormat;
66 import org.springframework.beans.factory.annotation.Autowired;
68 @org.springframework.stereotype.Component("csar-utils")
69 public class CsarUtils {
71 public static final String ARTIFACTS_PATH = "Artifacts/";
72 public static final String ARTIFACTS = "Artifacts";
73 public static final String ARTIFACT_CREATED_FROM_CSAR = "Artifact created from csar";
74 private static final Logger log = Logger.getLogger(CsarUtils.class);
75 private static final LoggerSupportability loggerSupportability = LoggerSupportability.getLogger(CsarUtils.class.getName());
76 private static final String PATH_DELIMITER = "/";
77 private static final String DEFINITION = "Definitions";
78 private static final String DEL_PATTERN = "([/\\\\]+)";
79 private static final String WORD_PATTERN = "\\w\\_\\@\\-\\.\\s]+)";
80 public static final String VALID_ENGLISH_ARTIFACT_NAME = "([" + WORD_PATTERN;
81 public static final String VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN = ARTIFACTS + DEL_PATTERN +
82 // Artifact Group (i.e Deployment/Informational)
83 VALID_ENGLISH_ARTIFACT_NAME + DEL_PATTERN +
85 VALID_ENGLISH_ARTIFACT_NAME + DEL_PATTERN +
86 // Artifact Any File Name
88 public static final String SERVICE_TEMPLATE_PATH_PATTERN = DEFINITION + DEL_PATTERN +
89 // Service Template File Name
90 VALID_ENGLISH_ARTIFACT_NAME;
91 private static final String VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS = "([\\d" + WORD_PATTERN;
92 private static final String VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN =
93 ARTIFACTS + DEL_PATTERN + ImportUtils.Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX + VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN
94 + VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN + VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS + DEL_PATTERN
95 + VALID_ENGLISH_ARTIFACT_NAME_WITH_DIGITS;
97 private final ToscaOperationFacade toscaOperationFacade;
98 private final ComponentsUtils componentsUtils;
99 private final MapFromModelCsarGeneratorService mapFromModelCsarGeneratorService;
102 public CsarUtils(final ToscaOperationFacade toscaOperationFacade,
103 final ComponentsUtils componentsUtils,
104 final MapFromModelCsarGeneratorService mapFromModelCsarGeneratorService) {
105 this.toscaOperationFacade = toscaOperationFacade;
106 this.componentsUtils = componentsUtils;
107 this.mapFromModelCsarGeneratorService = mapFromModelCsarGeneratorService;
111 * Extracts artifacts of VFCs from CSAR
114 * @return Map of <String, List<ArtifactDefinition>> the contains Lists of artifacts according vfcToscaNamespace
116 public static Map<String, List<ArtifactDefinition>> extractVfcsArtifactsFromCsar(Map<String, byte[]> csar) {
117 Map<String, List<ArtifactDefinition>> artifacts = new HashMap<>();
119 log.debug("************* Going to extract VFCs artifacts from Csar. ");
120 Map<String, Set<List<String>>> collectedWarningMessages = new HashMap<>();
121 csar.entrySet().stream()
122 // filter CSAR entry by node type artifact path
123 .filter(e -> Pattern.compile(VFC_NODE_TYPE_ARTIFACTS_PATH_PATTERN).matcher(e.getKey()).matches())
124 // extract ArtifactDefinition from CSAR entry for each entry with matching artifact path
125 .forEach(e -> extractVfcArtifact(e, collectedWarningMessages).ifPresent(ip -> addExtractedVfcArtifact(ip, artifacts)));
126 // add counter suffix to artifact labels
127 handleWarningMessages(collectedWarningMessages);
133 * Print warnings to log
135 * @param collectedWarningMessages
137 public static void handleWarningMessages(Map<String, Set<List<String>>> collectedWarningMessages) {
138 collectedWarningMessages.entrySet().stream()
140 .forEach(e -> e.getValue().stream()
141 // add each warning message to log
142 .forEach(args -> log.warn(e.getKey(), args.toArray())));
145 private static void addExtractedVfcArtifact(ImmutablePair<String, ArtifactDefinition> extractedVfcArtifact,
146 Map<String, List<ArtifactDefinition>> artifacts) {
147 String vfcToscaNamespace = extractedVfcArtifact.getKey();
148 artifacts.computeIfAbsent(vfcToscaNamespace, k -> new ArrayList<>());
149 artifacts.get(vfcToscaNamespace).add(extractedVfcArtifact.getValue());
152 private static Optional<ImmutablePair<String, ArtifactDefinition>> extractVfcArtifact(Entry<String, byte[]> entry,
153 Map<String, Set<List<String>>> collectedWarningMessages) {
154 String[] parsedCsarArtifactPath = entry.getKey().split(PATH_DELIMITER);
155 String groupType = parsedCsarArtifactPath[2].toUpperCase();
156 return detectArtifactGroupType(groupType, collectedWarningMessages).left()
157 .map(buildArtifactDefinitionFromCsarArtifactPath(entry, collectedWarningMessages, parsedCsarArtifactPath))
158 .either(ad -> Optional.of(new ImmutablePair<>(parsedCsarArtifactPath[1], ad)), b -> Optional.empty());
161 private static Either<ArtifactGroupTypeEnum, Boolean> detectArtifactGroupType(String groupType,
162 Map<String, Set<List<String>>> collectedWarningMessages) {
163 Either<ArtifactGroupTypeEnum, Boolean> result;
165 ArtifactGroupTypeEnum artifactGroupType = ArtifactGroupTypeEnum.findType(groupType.toUpperCase());
166 if (artifactGroupType == null || (artifactGroupType != ArtifactGroupTypeEnum.INFORMATIONAL
167 && artifactGroupType != ArtifactGroupTypeEnum.DEPLOYMENT)) {
168 String warningMessage = "Warning - unrecognized artifact group type {} was received.";
169 List<String> messageArguments = new ArrayList<>();
170 messageArguments.add(groupType);
171 if (!collectedWarningMessages.containsKey(warningMessage)) {
172 Set<List<String>> messageArgumentLists = new HashSet<>();
173 messageArgumentLists.add(messageArguments);
174 collectedWarningMessages.put(warningMessage, messageArgumentLists);
176 collectedWarningMessages.get(warningMessage).add(messageArguments);
178 result = Either.right(false);
180 result = Either.left(artifactGroupType);
182 } catch (Exception e) {
183 log.debug("detectArtifactGroupType failed with exception", e);
184 result = Either.right(false);
189 private static F<ArtifactGroupTypeEnum, ArtifactDefinition> buildArtifactDefinitionFromCsarArtifactPath(Entry<String, byte[]> entry,
190 Map<String, Set<List<String>>> collectedWarningMessages,
191 String[] parsedCsarArtifactPath) {
192 return artifactGroupType -> {
193 ArtifactDefinition artifact;
194 artifact = new ArtifactDefinition();
195 artifact.setArtifactGroupType(artifactGroupType);
196 artifact.setArtifactType(
197 detectArtifactTypeVFC(artifactGroupType, parsedCsarArtifactPath[3], parsedCsarArtifactPath[1], collectedWarningMessages));
198 artifact.setArtifactName(ValidationUtils.normalizeFileName(parsedCsarArtifactPath[parsedCsarArtifactPath.length - 1]));
199 artifact.setPayloadData(Base64.encodeBase64String(entry.getValue()));
200 artifact.setArtifactDisplayName(
201 artifact.getArtifactName().lastIndexOf('.') > 0 ? artifact.getArtifactName().substring(0, artifact.getArtifactName().lastIndexOf('.'))
202 : artifact.getArtifactName());
203 artifact.setArtifactLabel(ValidationUtils.normalizeArtifactLabel(artifact.getArtifactName()));
204 artifact.setDescription(ARTIFACT_CREATED_FROM_CSAR);
205 artifact.setIsFromCsar(true);
206 artifact.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(entry.getValue()));
212 * This method checks the artifact GroupType & Artifact Type. <br> if there is any problem warning messages are added to collectedWarningMessages
214 * @param artifactPath
215 * @param collectedWarningMessages
218 public static Either<NonMetaArtifactInfo, Boolean> validateNonMetaArtifact(String artifactPath, byte[] payloadData,
219 Map<String, Set<List<String>>> collectedWarningMessages) {
221 String[] parsedArtifactPath = artifactPath.split(PATH_DELIMITER);
222 String groupType = parsedArtifactPath[1];
223 String receivedTypeName = parsedArtifactPath[2];
224 String artifactFileNameType = parsedArtifactPath[3];
225 return detectArtifactGroupType(groupType, collectedWarningMessages).left().bind(artifactGroupType -> {
226 String artifactType = detectArtifactTypeVF(artifactGroupType, receivedTypeName, collectedWarningMessages);
228 .left(new NonMetaArtifactInfo(artifactFileNameType, artifactPath, artifactType, artifactGroupType, payloadData, null, true));
230 } catch (Exception e) {
231 log.debug("detectArtifactGroupType failed with exception", e);
232 return Either.right(false);
236 private static String detectArtifactTypeVFC(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName, String parentVfName,
237 Map<String, Set<List<String>>> collectedWarningMessages) {
238 String warningMessage = "Warning - artifact type {} that was provided for VFC {} is not recognized.";
239 return detectArtifactType(artifactGroupType, receivedTypeName, warningMessage, collectedWarningMessages, parentVfName);
242 private static String detectArtifactTypeVF(ArtifactGroupTypeEnum artifactGroupType, String receivedTypeName,
243 Map<String, Set<List<String>>> collectedWarningMessages) {
244 String warningMessage = "Warning - artifact type {} that was provided for VF is not recognized.";
245 return detectArtifactType(artifactGroupType, receivedTypeName, warningMessage, collectedWarningMessages);
248 private static String detectArtifactType(final ArtifactGroupTypeEnum artifactGroupType, final String receivedTypeName,
249 final String warningMessage, final Map<String, Set<List<String>>> collectedWarningMessages,
250 final String... arguments) {
251 final ArtifactConfiguration artifactConfiguration = ArtifactConfigManager.getInstance()
252 .find(receivedTypeName, artifactGroupType, ComponentType.RESOURCE).orElse(null);
253 if (artifactConfiguration == null) {
254 final List<String> messageArguments = new ArrayList<>();
255 messageArguments.add(receivedTypeName);
256 messageArguments.addAll(Arrays.asList(arguments));
257 if (!collectedWarningMessages.containsKey(warningMessage)) {
258 final Set<List<String>> messageArgumentLists = new HashSet<>();
259 messageArgumentLists.add(messageArguments);
260 collectedWarningMessages.put(warningMessage, messageArgumentLists);
262 collectedWarningMessages.get(warningMessage).add(messageArguments);
265 return artifactConfiguration == null ? ArtifactTypeEnum.OTHER.getType() : receivedTypeName;
271 * @param isInCertificationRequest
274 public Either<byte[], ResponseFormat> createCsar(final Component component, final boolean getFromCS, final boolean isInCertificationRequest) {
276 .log(LoggerSupportabilityActions.GENERATE_CSAR, StatusCode.STARTED, "Starting to create Csar for component {} ", component.getName());
278 return generateCsarZip(isAsdPackage(component), component, getFromCS, isInCertificationRequest).left().map(responseFormat -> {
280 .log(LoggerSupportabilityActions.GENERATE_CSAR, StatusCode.COMPLETE, "Ended create Csar for component {} ", component.getName());
281 return responseFormat;
285 private boolean isAsdPackage(final Component component) {
286 final Either<CsarDefinition, ResponseFormat> collectedComponentCsarDefinition = collectComponentCsarDefinition(component);
287 if (collectedComponentCsarDefinition.isLeft()) {
288 final ComponentArtifacts componentArtifacts = collectedComponentCsarDefinition.left().value().getComponentArtifacts();
289 if (componentArtifacts != null) {
290 final ComponentTypeArtifacts mainTypeAndCIArtifacts = componentArtifacts.getMainTypeAndCIArtifacts();
291 if (mainTypeAndCIArtifacts != null) {
292 final ArtifactsInfo artifactsInfo = mainTypeAndCIArtifacts.getComponentArtifacts();
293 if (artifactsInfo != null) {
294 final Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactsInfosMap = artifactsInfo.getArtifactsInfo();
295 if (MapUtils.isNotEmpty(artifactsInfosMap) && artifactsInfosMap.containsKey(ArtifactGroupTypeEnum.DEPLOYMENT)) {
296 return artifactsInfosMap.get(ArtifactGroupTypeEnum.DEPLOYMENT).containsKey(ArtifactTypeEnum.ASD_PACKAGE.getType());
305 private Either<byte[], ResponseFormat> generateCsarZip(boolean isAsdPackage,
308 boolean isInCertificationRequest) {
309 try (final ByteArrayOutputStream out = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(out)) {
310 Either<ZipOutputStream, ResponseFormat> populateZip = mapFromModelCsarGeneratorService.generateCsarZip(
311 component, getFromCS, zip, isInCertificationRequest, isAsdPackage);
312 if (populateZip.isRight()) {
313 log.debug("Failed to populate CSAR zip file {}. Please fix DB table accordingly ", populateZip.right().value());
314 return Either.right(populateZip.right().value());
317 return Either.left(out.toByteArray());
318 } catch (IOException e) {
319 log.debug("Failed with IOexception to create CSAR zip for component {}. Please fix DB table accordingly ", component.getUniqueId(), e);
320 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
321 return Either.right(responseFormat);
325 /************************************ Artifacts Structure END******************************************************************/
327 private Either<CsarDefinition, ResponseFormat> collectComponentCsarDefinition(Component component) {
328 ComponentArtifacts componentArtifacts = new ComponentArtifacts();
329 Component updatedComponent = component;
331 //get service to receive the AII artifacts uploaded to the service
332 if (updatedComponent.getComponentType() == ComponentTypeEnum.SERVICE) {
333 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(updatedComponent.getUniqueId());
335 if (getServiceResponse.isRight()) {
336 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getServiceResponse.right().value());
337 return Either.right(componentsUtils.getResponseFormat(actionStatus));
340 updatedComponent = getServiceResponse.left().value();
343 //find the artifacts of the main component, it would have its composed instances artifacts in a separate folder
344 ComponentTypeArtifacts componentInstanceArtifacts = new ComponentTypeArtifacts();
345 ArtifactsInfo artifactsInfo = collectComponentArtifacts(updatedComponent);
346 componentInstanceArtifacts.setComponentArtifacts(artifactsInfo);
347 componentArtifacts.setMainTypeAndCIArtifacts(componentInstanceArtifacts);
349 Map<String, ComponentTypeArtifacts> resourceTypeArtifacts = componentArtifacts
350 .getComponentTypeArtifacts(); //artifacts mapped by the component type(tosca name+version)
351 //get the component instances
352 List<ComponentInstance> componentInstances = updatedComponent.getComponentInstances();
353 if (componentInstances != null) {
354 for (ComponentInstance componentInstance : componentInstances) {
355 //call recursive to find artifacts for all the path
356 Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts = collectComponentInstanceArtifacts(
357 updatedComponent, componentInstance, resourceTypeArtifacts, componentInstanceArtifacts);
358 if (collectComponentInstanceArtifacts.isRight()) {
359 return Either.right(collectComponentInstanceArtifacts.right().value());
364 if (log.isDebugEnabled()) {
365 printResult(componentArtifacts, updatedComponent.getName());
368 return Either.left(new CsarDefinition(componentArtifacts));
371 private void printResult(ComponentArtifacts componentArtifacts, String name) {
372 StringBuilder result = new StringBuilder();
373 result.append("Artifacts of main component " + name + "\n");
374 ComponentTypeArtifacts componentInstanceArtifacts = componentArtifacts.getMainTypeAndCIArtifacts();
375 printArtifacts(componentInstanceArtifacts);
376 result.append("Type Artifacts\n");
377 for (Entry<String, ComponentTypeArtifacts> typeArtifacts : componentArtifacts.getComponentTypeArtifacts().entrySet()) {
378 result.append("Folder " + typeArtifacts.getKey() + "\n");
379 result.append(printArtifacts(typeArtifacts.getValue()));
382 if (log.isDebugEnabled()) {
383 log.debug(result.toString());
387 /************************************ Artifacts Structure ******************************************************************/
389 private String printArtifacts(ComponentTypeArtifacts componentInstanceArtifacts) {
390 StringBuilder result = new StringBuilder();
391 ArtifactsInfo artifactsInfo = componentInstanceArtifacts.getComponentArtifacts();
392 Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componentArtifacts = artifactsInfo.getArtifactsInfo();
393 printArtifacts(componentArtifacts);
394 result = result.append("Resources\n");
395 for (Entry<String, ArtifactsInfo> resourceInstance : componentInstanceArtifacts.getComponentInstancesArtifacts().entrySet()) {
396 result.append("Folder" + resourceInstance.getKey() + "\n");
397 result.append(printArtifacts(resourceInstance.getValue().getArtifactsInfo()));
400 return result.toString();
403 private String printArtifacts(Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componetArtifacts) {
404 StringBuilder result = new StringBuilder();
405 for (Entry<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactGroup : componetArtifacts.entrySet()) {
406 result.append(" " + artifactGroup.getKey().getType());
407 for (Entry<String, List<ArtifactDefinition>> groupArtifacts : artifactGroup.getValue().entrySet()) {
408 result.append(" " + groupArtifacts.getKey());
409 for (ArtifactDefinition artifact : groupArtifacts.getValue()) {
410 result.append(" " + artifact.getArtifactDisplayName());
415 return result.toString();
418 private ComponentTypeArtifacts collectComponentTypeArtifacts(Component fetchedComponent) {
419 ArtifactsInfo componentArtifacts = collectComponentArtifacts(fetchedComponent);
420 ComponentTypeArtifacts componentArtifactsInfo = new ComponentTypeArtifacts();
421 if (componentArtifacts.isNotEmpty()) {
422 componentArtifactsInfo.setComponentArtifacts(componentArtifacts);
424 return componentArtifactsInfo;
427 private Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts(Component parentComponent, ComponentInstance componentInstance,
428 Map<String, ComponentTypeArtifacts> resourcesTypeArtifacts,
429 ComponentTypeArtifacts instanceArtifactsLocation) {
430 //1. get the component instance component
432 if (componentInstance.getOriginType() == OriginTypeEnum.ServiceProxy) {
433 componentUid = componentInstance.getSourceModelUid();
435 componentUid = componentInstance.getComponentUid();
437 Either<Component, StorageOperationStatus> component = toscaOperationFacade.getToscaElement(componentUid);
438 if (component.isRight()) {
439 log.error("Failed to fetch resource with id {} for instance {}", componentUid, parentComponent.getUUID());
440 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ASSET_NOT_FOUND_DURING_CSAR_CREATION,
441 parentComponent.getComponentType().getValue(), parentComponent.getUUID(),
442 componentInstance.getOriginType().getComponentType().getValue(), componentUid));
444 Component fetchedComponent = component.left().value();
446 //2. fill the artifacts for the current component parent type
447 String toscaComponentName =
448 componentInstance.getToscaComponentName() + "_v" + componentInstance.getComponentVersion();
450 // if there are no artifacts for this component type we need to fetch and build them
451 ComponentTypeArtifacts componentParentArtifacts = Optional
452 .ofNullable(resourcesTypeArtifacts.get(toscaComponentName))
453 .orElseGet(() -> collectComponentTypeArtifacts(fetchedComponent));
455 if (componentParentArtifacts.getComponentArtifacts().isNotEmpty()) {
456 resourcesTypeArtifacts.put(toscaComponentName, componentParentArtifacts);
459 //3. find the artifacts specific to the instance
460 Map<String, List<ArtifactDefinition>> componentInstanceSpecificInformationalArtifacts =
461 getComponentInstanceSpecificArtifacts(componentInstance.getArtifacts(),
462 componentParentArtifacts.getComponentArtifacts().getArtifactsInfo(), ArtifactGroupTypeEnum.INFORMATIONAL);
463 Map<String, List<ArtifactDefinition>> componentInstanceSpecificDeploymentArtifacts =
464 getComponentInstanceSpecificArtifacts(componentInstance.getDeploymentArtifacts(),
465 componentParentArtifacts.getComponentArtifacts().getArtifactsInfo(), ArtifactGroupTypeEnum.DEPLOYMENT);
467 //4. add the instances artifacts to the component type
468 ArtifactsInfo artifactsInfo = new ArtifactsInfo();
469 if (!componentInstanceSpecificInformationalArtifacts.isEmpty()) {
470 artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.INFORMATIONAL, componentInstanceSpecificInformationalArtifacts);
472 if (!componentInstanceSpecificDeploymentArtifacts.isEmpty()) {
473 artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, componentInstanceSpecificDeploymentArtifacts);
475 if (!artifactsInfo.isEmpty()) {
476 instanceArtifactsLocation.addComponentInstancesArtifacts(componentInstance.getNormalizedName(), artifactsInfo);
479 //5. do the same for all the component instances
480 List<ComponentInstance> componentInstances = fetchedComponent.getComponentInstances();
481 if (componentInstances != null) {
482 for (ComponentInstance childComponentInstance : componentInstances) {
483 Either<Boolean, ResponseFormat> collectComponentInstanceArtifacts = collectComponentInstanceArtifacts(
484 fetchedComponent, childComponentInstance, resourcesTypeArtifacts, componentParentArtifacts);
485 if (collectComponentInstanceArtifacts.isRight()) {
486 return collectComponentInstanceArtifacts;
491 return Either.left(true);
494 private Map<String, List<ArtifactDefinition>> getComponentInstanceSpecificArtifacts(Map<String, ArtifactDefinition> componentArtifacts,
495 Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> componentTypeArtifacts,
496 ArtifactGroupTypeEnum artifactGroupTypeEnum) {
497 Map<String, List<ArtifactDefinition>> parentArtifacts = componentTypeArtifacts
498 .get(artifactGroupTypeEnum); //the artfiacts of the component itself and not the instance
500 Map<String, List<ArtifactDefinition>> artifactsByTypeOfComponentInstance = new HashMap<>();
501 if (componentArtifacts != null) {
502 for (ArtifactDefinition artifact : componentArtifacts.values()) {
503 List<ArtifactDefinition> parentArtifactsByType = null;
504 if (parentArtifacts != null) {
505 parentArtifactsByType = parentArtifacts.get(artifact.getArtifactType());
507 //the artifact is of instance
508 if (parentArtifactsByType == null || !parentArtifactsByType.contains(artifact)) {
509 List<ArtifactDefinition> typeArtifacts = artifactsByTypeOfComponentInstance.get(artifact.getArtifactType());
510 if (typeArtifacts == null) {
511 typeArtifacts = new ArrayList<>();
512 artifactsByTypeOfComponentInstance.put(artifact.getArtifactType(), typeArtifacts);
514 typeArtifacts.add(artifact);
519 return artifactsByTypeOfComponentInstance;
522 private ArtifactsInfo collectComponentArtifacts(Component component) {
523 Map<String, ArtifactDefinition> informationalArtifacts = component.getArtifacts();
524 Map<String, List<ArtifactDefinition>> informationalArtifactsByType = collectGroupArtifacts(informationalArtifacts);
525 Map<String, ArtifactDefinition> deploymentArtifacts = component.getDeploymentArtifacts();
526 Map<String, List<ArtifactDefinition>> deploymentArtifactsByType = collectGroupArtifacts(deploymentArtifacts);
527 ArtifactsInfo artifactsInfo = new ArtifactsInfo();
528 if (!informationalArtifactsByType.isEmpty()) {
529 artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.INFORMATIONAL, informationalArtifactsByType);
531 if (!deploymentArtifactsByType.isEmpty()) {
532 artifactsInfo.addArtifactsToGroup(ArtifactGroupTypeEnum.DEPLOYMENT, deploymentArtifactsByType);
535 return artifactsInfo;
538 private Map<String, List<ArtifactDefinition>> collectGroupArtifacts(
539 final Map<String, ArtifactDefinition> componentArtifacts) {
540 final Map<String, List<ArtifactDefinition>> artifactsByType = new HashMap<>();
541 for (final ArtifactDefinition artifact : componentArtifacts.values()) {
542 if (artifact.getArtifactUUID() != null) {
543 artifactsByType.putIfAbsent(artifact.getArtifactType(), new ArrayList<>());
544 final List<ArtifactDefinition> typeArtifacts = artifactsByType.get(artifact.getArtifactType());
545 typeArtifacts.add(artifact);
548 return artifactsByType;
553 public static final class NonMetaArtifactInfo {
555 private final String path;
556 private final String artifactName;
557 private final String displayName;
558 private final String artifactLabel;
559 private final String artifactType;
560 private final ArtifactGroupTypeEnum artifactGroupType;
561 private final String payloadData;
562 private final String artifactChecksum;
563 private final boolean isFromCsar;
565 private String artifactUniqueId;
567 public NonMetaArtifactInfo(final String artifactName, final String path, final String artifactType,
568 final ArtifactGroupTypeEnum artifactGroupType, final byte[] payloadData, final String artifactUniqueId,
569 final boolean isFromCsar) {
571 this.isFromCsar = isFromCsar;
572 this.artifactName = ValidationUtils.normalizeFileName(artifactName);
573 this.artifactType = artifactType;
574 this.artifactGroupType = artifactGroupType;
575 final int pointIndex = artifactName.lastIndexOf('.');
576 if (pointIndex > 0) {
577 displayName = artifactName.substring(0, pointIndex);
579 displayName = artifactName;
581 this.artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactName);
582 if (payloadData == null) {
583 this.payloadData = null;
584 this.artifactChecksum = null;
586 this.payloadData = Base64.encodeBase64String(payloadData);
587 this.artifactChecksum = GeneralUtility.calculateMD5Base64EncodedByByteArray(payloadData);
589 this.artifactUniqueId = artifactUniqueId;
594 * The artifacts Definition saved by their structure
596 private class ArtifactsInfo {
597 //Key is the type of artifacts(Informational/Deployment)
599 //Value is a map between an artifact type and a list of all artifacts of this type
600 private Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> artifactsInfoField;
602 public ArtifactsInfo() {
603 this.artifactsInfoField = new EnumMap<>(ArtifactGroupTypeEnum.class);
606 public Map<ArtifactGroupTypeEnum, Map<String, List<ArtifactDefinition>>> getArtifactsInfo() {
607 return artifactsInfoField;
610 public void addArtifactsToGroup(ArtifactGroupTypeEnum artifactGroup, Map<String, List<ArtifactDefinition>> artifactsDefinition) {
611 if (artifactsInfoField.get(artifactGroup) == null) {
612 artifactsInfoField.put(artifactGroup, artifactsDefinition);
614 Map<String, List<ArtifactDefinition>> artifactTypeEnumListMap = artifactsInfoField.get(artifactGroup);
615 artifactTypeEnumListMap.putAll(artifactsDefinition);
616 artifactsInfoField.put(artifactGroup, artifactTypeEnumListMap);
620 public boolean isEmpty() {
621 return artifactsInfoField.isEmpty();
624 public boolean isNotEmpty() {
630 * The artifacts of the component and of all its composed instances
632 private class ComponentTypeArtifacts {
634 private ArtifactsInfo componentArtifacts; //component artifacts (describes the Informational Deployment folders)
636 private Map<String, ArtifactsInfo> componentInstancesArtifacts; //artifacts of the composed instances mapped by the resourceInstance normalized name (describes the Resources folder)
638 public ComponentTypeArtifacts() {
639 componentArtifacts = new ArtifactsInfo();
640 componentInstancesArtifacts = new HashMap<>();
643 public ArtifactsInfo getComponentArtifacts() {
644 return componentArtifacts;
647 public void setComponentArtifacts(ArtifactsInfo artifactsInfo) {
648 this.componentArtifacts = artifactsInfo;
651 public Map<String, ArtifactsInfo> getComponentInstancesArtifacts() {
652 return componentInstancesArtifacts;
655 public void addComponentInstancesArtifacts(String normalizedName, ArtifactsInfo artifactsInfo) {
656 componentInstancesArtifacts.put(normalizedName, artifactsInfo);
660 private class ComponentArtifacts {
662 //artifacts of the component and CI's artifacts contained in it's composition (represents Informational, Deployment & Resource folders of main component)
663 private ComponentTypeArtifacts mainTypeAndCIArtifacts;
664 //artifacts of all component types mapped by their tosca name
665 private Map<String, ComponentTypeArtifacts> componentTypeArtifacts;
667 public ComponentArtifacts() {
668 mainTypeAndCIArtifacts = new ComponentTypeArtifacts();
669 componentTypeArtifacts = new HashMap<>();
672 public ComponentTypeArtifacts getMainTypeAndCIArtifacts() {
673 return mainTypeAndCIArtifacts;
676 public void setMainTypeAndCIArtifacts(ComponentTypeArtifacts componentInstanceArtifacts) {
677 this.mainTypeAndCIArtifacts = componentInstanceArtifacts;
680 public Map<String, ComponentTypeArtifacts> getComponentTypeArtifacts() {
681 return componentTypeArtifacts;
685 private class CsarDefinition {
687 private ComponentArtifacts componentArtifacts;
689 // add list of tosca artifacts and meta describes CSAR zip root
690 public CsarDefinition(ComponentArtifacts componentArtifacts) {
691 this.componentArtifacts = componentArtifacts;
694 public ComponentArtifacts getComponentArtifacts() {
695 return componentArtifacts;