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=========================================================
19 * Modifications copyright (c) 2020 Nokia
20 * ================================================================================
22 package org.openecomp.sdc.be.components.impl;
24 import static org.openecomp.sdc.be.dao.api.ActionStatus.MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE;
26 import com.google.common.annotations.VisibleForTesting;
27 import com.google.gson.Gson;
28 import com.google.gson.GsonBuilder;
29 import fj.data.Either;
30 import io.vavr.control.Option;
31 import java.math.BigDecimal;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.Comparator;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.List;
39 import java.util.Map.Entry;
40 import java.util.Objects;
41 import java.util.Optional;
43 import java.util.function.Consumer;
44 import java.util.function.Function;
45 import java.util.function.Predicate;
46 import java.util.function.Supplier;
47 import java.util.stream.Collectors;
48 import javax.servlet.http.HttpServletRequest;
49 import org.apache.commons.codec.binary.Base64;
50 import org.apache.commons.collections.CollectionUtils;
51 import org.apache.commons.collections.MapUtils;
52 import org.apache.commons.io.FilenameUtils;
53 import org.apache.commons.lang.ArrayUtils;
54 import org.apache.commons.lang.StringUtils;
55 import org.apache.commons.lang3.tuple.ImmutablePair;
56 import org.openecomp.sdc.be.components.ArtifactsResolver;
57 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
58 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
59 import org.openecomp.sdc.be.components.impl.artifact.ArtifactTypeToPayloadTypeSelector;
60 import org.openecomp.sdc.be.components.impl.artifact.PayloadTypeEnum;
61 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
62 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
63 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
64 import org.openecomp.sdc.be.components.impl.utils.ComponentUtils;
65 import org.openecomp.sdc.be.components.impl.validation.PMDictionaryValidator;
66 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
67 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
68 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
69 import org.openecomp.sdc.be.components.utils.ArtifactUtils;
70 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
71 import org.openecomp.sdc.be.config.ArtifactConfiguration;
72 import org.openecomp.sdc.be.config.BeEcompErrorManager;
73 import org.openecomp.sdc.be.config.Configuration;
74 import org.openecomp.sdc.be.config.Configuration.ArtifactTypeConfig;
75 import org.openecomp.sdc.be.config.ConfigurationManager;
76 import org.openecomp.sdc.be.dao.api.ActionStatus;
77 import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
78 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
79 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
80 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
81 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
82 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
83 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
84 import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition;
85 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
86 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
87 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
88 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
89 import org.openecomp.sdc.be.info.ArtifactTemplateInfo;
90 import org.openecomp.sdc.be.model.ArtifactDefinition;
91 import org.openecomp.sdc.be.model.Component;
92 import org.openecomp.sdc.be.model.ComponentInstance;
93 import org.openecomp.sdc.be.model.ComponentParametersView;
94 import org.openecomp.sdc.be.model.GroupDefinition;
95 import org.openecomp.sdc.be.model.GroupInstance;
96 import org.openecomp.sdc.be.model.HeatParameterDefinition;
97 import org.openecomp.sdc.be.model.InterfaceDefinition;
98 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
99 import org.openecomp.sdc.be.model.LifecycleStateEnum;
100 import org.openecomp.sdc.be.model.Operation;
101 import org.openecomp.sdc.be.model.Resource;
102 import org.openecomp.sdc.be.model.Service;
103 import org.openecomp.sdc.be.model.User;
104 import org.openecomp.sdc.be.model.heat.HeatParameterType;
105 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
106 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
107 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeTemplateOperation;
108 import org.openecomp.sdc.be.model.operations.StorageException;
109 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
110 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
111 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
112 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
113 import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation;
114 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
115 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
116 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
117 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
118 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
119 import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation;
120 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
121 import org.openecomp.sdc.be.resources.data.DAOArtifactData;
122 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
123 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
124 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
125 import org.openecomp.sdc.be.servlets.RepresentationUtils;
126 import org.openecomp.sdc.be.tosca.CsarUtils;
127 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
128 import org.openecomp.sdc.be.user.Role;
129 import org.openecomp.sdc.be.user.UserBusinessLogic;
130 import org.openecomp.sdc.be.utils.TypeUtils;
131 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
132 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
133 import org.openecomp.sdc.common.api.Constants;
134 import org.openecomp.sdc.common.datastructure.Wrapper;
135 import org.openecomp.sdc.common.log.wrappers.Logger;
136 import org.openecomp.sdc.common.util.GeneralUtility;
137 import org.openecomp.sdc.common.util.ValidationUtils;
138 import org.openecomp.sdc.common.util.YamlToObjectConverter;
139 import org.openecomp.sdc.exception.ResponseFormat;
140 import org.springframework.beans.factory.annotation.Autowired;
141 import org.yaml.snakeyaml.Yaml;
143 @org.springframework.stereotype.Component("artifactBusinessLogic")
144 public class ArtifactsBusinessLogic extends BaseBusinessLogic {
146 public static final String HEAT_ENV_NAME = "heatEnv";
147 public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
148 public static final String HEAT_ENV_SUFFIX = "env";
149 public static final String ARTIFACT_ACTION_LOCK = "Artifact action - lock ";
150 public static final String FAILED_UPLOAD_ARTIFACT_TO_COMPONENT = "Failed to upload artifact to component with type {} and uuid {}. Status is {}. ";
151 public static final String COMPONENT_INSTANCE_NOT_FOUND = "Component instance {} was not found for component {}";
152 private static final String RESOURCE_INSTANCE = "resource instance";
153 private static final String ARTIFACT_TYPE_OTHER = "OTHER";
154 private static final String ARTIFACT_DESCRIPTION = "artifact description";
155 private static final String ARTIFACT_LABEL = "artifact label";
156 private static final String ARTIFACT_URL = "artifact url";
157 private static final String ARTIFACT_NAME = "artifact name";
158 private static final String ARTIFACT_PAYLOAD = "artifact payload";
159 private static final String ARTIFACT_PLACEHOLDER_TYPE = "type";
160 private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
161 private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
162 private static final String ARTIFACT_PLACEHOLDER_FILE_EXTENSION = "fileExtension";
163 private static final Logger log = Logger.getLogger(ArtifactsBusinessLogic.class.getName());
164 private static final String FAILED_UPDATE_GROUPS = "Failed to update groups of the component {}. ";
165 private static final String FAILED_SAVE_ARTIFACT = "Failed to save the artifact.";
166 private static final String FAILED_FETCH_COMPONENT = "Could not fetch component with type {} and uuid {}. Status is {}. ";
167 private static final String NULL_PARAMETER = "One of the function parameteres is null";
168 private static final String ROLLBACK = "all changes rollback";
169 private static final String COMMIT = "all changes committed";
170 private static final String UPDATE_ARTIFACT = "Update Artifact";
171 private static final String FOUND_DEPLOYMENT_ARTIFACT = "Found deployment artifact {}";
172 private Gson gson = new GsonBuilder().setPrettyPrinting().create();
173 @javax.annotation.Resource
174 private IInterfaceLifecycleOperation interfaceLifecycleOperation;
175 @javax.annotation.Resource
176 private UserAdminOperation userOperaton;
177 @javax.annotation.Resource
178 private IElementOperation elementOperation;
179 @javax.annotation.Resource
180 private IHeatParametersOperation heatParametersOperation;
181 private ArtifactCassandraDao artifactCassandraDao;
182 private ToscaExportHandler toscaExportUtils;
183 private CsarUtils csarUtils;
184 private LifecycleBusinessLogic lifecycleBusinessLogic;
185 private UserBusinessLogic userBusinessLogic;
186 private ArtifactsResolver artifactsResolver;
187 private NodeTemplateOperation nodeTemplateOperation;
190 public ArtifactsBusinessLogic(ArtifactCassandraDao artifactCassandraDao, ToscaExportHandler toscaExportUtils, CsarUtils csarUtils,
191 LifecycleBusinessLogic lifecycleBusinessLogic, UserBusinessLogic userBusinessLogic,
192 ArtifactsResolver artifactsResolver, IElementOperation elementDao, IGroupOperation groupOperation,
193 IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation,
194 InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
195 ArtifactsOperations artifactToscaOperation) {
196 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
197 artifactToscaOperation);
198 this.artifactCassandraDao = artifactCassandraDao;
199 this.toscaExportUtils = toscaExportUtils;
200 this.csarUtils = csarUtils;
201 this.lifecycleBusinessLogic = lifecycleBusinessLogic;
202 this.userBusinessLogic = userBusinessLogic;
203 this.artifactsResolver = artifactsResolver;
206 public static <R> Either<Boolean, R> ifTrue(boolean predicate, Supplier<Either<Boolean, R>> ifTrue) {
207 return predicate ? ifTrue.get() : Either.left(false);
210 public static <L, R> Either<L, R> forEach(Either<L, R> e, Consumer<L> c) {
211 return e.left().map(l -> {
217 private static Option<ComponentInstance> findFirstMatching(Component component, Predicate<ComponentInstance> filter) {
218 return Option.ofOptional(component.getComponentInstances().stream().filter(filter).findFirst());
222 public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
223 ArtifactOperationInfo operation, String artifactId,
224 ArtifactDefinition artifactInfo, String origMd5, String originData,
225 String interfaceName, String operationName, String parentId,
226 String containerComponentType, boolean shouldLock, boolean inTransaction) {
227 // step 1 - detect auditing type
228 AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
229 // step 2 - check header
230 if (userId == null) {
231 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
232 log.debug("handleArtifactRequest - no HTTP_CSP_HEADER , component id {}", componentId);
233 handleAuditing(auditingAction, null, componentId, null, null, null, artifactId, responseFormat, componentType, null);
234 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
236 // step 3 - check user existence
238 // step 4 - check user's role
239 User user = validateUserExists(userId, auditingAction, componentId, artifactId, componentType, inTransaction);
240 validateUserRole(user, auditingAction, componentId, artifactId, componentType, operation);
243 // 5. check service/resource existence
245 // 6. check service/resource check out
247 // 7. user is owner of checkout state
248 Component component = null;
249 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
250 component = validateComponentExists(realComponentId, auditingAction, user, artifactId, componentType, containerComponentType);
251 validateWorkOnComponent(component, userId, auditingAction, user, artifactId, operation);
252 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
253 validateResourceInstanceById(component, componentId);
256 return validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
257 operationName, user, component, shouldLock, inTransaction, true);
260 public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
261 ArtifactOperationInfo operation, String artifactId,
262 ArtifactDefinition artifactInfo, String origMd5, String originData,
263 String interfaceName, String operationName, String parentId,
264 String containerComponentType) {
265 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
266 operationName, parentId, containerComponentType, true, false);
270 * This Method validates only the Artifact and does not validate user / role / component ect...<br> For regular usage use <br> {@link
271 * #handleArtifactRequest(String, String, ComponentTypeEnum, ArtifactOperationInfo, String, ArtifactDefinition, String, String, String, String,
276 public Either<ArtifactDefinition, Operation> validateAndHandleArtifact(String componentUniqueId, ComponentTypeEnum componentType,
277 ArtifactOperationInfo operation, String artifactUniqueId,
278 ArtifactDefinition artifactDefinition, String origMd5, String originData,
279 String interfaceName, String operationName, User user, Component component,
280 boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
281 AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
282 artifactDefinition = validateArtifact(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, auditingAction, user,
283 component, shouldLock, inTransaction);
285 Either<ArtifactDefinition, Operation> result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition,
286 origMd5, originData, interfaceName, operationName, auditingAction, user, component, shouldLock, inTransaction, needUpdateGroup);
287 //TODO: audit positive action
292 ArtifactDefinition validateArtifact(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId,
293 ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, User user, Component component,
294 boolean shouldLock, boolean inTransaction) {
295 ArtifactDefinition artifactInfoToReturn = artifactInfo;
296 ArtifactOperationEnum operationEnum = operation.getArtifactOperationEnum();
297 if (operationEnum == ArtifactOperationEnum.UPDATE || operationEnum == ArtifactOperationEnum.DELETE
298 || operationEnum == ArtifactOperationEnum.DOWNLOAD) {
299 ArtifactDefinition dbArtifact = getArtifactIfBelongsToComponent(componentId, componentType, artifactId, component);
300 if (operation.isDownload()) {
301 artifactInfoToReturn = dbArtifact;
302 handleHeatEnvDownload(componentId, componentType, user, component, dbArtifact, shouldLock, inTransaction);
305 return artifactInfoToReturn;
309 void handleHeatEnvDownload(String componentId, ComponentTypeEnum componentType, User user, Component component,
310 ArtifactDefinition artifactDefinition, boolean shouldLock, boolean inTransaction) {
311 if (artifactDefinition.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType()) && ComponentTypeEnum.SERVICE == component
312 .getComponentType()) {
313 ComponentInstance componentInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId))
314 .findAny().orElse(null);
315 if (componentInstance == null) {
316 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentId, "instance", "Service",
317 component.getName());
319 Map<String, ArtifactDefinition> deploymentArtifacts = componentInstance.getDeploymentArtifacts();
320 ArtifactDefinition heatEnvWithHeatParams = deploymentArtifacts.values().stream()
321 .filter(p -> p.getUniqueId().equals(artifactDefinition.getUniqueId())).findAny().orElse(null);
322 Either<ArtifactDefinition, ResponseFormat> eitherGenerated = generateHeatEnvArtifact(heatEnvWithHeatParams, componentType, component,
323 componentInstance.getName(), user, componentId, shouldLock, inTransaction);
324 if (eitherGenerated.isRight()) {
325 throw new ByResponseFormatComponentException((eitherGenerated.right().value()));
330 private boolean artifactGenerationRequired(Component component, ArtifactDefinition artifactInfo) {
331 boolean needGenerate;
332 needGenerate = artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && (
333 component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN
334 || component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
335 needGenerate = needGenerate || (ComponentTypeEnum.RESOURCE == component.getComponentType() && (
336 artifactInfo.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType()) || isAbstractVfcEmptyCsar((Resource) component,
341 private boolean isAbstractVfcEmptyCsar(Resource resource, ArtifactDefinition artifactInfo) {
342 return resource.isAbstract() && artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && artifactInfo.getArtifactType()
343 .equals(ArtifactTypeEnum.TOSCA_CSAR.getType()) && StringUtils.isEmpty(artifactInfo.getArtifactChecksum());
346 public Either<ArtifactDefinition, Operation> generateAndSaveToscaArtifact(ArtifactDefinition artifactDefinition, Component component, User user,
347 boolean isInCertificationRequest, boolean shouldLock,
348 boolean inTransaction, boolean fetchTemplatesFromDB) {
349 return decodeToscaArtifactPayload(component, isInCertificationRequest, fetchTemplatesFromDB, artifactDefinition.getArtifactType()).left()
351 // TODO: Avoid output argument
352 artifactDefinition.setPayload(payload);
353 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
354 artifactDefinition.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(payload));
355 return lockComponentAndUpdateArtifact(component.getUniqueId(), artifactDefinition, AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE,
356 artifactDefinition.getUniqueId(), user, component.getComponentType(), component, payload, shouldLock, inTransaction);
357 }).right().map(ex -> {
358 // TODO: This should not be done but in order to keep this refactoring small enough, we stop here.
360 // Bubble up this exception
365 private Either<byte[], ComponentException> decodeToscaArtifactPayload(Component parent, boolean isInCertificationRequest,
366 boolean fetchTemplatesFromDB, String artifactType) {
367 log.debug("tosca artifact generation");
368 if (ArtifactTypeEnum.TOSCA_CSAR.getType().equals(artifactType)) {
369 return csarUtils.createCsar(parent, fetchTemplatesFromDB, isInCertificationRequest).right().map(error -> {
370 log.debug("Failed to generate tosca csar for component {} error {}", parent.getUniqueId(), error);
371 return new ByResponseFormatComponentException(error);
374 return toscaExportUtils.exportComponent(parent).left().map(toscaRepresentation -> {
375 log.debug("Tosca yaml exported for component {} ", parent.getUniqueId());
376 return toscaRepresentation.getMainYaml();
377 }).right().map(toscaError -> {
378 log.debug("Failed export tosca yaml for component {} error {}", parent.getUniqueId(), toscaError);
379 return new ByActionStatusComponentException(componentsUtils.convertFromToscaError(toscaError));
384 private Either<ArtifactDefinition, Operation> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
385 String artifactId, ArtifactDefinition artifactInfo, String origMd5, String originData,
386 String interfaceName, String operationName, AuditingActionEnum auditingAction, User user,
387 Component parent, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
388 if (interfaceName != null && operationName != null) {
389 interfaceName = interfaceName.toLowerCase();
390 operationName = operationName.toLowerCase();
393 lockComponent(componentType, artifactId, auditingAction, user, parent);
395 Either<ArtifactDefinition, Operation> result;
396 boolean operationSucceeded = false;
398 switch (operation.getArtifactOperationEnum()) {
400 if (artifactGenerationRequired(parent, artifactInfo)) {
401 result = Either.left(generateNotSavedArtifact(parent, artifactInfo));
403 result = Either.left(handleDownload(componentId, artifactId, componentType, parent));
407 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, parent));
410 result = handleUpdate(componentId, componentType, operation, artifactId, artifactInfo, null, origMd5, originData, interfaceName,
411 operationName, auditingAction, user, parent, needUpdateGroup);
414 result = handleCreate(componentId, artifactInfo, operation, auditingAction, user, componentType, parent, origMd5, originData,
415 interfaceName, operationName);
418 result = Either.left(handleLink(componentId, artifactInfo, componentType, parent));
421 throw new UnsupportedOperationException(
422 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
424 operationSucceeded = true;
427 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
431 private void lockComponent(ComponentTypeEnum componentType, String artifactId, AuditingActionEnum auditingAction, User user, Component parent) {
433 lockComponent(parent, ARTIFACT_ACTION_LOCK);
434 } catch (ComponentException e) {
435 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, null, null, artifactId, e.getResponseFormat(), componentType, null);
441 public Either<ArtifactDefinition, Operation> handleUpdate(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
442 String artifactId, ArtifactDefinition artifactInfo, byte[] decodedPayload,
443 String origMd5, String originData, String interfaceName, String operationName,
444 AuditingActionEnum auditingAction, User user, Component parent,
445 boolean needUpdateGroup) {
446 Either<ArtifactDefinition, Operation> result;
447 validateArtifactType(artifactInfo);
448 final String artifactType = artifactInfo.getArtifactType();
449 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && (ArtifactTypeEnum.HEAT.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_VOL
450 .getType().equals(artifactType) || ArtifactTypeEnum.HEAT_NET.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_ENV.getType()
451 .equals(artifactType))) {
452 result = handleUpdateHeatEnvAndHeatMeta(componentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, originData,
454 if (needUpdateGroup) {
455 ActionStatus error = updateGroupInstance(artifactInfo, result.left().value(), parent, componentId);
456 if (error != ActionStatus.OK) {
457 throw new ByActionStatusComponentException(error);
460 } else if (componentType == ComponentTypeEnum.RESOURCE && ArtifactTypeEnum.HEAT_ENV.getType().equals(artifactType)) {
461 result = handleUpdateHeatWithHeatEnvParams(componentId, artifactInfo, auditingAction, componentType, parent, originData, origMd5,
462 operation, needUpdateGroup);
464 if (decodedPayload == null) {
465 decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5,
466 originData, interfaceName, operationName);
468 result = updateArtifactFlow(parent, componentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
469 if (needUpdateGroup && result.isLeft()) {
470 ArtifactDefinition updatedArtifact = result.left().value();
471 updateGroupForHeat(artifactInfo, updatedArtifact, parent);
477 private void validateArtifactType(final ArtifactDefinition artifactInfo) {
478 if (!isArtifactSupported(artifactInfo.getArtifactType())) {
479 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
483 private void validateArtifactType(final ArtifactDefinition artifactInfo, final ComponentTypeEnum componentType) {
484 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactInfo.getArtifactType()).orElse(null);
485 if (artifactConfiguration == null) {
486 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
487 log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName());
488 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE);
489 throw new ByResponseFormatComponentException(responseFormat);
491 final ArtifactGroupTypeEnum artifactGroupType = artifactInfo.getArtifactGroupType();
493 validateArtifactType(componentType, artifactGroupType, artifactConfiguration);
494 } catch (final ComponentException e) {
495 log.debug("Artifact is invalid", e);
496 BeEcompErrorManager.getInstance()
497 .logBeInvalidTypeError("Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(),
498 "Artifact " + artifactInfo.getArtifactName());
499 log.debug("Not supported artifact type = {}", artifactInfo.getArtifactType());
500 final ResponseFormat responseFormat = componentsUtils
501 .getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
502 throw new ByResponseFormatComponentException(responseFormat);
506 private void validateArtifactType(final ComponentTypeEnum componentType, final ArtifactGroupTypeEnum groupType,
507 final ArtifactConfiguration artifactConfiguration) {
508 final boolean supportComponentType =
509 CollectionUtils.isNotEmpty(artifactConfiguration.getComponentTypes()) && artifactConfiguration.getComponentTypes().stream()
510 .anyMatch(componentType1 -> componentType1.getValue().equalsIgnoreCase(componentType.getValue()));
511 if (!supportComponentType) {
512 log.debug("Artifact Type '{}' not supported for Component Type '{}'", artifactConfiguration.getType(), componentType.getValue());
513 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
515 final boolean supportResourceType = artifactConfiguration.hasSupport(groupType);
516 if (!supportResourceType) {
517 log.debug("Artifact Type '{}' not supported for Component Type '{}' and Category '{}'", artifactConfiguration.getType(),
518 componentType.getValue(), groupType.getType());
519 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
523 private boolean isArtifactSupported(final String artifactType) {
524 final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
525 final List<ArtifactConfiguration> artifactConfigurationList = configuration.getArtifacts();
526 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
529 return artifactConfigurationList.stream().anyMatch(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType));
533 public ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent) {
534 List<GroupDefinition> groups = parent.getGroups();
535 if (groups != null && !groups.isEmpty()) {
536 List<GroupDataDefinition> groupToUpdate = groups.stream()
537 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfo.getUniqueId())).collect(Collectors.toList());
538 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
539 groupToUpdate.forEach(g -> {
540 g.getArtifacts().remove(artifactInfo.getUniqueId());
541 g.getArtifactsUuid().remove(artifactInfo.getArtifactUUID());
542 g.getArtifacts().add(artAfterUpdate.getUniqueId());
543 g.getArtifactsUuid().add(artAfterUpdate.getArtifactUUID());
544 if (!artifactInfo.getArtifactUUID().equals(artAfterUpdate.getArtifactUUID())) {
545 g.setGroupUUID(UniqueIdBuilder.generateUUID());
548 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
549 if (status.isRight()) {
550 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
551 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status.right().value()));
555 return ActionStatus.OK;
559 ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfoHeat, ArtifactDefinition artHeatAfterUpdate, ArtifactDefinition artifactInfoHeatE,
560 ArtifactDefinition artHEAfterUpdate, Component parent) {
561 List<GroupDefinition> groups = parent.getGroups();
562 if (groups != null && !groups.isEmpty()) {
563 List<GroupDataDefinition> groupToUpdate = groups.stream()
564 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfoHeat.getUniqueId())).collect(Collectors.toList());
565 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
566 groupToUpdate.forEach(g -> {
567 g.getArtifacts().remove(artifactInfoHeat.getUniqueId());
568 g.getArtifactsUuid().remove(artifactInfoHeat.getArtifactUUID());
569 g.getArtifacts().remove(artifactInfoHeatE.getUniqueId());
570 g.getArtifacts().add(artHeatAfterUpdate.getUniqueId());
571 g.getArtifactsUuid().add(artHeatAfterUpdate.getArtifactUUID());
572 g.getArtifacts().add(artHEAfterUpdate.getUniqueId());
574 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
575 if (status.isRight()) {
576 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
577 return componentsUtils.convertFromStorageResponse(status.right().value());
581 return ActionStatus.OK;
584 private ActionStatus updateGroupInstance(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent, String parentId) {
585 List<GroupInstance> updatedGroupInstances = new ArrayList<>();
586 List<GroupInstance> groupInstances = null;
587 Optional<ComponentInstance> componentInstOp = parent.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(parentId))
589 if (componentInstOp.isPresent()) {
590 groupInstances = componentInstOp.get().getGroupInstances();
592 if (CollectionUtils.isNotEmpty(groupInstances)) {
593 boolean isUpdated = false;
594 for (GroupInstance groupInstance : groupInstances) {
596 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifacts()) && groupInstance.getGroupInstanceArtifacts()
597 .contains(artifactInfo.getUniqueId())) {
598 groupInstance.getGroupInstanceArtifacts().remove(artifactInfo.getUniqueId());
599 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getUniqueId());
602 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifactsUuid()) && groupInstance.getGroupInstanceArtifactsUuid()
603 .contains(artifactInfo.getArtifactUUID())) {
604 groupInstance.getGroupInstanceArtifactsUuid().remove(artifactInfo.getArtifactUUID());
605 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getArtifactUUID());
609 updatedGroupInstances.add(groupInstance);
613 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
614 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
615 if (status.isRight()) {
616 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
617 return componentsUtils.convertFromStorageResponse(status.right().value());
619 return ActionStatus.OK;
622 ArtifactDefinition generateNotSavedArtifact(Component parent, ArtifactDefinition artifactDefinition) {
623 if (artifactDefinition.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA) {
624 Either<byte[], ComponentException> decodedPayload = decodeToscaArtifactPayload(parent, false, false,
625 artifactDefinition.getArtifactType());
626 // TODO: This should not be done, but in order to keep this refactoring relatively small, we stop here
627 if (decodedPayload.isRight()) {
628 throw decodedPayload.right().value();
630 artifactDefinition.setPayload(decodedPayload.left().value());
631 return artifactDefinition;
634 String heatArtifactId = artifactDefinition.getGeneratedFromId();
635 Either<ArtifactDefinition, StorageOperationStatus> heatRes = artifactToscaOperation.getArtifactById(parent.getUniqueId(), heatArtifactId);
636 if (heatRes.isRight()) {
637 log.debug("Failed to fetch heat artifact by generated id {} for heat env {}", heatArtifactId, artifactDefinition.getUniqueId());
638 throw new StorageException(heatRes.right().value());
640 String generatedPayload = generateHeatEnvPayload(heatRes.left().value());
641 artifactDefinition.setPayloadData(generatedPayload);
642 return artifactDefinition;
646 private Either<ArtifactDefinition, Operation> handleUpdateHeatWithHeatEnvParams(String componentId, ArtifactDefinition artifactInfo,
647 AuditingActionEnum auditingAction,
648 ComponentTypeEnum componentType, Component parent,
649 String originData, String origMd5,
650 ArtifactOperationInfo operation, boolean needToUpdateGroup) {
651 Either<ArtifactDefinition, StorageOperationStatus> artifactHeatRes = artifactToscaOperation
652 .getArtifactById(componentId, artifactInfo.getGeneratedFromId());
653 ArtifactDefinition currHeatArtifact = artifactHeatRes.left().value();
654 if (origMd5 != null) {
655 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
656 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
657 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
658 } else { // duplicate
659 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
662 return updateHeatParams(componentId, artifactInfo, auditingAction, parent, componentType, currHeatArtifact, needToUpdateGroup);
665 private void handleLockingAndCommit(Component parent, boolean shouldLock, boolean inTransaction, boolean actionSucceeded) {
666 if (actionSucceeded) {
668 if (!inTransaction) {
669 janusGraphDao.commit();
673 if (!inTransaction) {
674 janusGraphDao.rollback();
678 graphLockOperation.unlockComponent(parent.getUniqueId(), parent.getComponentType().getNodeType());
682 public ImmutablePair<String, byte[]> handleDownloadToscaModelRequest(Component component, ArtifactDefinition csarArtifact) {
683 if (artifactGenerationRequired(component, csarArtifact)) {
684 Either<byte[], ResponseFormat> generated = csarUtils.createCsar(component, false, false);
685 if (generated.isRight()) {
686 log.debug("Failed to export tosca csar for component {} error {}", component.getUniqueId(), generated.right().value());
687 throw new ByResponseFormatComponentException(generated.right().value());
689 return new ImmutablePair<>(csarArtifact.getArtifactName(), generated.left().value());
691 return downloadArtifact(csarArtifact);
694 public ImmutablePair<String, byte[]> handleDownloadRequestById(String componentId, String artifactId, String userId,
695 ComponentTypeEnum componentType, String parentId, String containerComponentType) {
696 // perform all validation in common flow
697 Either<ArtifactDefinition, Operation> result = handleArtifactRequest(componentId, userId, componentType,
698 new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DOWNLOAD), artifactId, null, null, null, null, null, parentId,
699 containerComponentType);
700 ArtifactDefinition artifactDefinition;
701 Either<ArtifactDefinition, Operation> insideValue = result;
702 if (insideValue.isLeft()) {
703 artifactDefinition = insideValue.left().value();
705 artifactDefinition = insideValue.right().value().getImplementationArtifact();
707 // for tosca artifacts and heat env on VF level generated on download without saving
708 if (artifactDefinition.getPayloadData() != null) {
709 return (new ImmutablePair<>(artifactDefinition.getArtifactName(), artifactDefinition.getPayloadData()));
711 return downloadArtifact(artifactDefinition);
714 public Map<String, ArtifactDefinition> handleGetArtifactsByType(String containerComponentType, String parentId, ComponentTypeEnum componentType,
715 String componentId, String artifactGroupType, String userId) {
718 // detect auditing type
719 Map<String, ArtifactDefinition> resMap = null;
724 if (userId == null) {
725 log.debug("handleGetArtifactsByType - no HTTP_CSP_HEADER , component id {}", componentId);
726 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
730 // check user existence
735 validateUserExists(userId);
738 // 5. check service/resource existence
740 // 6. check service/resource check out
742 // 7. user is owner of checkout state
743 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
744 ComponentParametersView componentFilter = new ComponentParametersView();
745 componentFilter.disableAll();
746 componentFilter.setIgnoreArtifacts(false);
747 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
748 componentFilter.setIgnoreComponentInstances(false);
750 Component component = validateComponentExistsByFilter(realComponentId, ComponentTypeEnum.findByParamName(containerComponentType),
752 lockComponent(component, ARTIFACT_ACTION_LOCK);
753 boolean failed = false;
755 ArtifactGroupTypeEnum groupType = ArtifactGroupTypeEnum.findType(artifactGroupType);
756 if (groupType == null) {
757 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
758 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
760 if (parentId == null && groupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
761 List<ArtifactDefinition> list = getDeploymentArtifacts(component, componentId);
762 if (list != null && !list.isEmpty()) {
763 resMap = list.stream().collect(Collectors.toMap(ArtifactDataDefinition::getArtifactLabel, Function.identity()));
765 resMap = new HashMap<>();
769 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsMapStatus = getArtifacts(realComponentId,
770 componentType.getNodeType(), groupType, componentId);
771 if (artifactsMapStatus.isRight()) {
772 if (artifactsMapStatus.right().value() != StorageOperationStatus.NOT_FOUND) {
773 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
774 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
776 resMap = new HashMap<>();
779 resMap = artifactsMapStatus.left().value();
783 } catch (ComponentException e) {
790 janusGraphDao.rollback();
793 janusGraphDao.commit();
795 componentType = component.getComponentType();
796 NodeTypeEnum nodeType = componentType.getNodeType();
797 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
801 private ArtifactDefinition getArtifactIfBelongsToComponent(String componentId, ComponentTypeEnum componentType, String artifactId,
802 Component component) {
803 // check artifact existence
804 Either<ArtifactDefinition, StorageOperationStatus> artifactResult = artifactToscaOperation
805 .getArtifactById(componentId, artifactId, componentType, component.getUniqueId());
806 if (artifactResult.isRight()) {
807 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentId);
809 // verify artifact belongs to component
811 switch (componentType) {
814 found = ComponentUtils.checkArtifactInComponent(component, artifactId);
816 case RESOURCE_INSTANCE:
817 found = ComponentUtils.checkArtifactInResourceInstance(component, componentId, artifactId);
823 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentType.name().toLowerCase());
825 return artifactResult.left().value();
828 private Either<ArtifactDefinition, Operation> handleCreate(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
829 AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType,
830 Component parent, String origMd5, String originData, String interfaceType,
831 String operationName) {
832 byte[] decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, null, user, componentType, parent, origMd5,
833 originData, interfaceType, operationName);
834 return createArtifact(parent, componentId, artifactInfo, decodedPayload, componentType, auditingAction, interfaceType, operationName);
837 private ArtifactDefinition handleLink(String componentId, ArtifactDefinition artifactInfo, ComponentTypeEnum componentType, Component parent) {
838 ComponentInstance foundInstance = findComponentInstance(componentId, parent);
839 String instanceId = null;
840 if (foundInstance != null) {
841 instanceId = foundInstance.getUniqueId();
843 NodeTypeEnum nodeType = convertParentType(componentType);
844 Either<ArtifactDefinition, StorageOperationStatus> artifactDefinitionEither = artifactToscaOperation
845 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
846 if (artifactDefinitionEither.isRight()) {
847 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
849 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), componentId, componentType) != StorageOperationStatus.OK) {
850 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
852 return artifactDefinitionEither.left().value();
855 private <T> Either<ArtifactDefinition, T> lockComponentAndUpdateArtifact(String parentId, ArtifactDefinition artifactInfo,
856 AuditingActionEnum auditingAction, String artifactId, User user,
857 ComponentTypeEnum componentType, Component parent, byte[] decodedPayload,
858 boolean shouldLock, boolean inTransaction) {
859 boolean failed = false;
860 boolean writeAudit = true;
862 lockComponent(parent, shouldLock, ARTIFACT_ACTION_LOCK);
864 return updateArtifactFlow(parent, parentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
865 } catch (ComponentException ce) {
867 handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, ce.getResponseFormat(), componentType, null);
871 } catch (StorageException se) {
877 unlockComponent(failed, parent, inTransaction);
882 private byte[] validateInput(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
883 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
884 String origMd5, String originData, String interfaceType, String operationName) {
885 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
886 return getValidPayload(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, interfaceType,
890 private byte[] getValidPayload(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
891 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
892 String interfaceType, String operationName) {
894 Either<ArtifactDefinition, ResponseFormat> validateResult = validateInput(componentId, artifactInfo, operation, artifactId, user,
895 interfaceType, operationName, componentType, parent);
896 if (validateResult.isRight()) {
897 ResponseFormat responseFormat = validateResult.right().value();
898 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
899 throw new ByResponseFormatComponentException(responseFormat);
901 Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
902 if (payloadEither.isRight()) {
903 ResponseFormat responseFormat = payloadEither.right().value();
904 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
905 log.debug("Error during handle payload");
906 throw new ByResponseFormatComponentException(responseFormat);
908 // validate heat parameters. this part must be after the parameters are
910 // extracted in "handlePayload"
911 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters = validateAndConvertHeatParameters(artifactInfo,
912 artifactInfo.getArtifactType());
913 if (validateAndConvertHeatParameters.isRight()) {
914 ResponseFormat responseFormat = validateAndConvertHeatParameters.right().value();
915 handleAuditing(auditingAction, parent, componentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null);
916 log.debug("Error during handle payload");
917 throw new ByResponseFormatComponentException(responseFormat);
919 return payloadEither.left().value();
922 public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
923 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
924 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
925 if (componentsUtils.isExternalApiEvent(auditingActionEnum)) {
930 user.setUserId("UNKNOWN");
932 handleInternalAuditEvent(auditingActionEnum, component, componentId, user, artifactDefinition, prevArtifactUuid, currentArtifactUuid,
933 responseFormat, componentTypeEnum, resourceInstanceName);
936 private void handleInternalAuditEvent(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
937 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
938 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
939 switch (componentTypeEnum) {
941 Resource resource = (Resource) component;
942 if (resource == null) {
943 // In that case, component ID should be instead of name
944 resource = new Resource();
945 resource.setName(componentId);
947 componentsUtils.auditResource(responseFormat, user, resource, resource.getName(), auditingActionEnum,
948 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(), currentArtifactUuid, artifactDefinition);
951 Service service = (Service) component;
952 if (service == null) {
953 // In that case, component ID should be instead of name
954 service = new Service();
955 service.setName(componentId);
958 .auditComponent(responseFormat, user, service, auditingActionEnum, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
959 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
960 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
962 case RESOURCE_INSTANCE:
963 if (resourceInstanceName == null) {
964 resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId);
966 componentsUtils.auditComponent(responseFormat, user, component, auditingActionEnum,
967 new ResourceCommonInfo(resourceInstanceName, ComponentTypeEnum.RESOURCE_INSTANCE.getValue()),
968 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
969 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
976 private String getResourceInstanceNameFromComponent(Component component, String componentId) {
977 ComponentInstance resourceInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findFirst()
979 String resourceInstanceName = null;
980 if (resourceInstance != null) {
981 resourceInstanceName = resourceInstance.getName();
983 return resourceInstanceName;
986 private void validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperationInfo operation) {
987 if (origMd5 == null) {
988 if (operation.isCreateOrLink() && ArrayUtils.isNotEmpty(payload)) {
989 log.debug("Missing md5 header during artifact create");
990 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
993 if (ArrayUtils.isNotEmpty(payload)) {
994 log.debug("Cannot have payload while md5 header is missing");
995 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
998 String encodeBase64Str = GeneralUtility.calculateMD5Base64EncodedByString(originData);
999 if (!encodeBase64Str.equals(origMd5)) {
1000 log.debug("The calculated md5 is different then the received one");
1001 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1006 private Either<ArtifactDefinition, ResponseFormat> validateInput(final String componentId, final ArtifactDefinition artifactInfo,
1007 final ArtifactOperationInfo operation, final String artifactId, final User user,
1008 String interfaceName, String operationName,
1009 final ComponentTypeEnum componentType, final Component parentComponent) {
1010 final ArtifactDefinition existingArtifactInfo = findArtifact(parentComponent, componentType, componentId, operation, artifactId);
1011 final boolean isCreateOrLinkOperation = ArtifactOperationEnum.isCreateOrLink(operation.getArtifactOperationEnum());
1012 if (!isCreateOrLinkOperation && existingArtifactInfo == null) {
1013 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1015 final Component component;
1016 if (parentComponent.getUniqueId().equals(componentId)) {
1017 component = parentComponent;
1019 final ComponentInstance componentInstance = findComponentInstance(componentId, parentComponent);
1020 component = findComponent(componentInstance.getComponentUid());
1021 component.setComponentType(componentType);
1023 if (!isCreateOrLinkOperation) {
1024 ignoreUnupdateableFieldsInUpdate(operation, artifactInfo, existingArtifactInfo);
1026 if (isInformationalArtifact(artifactInfo)) {
1027 validateInformationalArtifact(artifactInfo, component);
1029 Either<Boolean, ResponseFormat> validateAndSetArtifactname = validateAndSetArtifactName(artifactInfo);
1030 if (validateAndSetArtifactname.isRight()) {
1031 return Either.right(validateAndSetArtifactname.right().value());
1033 if (!validateArtifactNameUniqueness(componentId, parentComponent, artifactInfo, componentType)) {
1034 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST));
1036 if (operationName != null && interfaceName != null) {
1037 operationName = operationName.toLowerCase();
1038 interfaceName = interfaceName.toLowerCase();
1040 Either<ActionStatus, ResponseFormat> logicalNameStatus = handleArtifactLabel(componentId, parentComponent, operation, artifactInfo,
1041 operationName, componentType);
1042 if (logicalNameStatus.isRight()) {
1043 return Either.right(logicalNameStatus.right().value());
1045 // This is a patch to block possibility of updating service api fields
1047 // through other artifacts flow
1048 final ArtifactGroupTypeEnum artifactGroupType =
1049 operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL;
1050 if (operation.isNotCreateOrLink()) {
1051 checkAndSetUnUpdatableFields(user, artifactInfo, existingArtifactInfo, artifactGroupType);
1053 checkCreateFields(user, artifactInfo, artifactGroupType);
1055 composeArtifactId(componentId, artifactId, artifactInfo, interfaceName, operationName);
1056 if (existingArtifactInfo != null) {
1057 artifactInfo.setMandatory(existingArtifactInfo.getMandatory());
1058 if (operation.isNotCreateOrLink()) {
1059 validateArtifactTypeNotChanged(artifactInfo, existingArtifactInfo);
1062 // artifactGroupType is not allowed to be updated
1063 if (operation.isNotCreateOrLink()) {
1064 Either<ArtifactDefinition, ResponseFormat> validateGroupType = validateOrSetArtifactGroupType(artifactInfo, existingArtifactInfo);
1065 if (validateGroupType.isRight()) {
1066 return Either.right(validateGroupType.right().value());
1069 setArtifactTimeout(artifactInfo, existingArtifactInfo);
1070 if (isHeatArtifact(artifactInfo)) {
1071 validateHeatArtifact(parentComponent, componentId, artifactInfo);
1073 if (isDeploymentArtifact(artifactInfo)) {
1074 if (componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1075 final String artifactName = artifactInfo.getArtifactName();
1076 final String existingArtifactName = (existingArtifactInfo == null) ? null : existingArtifactInfo.getArtifactName();
1077 if (operation.isCreateOrLink() || ((artifactName != null) && !artifactName.equalsIgnoreCase(existingArtifactName))) {
1078 validateSingleDeploymentArtifactName(artifactName, parentComponent);
1081 validateDeploymentArtifact(artifactInfo, component);
1083 Either<Boolean, ResponseFormat> descriptionResult = validateAndCleanDescription(artifactInfo);
1084 if (descriptionResult.isRight()) {
1085 return Either.right(descriptionResult.right().value());
1087 validateArtifactType(artifactInfo, component.getComponentType());
1088 artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase());
1089 if (existingArtifactInfo != null && existingArtifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.SERVICE_API) {
1090 // Change of type is not allowed and should be ignored
1091 artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER);
1092 Either<Boolean, ResponseFormat> validateUrl = validateAndServiceApiUrl(artifactInfo);
1093 if (validateUrl.isRight()) {
1094 return Either.right(validateUrl.right().value());
1096 Either<Boolean, ResponseFormat> validateUpdate = validateFirstUpdateHasPayload(artifactInfo, existingArtifactInfo);
1097 if (validateUpdate.isRight()) {
1098 log.debug("serviceApi first update cnnot be without payload.");
1099 return Either.right(validateUpdate.right().value());
1102 if (artifactInfo.getApiUrl() != null) {
1103 artifactInfo.setApiUrl(null);
1104 log.error("Artifact URL cannot be set through this API - ignoring");
1106 if (Boolean.TRUE.equals(artifactInfo.getServiceApi())) {
1107 artifactInfo.setServiceApi(false);
1108 log.error("Artifact service API flag cannot be changed - ignoring");
1111 return Either.left(artifactInfo);
1114 private Component findComponent(final String componentId) {
1115 Either<? extends Component, StorageOperationStatus> component = toscaOperationFacade.getToscaFullElement(componentId);
1116 if (component.isRight()) {
1117 log.debug("Component '{}' not found ", componentId);
1118 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentId);
1120 return component.left().value();
1123 private void ignoreUnupdateableFieldsInUpdate(final ArtifactOperationInfo operation, final ArtifactDefinition artifactInfo,
1124 final ArtifactDefinition currentArtifactInfo) {
1125 if (operation.isUpdate()) {
1126 artifactInfo.setArtifactType(currentArtifactInfo.getArtifactType());
1127 artifactInfo.setArtifactGroupType(currentArtifactInfo.getArtifactGroupType());
1128 artifactInfo.setArtifactLabel(currentArtifactInfo.getArtifactLabel());
1132 private ArtifactDefinition findArtifact(final Component parentComponent, final ComponentTypeEnum componentType, final String parentId,
1133 final ArtifactOperationInfo operation, final String artifactId) {
1134 ArtifactDefinition foundArtifact = null;
1135 if (StringUtils.isNotEmpty(artifactId)) {
1136 foundArtifact = findArtifact(parentComponent, componentType, parentId, artifactId);
1138 if (foundArtifact != null && operation.isCreateOrLink()) {
1139 log.debug("Artifact {} already exist", artifactId);
1140 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, foundArtifact.getArtifactLabel());
1142 if (foundArtifact == null && operation.isNotCreateOrLink()) {
1143 log.debug("The artifact {} was not found on parent component or instance {}. ", artifactId, parentId);
1144 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, "");
1146 return foundArtifact;
1149 private ArtifactDefinition findArtifact(Component parentComponent, ComponentTypeEnum componentType, String parentId, String artifactId) {
1150 ArtifactDefinition foundArtifact;
1151 if (parentComponent.getUniqueId().equals(parentId)) {
1152 foundArtifact = artifactsResolver.findArtifactOnComponent(parentComponent, componentType, artifactId);
1154 ComponentInstance instance = findComponentInstance(parentId, parentComponent);
1155 foundArtifact = artifactsResolver.findArtifactOnComponentInstance(instance, artifactId);
1157 return foundArtifact;
1160 private void validateInformationalArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1161 final ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
1162 if (groupType != ArtifactGroupTypeEnum.INFORMATIONAL) {
1165 final ComponentTypeEnum parentComponentType = component.getComponentType();
1166 final String artifactType = artifactInfo.getArtifactType();
1167 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1168 if (artifactConfiguration == null) {
1169 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1171 validateArtifactType(parentComponentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1172 if (component.getComponentType() == ComponentTypeEnum.RESOURCE || component.getComponentType() == ComponentTypeEnum.RESOURCE_INSTANCE) {
1173 final ResourceTypeEnum resourceType = ((Resource) component).getResourceType();
1174 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1176 validateArtifactExtension(artifactConfiguration, artifactInfo);
1179 private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) {
1180 if (componentType == ComponentTypeEnum.RESOURCE) {
1181 return NodeTypeEnum.Resource;
1182 } else if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1183 return NodeTypeEnum.ResourceInstance;
1185 return NodeTypeEnum.Service;
1189 // This method is here for backward compatibility - when other parts of the code are cleaned can change to use the internal version
1190 public Either<ArtifactDefinition, ResponseFormat> handleDelete(String parentId, String artifactId, User user, Component parent,
1191 boolean shouldLock, boolean inTransaction) {
1192 ResponseFormat responseFormat;
1193 boolean operationSucceeded = false;
1195 lockComponent(ComponentTypeEnum.RESOURCE, artifactId, AuditingActionEnum.ARTIFACT_DELETE, user, parent);
1198 ArtifactDefinition artifactDefinition = handleDeleteInternal(parentId, artifactId, ComponentTypeEnum.RESOURCE, parent);
1199 operationSucceeded = true;
1200 return Either.left(artifactDefinition);
1201 } catch (ComponentException ce) {
1202 responseFormat = componentsUtils.getResponseFormat(ce);
1203 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1204 ComponentTypeEnum.RESOURCE, null);
1205 return Either.right(responseFormat);
1206 } catch (StorageException se) {
1207 responseFormat = componentsUtils.getResponseFormat(se);
1208 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1209 ComponentTypeEnum.RESOURCE, null);
1210 return Either.right(responseFormat);
1212 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
1216 private ArtifactDefinition handleDeleteInternal(String parentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1217 NodeTypeEnum parentType = convertParentType(componentType);
1218 log.debug("Going to find the artifact {} on the component {}", artifactId, parent.getUniqueId());
1219 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> getArtifactRes = findArtifact(artifactId, parent, parentId,
1221 if (getArtifactRes.isRight()) {
1222 log.debug("Failed to find the artifact {} belonging to {} on the component {}", artifactId, parentId, parent.getUniqueId());
1223 throw new ByActionStatusComponentException(getArtifactRes.right().value(), artifactId);
1225 ArtifactDefinition foundArtifact = getArtifactRes.left().value().getLeft();
1226 ComponentInstance foundInstance = getArtifactRes.left().value().getRight();
1227 String esId = foundArtifact.getEsId();
1228 Either<Boolean, StorageOperationStatus> needClone = ifTrue(StringUtils.isNotEmpty(esId),
1229 () -> forEach(artifactToscaOperation.isCloneNeeded(parent.getUniqueId(), foundArtifact, parentType), b -> log
1230 .debug("handleDelete: clone is needed for deleting {} held by {} in component {} {}? {}", foundArtifact.getArtifactName(), parentType,
1231 parent.getUniqueId(), parent.getName(), b)));
1232 boolean needToClone = false;
1233 // TODO: This should not be done, but in order to keep this refactoring small, we stop here.
1235 // Remove this block once the above refactoring is merged.
1236 if (needClone.isLeft()) {
1237 needToClone = needClone.left().value();
1239 throw new StorageException(needClone.right().value(), foundArtifact.getArtifactDisplayName());
1241 boolean isNeedToDeleteArtifactFromDB =
1242 componentType == ComponentTypeEnum.RESOURCE_INSTANCE && isArtifactOnlyResourceInstanceArtifact(foundArtifact, parent, parentId);
1243 boolean isDuplicated = false;
1244 ArtifactDataDefinition updatedArtifact = deleteOrUpdateArtifactOnGraph(parent, parentId, artifactId, parentType, foundArtifact, needToClone);
1245 isDuplicated = updatedArtifact.getDuplicated();
1246 if (!needToClone && !isDuplicated && isNeedToDeleteArtifactFromDB) {
1247 log.debug("Going to delete the artifact {} from the database. ", artifactId);
1248 CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(esId);
1249 if (cassandraStatus != CassandraOperationStatus.OK) {
1250 log.debug("Failed to delete the artifact {} from the database. ", artifactId);
1251 throw new StorageException(convertToStorageOperationStatus(cassandraStatus), foundArtifact.getArtifactDisplayName());
1254 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1255 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(artifactId, foundArtifact, foundInstance.getGroupInstances());
1256 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
1257 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
1258 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
1259 if (status.isRight()) {
1260 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1261 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1264 StorageOperationStatus status = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
1265 if (status != StorageOperationStatus.OK) {
1266 log.debug("Failed to generate new customization UUID for the component instance {}. ", parentId);
1267 throw new StorageException(status, foundArtifact.getArtifactDisplayName());
1270 List<GroupDataDefinition> updatedGroups = getUpdatedGroups(artifactId, foundArtifact, parent.getGroups());
1271 if (CollectionUtils.isNotEmpty(updatedGroups)) {
1272 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, updatedGroups);
1273 if (status.isRight()) {
1274 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1275 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1279 return foundArtifact;
1282 private boolean isArtifactOnlyResourceInstanceArtifact(ArtifactDefinition foundArtifact, Component parent, String instanceId) {
1283 Optional<ComponentInstance> componentInstanceOpt = parent.getComponentInstanceById(instanceId);
1284 if (!componentInstanceOpt.isPresent()) {
1285 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "", "", parent.getName());
1287 ComponentInstance foundInstance = componentInstanceOpt.get();
1288 String componentUid = foundInstance.getComponentUid();
1289 Either<Component, StorageOperationStatus> getContainerRes = toscaOperationFacade.getToscaElement(componentUid);
1290 if (getContainerRes.isRight()) {
1291 log.debug("Failed to fetch the container component {}. ", componentUid);
1292 throw new StorageException(getContainerRes.right().value());
1294 Component origComponent = getContainerRes.left().value();
1295 Map<String, ArtifactDefinition> deploymentArtifacts = origComponent.getDeploymentArtifacts();
1296 if (MapUtils.isNotEmpty(deploymentArtifacts)) {
1297 Optional<String> op = deploymentArtifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1298 if (op.isPresent()) {
1302 Map<String, ArtifactDefinition> artifacts = origComponent.getArtifacts();
1303 if (MapUtils.isNotEmpty(artifacts)) {
1304 Optional<String> op = artifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1305 if (op.isPresent()) {
1312 private List<GroupDataDefinition> getUpdatedGroups(String artifactId, ArtifactDefinition foundArtifact, List<GroupDefinition> groups) {
1313 List<GroupDataDefinition> updatedGroups = new ArrayList<>();
1314 boolean isUpdated = false;
1315 if (groups != null) {
1316 for (GroupDefinition group : groups) {
1318 if (CollectionUtils.isNotEmpty(group.getArtifacts()) && group.getArtifacts().contains(artifactId)) {
1319 group.getArtifacts().remove(artifactId);
1322 if (CollectionUtils.isNotEmpty(group.getArtifactsUuid()) && group.getArtifactsUuid().contains(foundArtifact.getArtifactUUID())) {
1323 group.getArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1327 updatedGroups.add(group);
1331 return updatedGroups;
1334 private List<GroupInstance> getUpdatedGroupInstances(String artifactId, ArtifactDefinition foundArtifact, List<GroupInstance> groupInstances) {
1335 if (CollectionUtils.isEmpty(groupInstances)) {
1336 return new ArrayList<>();
1338 // TODO: A defensive copy should be created here for groupInstances. Modifying
1340 // arguments (aka output arguments) is overall a bad practice as explained in
1342 // Clean Code by Robert Martin.
1344 // A better approach would be to use Lenses.
1345 return groupInstances.stream().filter(gi -> {
1346 boolean groupInstanceArtifactRemoved = gi.getGroupInstanceArtifacts() != null && gi.getGroupInstanceArtifacts().remove(artifactId);
1347 boolean groupInstanceArtifactUUIDRemoved =
1348 gi.getGroupInstanceArtifactsUuid() != null && gi.getGroupInstanceArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1349 return groupInstanceArtifactRemoved || groupInstanceArtifactUUIDRemoved;
1350 }).collect(Collectors.toList());
1353 private ArtifactDataDefinition deleteOrUpdateArtifactOnGraph(Component component, String parentId, String artifactId, NodeTypeEnum parentType,
1354 ArtifactDefinition foundArtifact, Boolean cloneIsNeeded) {
1355 Either<ArtifactDataDefinition, StorageOperationStatus> result;
1356 boolean isMandatory = foundArtifact.getMandatory() || foundArtifact.getServiceApi();
1357 String componentId = component.getUniqueId();
1358 String instanceId = componentId.equals(parentId) ? null : parentId;
1360 log.debug("Going to update mandatory artifact {} from the component {}", artifactId, parentId);
1361 resetMandatoryArtifactFields(foundArtifact);
1362 result = artifactToscaOperation.updateArtifactOnGraph(component, foundArtifact, parentType, artifactId, instanceId, true, true);
1363 } else if (cloneIsNeeded) {
1364 log.debug("Going to clone artifacts and to delete the artifact {} from the component {}", artifactId, parentId);
1365 result = artifactToscaOperation.deleteArtifactWithCloningOnGraph(componentId, foundArtifact, parentType, instanceId, false);
1367 log.debug("Going to delete the artifact {} from the component {}", artifactId, parentId);
1368 result = artifactToscaOperation.removeArtifactOnGraph(foundArtifact, componentId, instanceId, parentType, false);
1370 if (result.isRight()) {
1371 throw new StorageException(result.right().value(), foundArtifact.getArtifactDisplayName());
1373 return result.left().value();
1376 private Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> findArtifact(String artifactId,
1377 Component fetchedContainerComponent,
1379 ComponentTypeEnum componentType) {
1380 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> result = null;
1381 Map<String, ArtifactDefinition> artifacts = new HashMap<>();
1382 ComponentInstance foundInstance = null;
1383 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && StringUtils.isNotEmpty(parentId)) {
1384 Optional<ComponentInstance> componentInstanceOpt = fetchedContainerComponent.getComponentInstances().stream()
1385 .filter(i -> i.getUniqueId().equals(parentId)).findFirst();
1386 if (!componentInstanceOpt.isPresent()) {
1387 result = Either.right(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER);
1389 foundInstance = componentInstanceOpt.get();
1390 fetchArtifactsFromInstance(artifactId, artifacts, foundInstance);
1393 fetchArtifactsFromComponent(artifactId, fetchedContainerComponent, artifacts);
1395 if (result == null) {
1396 if (artifacts.containsKey(artifactId)) {
1397 result = Either.left(new ImmutablePair<>(artifacts.get(artifactId), foundInstance));
1399 result = Either.right(ActionStatus.ARTIFACT_NOT_FOUND);
1405 private void fetchArtifactsFromComponent(String artifactId, Component component, Map<String, ArtifactDefinition> artifacts) {
1406 Map<String, ArtifactDefinition> currArtifacts;
1407 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
1408 currArtifacts = component.getDeploymentArtifacts().values().stream()
1409 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, i -> i));
1410 if (MapUtils.isNotEmpty(currArtifacts)) {
1411 artifacts.putAll(currArtifacts);
1414 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1415 currArtifacts = component.getArtifacts().values().stream()
1416 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1417 if (MapUtils.isNotEmpty(currArtifacts)) {
1418 artifacts.putAll(currArtifacts);
1421 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1422 currArtifacts = component.getToscaArtifacts().values().stream()
1423 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1424 if (MapUtils.isNotEmpty(currArtifacts)) {
1425 artifacts.putAll(currArtifacts);
1430 private void fetchArtifactsFromInstance(String artifactId, Map<String, ArtifactDefinition> artifacts, ComponentInstance instance) {
1431 Map<String, ArtifactDefinition> currArtifacts;
1432 if (MapUtils.isNotEmpty(instance.getDeploymentArtifacts())) {
1433 currArtifacts = instance.getDeploymentArtifacts().values().stream()
1434 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1435 if (MapUtils.isNotEmpty(currArtifacts)) {
1436 artifacts.putAll(currArtifacts);
1439 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(instance.getArtifacts())) {
1440 currArtifacts = instance.getArtifacts().values().stream()
1441 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1442 if (MapUtils.isNotEmpty(currArtifacts)) {
1443 artifacts.putAll(currArtifacts);
1448 private StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) {
1449 StorageOperationStatus result;
1450 switch (cassandraStatus) {
1452 result = StorageOperationStatus.OK;
1455 result = StorageOperationStatus.NOT_FOUND;
1457 case CLUSTER_NOT_CONNECTED:
1458 case KEYSPACE_NOT_CONNECTED:
1459 result = StorageOperationStatus.CONNECTION_FAILURE;
1462 result = StorageOperationStatus.GENERAL_ERROR;
1468 private void resetMandatoryArtifactFields(ArtifactDefinition fetchedArtifact) {
1469 if (fetchedArtifact != null) {
1470 log.debug("Going to reset mandatory artifact {} fields. ", fetchedArtifact.getUniqueId());
1471 fetchedArtifact.setEsId(null);
1472 fetchedArtifact.setArtifactName(null);
1473 fetchedArtifact.setDescription(null);
1474 fetchedArtifact.setApiUrl(null);
1475 fetchedArtifact.setArtifactChecksum(null);
1476 nodeTemplateOperation.setDefaultArtifactTimeout(fetchedArtifact.getArtifactGroupType(), fetchedArtifact);
1477 fetchedArtifact.setArtifactUUID(null);
1478 long time = System.currentTimeMillis();
1479 fetchedArtifact.setPayloadUpdateDate(time);
1480 fetchedArtifact.setHeatParameters(null);
1481 fetchedArtifact.setHeatParamsUpdateDate(null);
1485 private StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId, ComponentTypeEnum componentType) {
1486 StorageOperationStatus error = StorageOperationStatus.OK;
1487 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1488 log.debug("Need to re-generate customization UUID for instance {}", instanceId);
1489 error = toscaOperationFacade.generateCustomizationUUIDOnInstance(componentId, instanceId);
1494 private ArtifactDefinition handleDownload(String componentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1495 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation
1496 .getArtifactById(componentId, artifactId, componentType, parent.getUniqueId());
1497 if (artifactById.isRight()) {
1498 throw new StorageException(artifactById.right().value());
1500 ArtifactDefinition artifactDefinition = artifactById.left().value();
1501 if (artifactDefinition == null) {
1502 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1504 return artifactDefinition;
1507 private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String componentId, Component parentComponent, ArtifactOperationInfo operation,
1508 ArtifactDefinition artifactInfo, String operationName,
1509 ComponentTypeEnum componentType) {
1510 String artifactLabel = artifactInfo.getArtifactLabel();
1511 if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) {
1512 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
1513 log.debug("missing artifact logical name for component {}", componentId);
1514 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1516 if (operation.isCreateOrLink() && !artifactInfo.getMandatory()) {
1517 if (operationName != null) {
1518 if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) {
1519 log.debug("artifact label cannot be set {}", artifactLabel);
1520 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED));
1522 artifactLabel = operationName;
1525 String displayName = artifactInfo.getArtifactDisplayName();
1526 if (displayName == null || displayName.isEmpty()) {
1527 displayName = artifactLabel;
1529 displayName = ValidationUtils.cleanArtifactDisplayName(displayName);
1530 artifactInfo.setArtifactDisplayName(displayName);
1531 if (!ValidationUtils.validateArtifactLabel(artifactLabel)) {
1532 log.debug("Invalid format form Artifact label : {}", artifactLabel);
1533 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1535 artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel);
1536 if (artifactLabel.isEmpty()) {
1537 log.debug("missing normalized artifact logical name for component {}", componentId);
1538 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1540 if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) {
1541 log.debug("Invalid lenght form Artifact label : {}", artifactLabel);
1542 return Either.right(componentsUtils
1543 .getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH)));
1545 if (!validateLabelUniqueness(componentId, parentComponent, artifactLabel, componentType)) {
1546 log.debug("Non unique Artifact label : {}", artifactLabel);
1547 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel));
1550 artifactInfo.setArtifactLabel(artifactLabel);
1551 return Either.left(ActionStatus.OK);
1554 private boolean validateLabelUniqueness(String componentId, Component parentComponent, String artifactLabel, ComponentTypeEnum componentType) {
1555 boolean isUnique = true;
1556 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts;
1557 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1558 artifacts = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1560 artifacts = artifactToscaOperation.getArtifacts(componentId);
1562 if (artifacts.isLeft()) {
1563 for (String label : artifacts.left().value().keySet()) {
1564 if (label.equals(artifactLabel)) {
1570 if (componentType == ComponentTypeEnum.RESOURCE && isUnique) {
1571 isUnique = isUniqueLabelInResourceInterfaces(componentId, artifactLabel);
1576 boolean validateArtifactNameUniqueness(String componentId, Component parentComponent, ArtifactDefinition artifactInfo,
1577 ComponentTypeEnum componentType) {
1578 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = getArtifacts(componentType, parentComponent, componentId,
1579 artifactInfo.getArtifactGroupType());
1580 String artifactName = artifactInfo.getArtifactName();
1581 if (artifacts.isLeft() && Objects.nonNull(artifacts.left().value())) {
1582 if (artifacts.left().value().values().stream().anyMatch(ad -> artifactName.equals(ad.getArtifactName())
1583 //check whether it is the same artifact we hold (by label)
1584 && !artifactInfo.getArtifactLabel().equals(ad.getArtifactLabel()))) {
1588 if (ComponentTypeEnum.RESOURCE == componentType) {
1589 return isUniqueArtifactNameInResourceInterfaces(componentId, artifactName, artifactInfo.getArtifactLabel());
1594 private boolean isUniqueArtifactNameInResourceInterfaces(String componentId, String artifactName, String artifactLabel) {
1595 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1596 .getAllInterfacesOfResource(componentId, true, true);
1597 if (allInterfacesOfResource.isLeft()) {
1598 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1599 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1600 .noneMatch(add -> artifactName.equals(add.getArtifactName()) && !artifactLabel.equals(add.getArtifactLabel()));
1605 private boolean isUniqueLabelInResourceInterfaces(String componentId, String artifactLabel) {
1606 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1607 .getAllInterfacesOfResource(componentId, true, true);
1608 if (allInterfacesOfResource.isLeft()) {
1609 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1610 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1611 .noneMatch(add -> artifactLabel.equals(add.getArtifactLabel()));
1616 private Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(ComponentTypeEnum componentType, Component parentComponent,
1618 ArtifactGroupTypeEnum artifactGroupType) {
1619 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse;
1620 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1621 artifactsResponse = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1623 artifactsResponse = artifactToscaOperation.getArtifacts(componentId);
1625 if (artifactsResponse.isRight() && artifactsResponse.right().value() == StorageOperationStatus.NOT_FOUND) {
1626 log.debug("failed to retrieve artifacts for {} ", componentId);
1627 return Either.right(artifactsResponse.right().value());
1629 return Either.left(artifactsResponse.left().value().entrySet().stream().filter(x -> artifactGroupType == x.getValue().getArtifactGroupType())
1630 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
1633 // ***************************************************************
1634 private Either<ArtifactDefinition, Operation> createArtifact(Component parent, String parentId, ArtifactDefinition artifactInfo,
1635 byte[] decodedPayload, ComponentTypeEnum componentTypeEnum,
1636 AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) {
1637 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
1638 if (artifactData == null) {
1639 BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact");
1640 log.debug("Failed to create artifact object for ES.");
1641 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1643 ComponentInstance foundInstance = findComponentInstance(parentId, parent);
1644 String instanceId = null;
1645 if (foundInstance != null) {
1646 if (foundInstance.isArtifactExists(artifactInfo.getArtifactGroupType(), artifactInfo.getArtifactLabel())) {
1647 log.debug("Failed to create artifact, already exists");
1648 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, artifactInfo.getArtifactLabel());
1650 instanceId = foundInstance.getUniqueId();
1652 // set on graph object id of artifact in ES!
1653 artifactInfo.setEsId(artifactData.getId());
1654 Either<ArtifactDefinition, Operation> operationResult;
1655 if (interfaceType != null && operationName != null) {
1656 // lifecycle artifact
1657 Operation operation = convertToOperation(artifactInfo, operationName);
1658 Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation
1659 .updateInterfaceOperation(parentId, interfaceType, operationName, operation);
1660 if (result.isRight()) {
1661 throw new StorageException(result.right().value());
1663 operationResult = Either.right(result.left().value());
1665 // information/deployment/api artifacts
1666 NodeTypeEnum nodeType = convertParentType(componentTypeEnum);
1667 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
1668 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
1669 if (result.isRight()) {
1670 throw new StorageException(result.right().value());
1672 ArtifactDefinition artifactDefinition = result.left().value();
1673 artifactData.setId(artifactDefinition.getEsId());
1674 operationResult = Either.left(artifactDefinition);
1675 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum) != StorageOperationStatus.OK) {
1676 throw new StorageException(generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum));
1679 saveArtifactInCassandra(artifactData, parent, artifactInfo, "", "", auditingActionEnum, componentTypeEnum);
1680 return operationResult;
1683 private ComponentInstance findComponentInstance(String componentInstanceId, Component containerComponent) {
1684 ComponentInstance foundInstance = null;
1685 if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
1686 foundInstance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst()
1689 return foundInstance;
1692 private void validateDeploymentArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1693 final ComponentTypeEnum componentType = component.getComponentType();
1694 if (componentType != ComponentTypeEnum.RESOURCE && componentType != ComponentTypeEnum.SERVICE
1695 && componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1696 log.debug("Invalid component type '{}' for artifact. " + "Expected Resource, Component or Resource Instance", componentType.getValue());
1697 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, componentType.getValue(),
1698 "Service, Resource or ResourceInstance", componentType.getValue());
1700 final String artifactType = artifactInfo.getArtifactType();
1701 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1702 if (artifactConfiguration == null) {
1703 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1705 validateArtifactType(componentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1706 if (componentType == ComponentTypeEnum.RESOURCE || componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1707 final Resource resource = (Resource) component;
1708 final ResourceTypeEnum resourceType = resource.getResourceType();
1709 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1711 validateArtifactExtension(artifactConfiguration, artifactInfo);
1714 private void validateHeatArtifact(final Component parentComponent, final String componentId, final ArtifactDefinition artifactDefinition) {
1715 final String artifactType = artifactDefinition.getArtifactType();
1716 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1717 if (artifactTypeEnum == null) {
1720 switch (artifactTypeEnum) {
1724 validateHeatTimeoutValue(artifactDefinition);
1727 validateHeatEnvDeploymentArtifact(parentComponent, componentId, artifactDefinition);
1734 private void setArtifactTimeout(final ArtifactDefinition newArtifactInfo, final ArtifactDefinition existingArtifactInfo) {
1735 final String artifactType = newArtifactInfo.getArtifactType();
1736 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1737 if (artifactTypeEnum == null) {
1738 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1741 switch (artifactTypeEnum) {
1745 if (newArtifactInfo.getTimeout() == null) {
1746 if (existingArtifactInfo == null) {
1747 newArtifactInfo.setTimeout(NodeTemplateOperation.getDefaultHeatTimeout());
1749 newArtifactInfo.setTimeout(existingArtifactInfo.getTimeout());
1754 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1760 void validateDeploymentArtifactTypeIsLegalForParent(ArtifactDefinition artifactInfo, ArtifactTypeEnum artifactType,
1761 Map<String, ArtifactTypeConfig> resourceDeploymentArtifacts) {
1762 if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) {
1763 log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType());
1764 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
1768 Optional<ArtifactConfiguration> loadArtifactTypeConfig(final String artifactType) {
1769 if (artifactType == null) {
1770 return Optional.empty();
1772 final List<ArtifactConfiguration> artifactConfigurationList = ConfigurationManager.getConfigurationManager().getConfiguration()
1774 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
1775 return Optional.empty();
1777 return artifactConfigurationList.stream().filter(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType))
1781 private Either<Boolean, ResponseFormat> extractHeatParameters(ArtifactDefinition artifactInfo) {
1782 // extract heat parameters
1783 if (artifactInfo.getPayloadData() != null) {
1784 String heatDecodedPayload = new String(Base64.decodeBase64(artifactInfo.getPayloadData()));
1785 Either<List<HeatParameterDefinition>, ResultStatusEnum> heatParameters = ImportUtils
1786 .getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo.getArtifactType());
1787 if (heatParameters.isRight() && (heatParameters.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND)) {
1788 log.info("failed to parse heat parameters ");
1789 ResponseFormat responseFormat = componentsUtils
1790 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactType());
1791 return Either.right(responseFormat);
1792 } else if (heatParameters.isLeft() && heatParameters.left().value() != null) {
1793 artifactInfo.setListHeatParameters(heatParameters.left().value());
1796 return Either.left(true);
1800 void validateArtifactExtension(final ArtifactConfiguration artifactConfiguration, final ArtifactDefinition artifactDefinition) {
1801 final List<String> acceptedTypes = artifactConfiguration.getAcceptedTypes();
1803 * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted.
1805 if (CollectionUtils.isEmpty(acceptedTypes)) {
1808 final String artifactName = artifactDefinition.getArtifactName();
1809 final String fileExtension = FilenameUtils.getExtension(artifactName);
1810 if (fileExtension == null || !acceptedTypes.contains(fileExtension.toLowerCase())) {
1811 final String artifactType = artifactDefinition.getArtifactType();
1812 log.debug("File extension \"{}\" is not allowed for artifact type \"{}\"", fileExtension, artifactType);
1813 throw new ByActionStatusComponentException(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, artifactType);
1818 void validateHeatEnvDeploymentArtifact(final Component parentComponent, final String parentId, final ArtifactDefinition artifactInfo) {
1819 final Wrapper<ArtifactDefinition> heatMDWrapper = new Wrapper<>();
1820 final Wrapper<byte[]> payloadWrapper = new Wrapper<>();
1821 validateYaml(artifactInfo);
1822 validateHeatExist(parentComponent.getUniqueId(), parentId, heatMDWrapper, artifactInfo, parentComponent.getComponentType());
1823 if (!heatMDWrapper.isEmpty()) {
1824 fillArtifactPayload(payloadWrapper, heatMDWrapper.getInnerElement());
1826 if (!heatMDWrapper.isEmpty()) {
1827 validateEnvVsHeat(artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement());
1831 public void fillArtifactPayload(Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactDefinition) {
1832 if (ArrayUtils.isEmpty(artifactDefinition.getPayloadData())) {
1833 Either<DAOArtifactData, CassandraOperationStatus> eitherArtifactData = artifactCassandraDao.getArtifact(artifactDefinition.getEsId());
1834 if (eitherArtifactData.isLeft()) {
1835 byte[] data = eitherArtifactData.left().value().getDataAsArray();
1836 payloadWrapper.setInnerElement(Base64.encodeBase64(data));
1838 log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName());
1839 throw new StorageException(DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()));
1842 payloadWrapper.setInnerElement(artifactDefinition.getPayloadData());
1846 private void validateEnvVsHeat(ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) {
1847 String envPayload = new String(Base64.decodeBase64(envArtifact.getPayloadData()));
1848 Map<String, Object> heatEnvToscaJson = (Map<String, Object>) new Yaml().load(envPayload);
1849 String heatDecodedPayload = new String(Base64.decodeBase64(heatPayloadData));
1850 Map<String, Object> heatToscaJson = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
1851 Either<Map<String, Object>, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils
1852 .findFirstToscaMapElement(heatEnvToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1853 if (eitherHeatEnvProperties.isRight()) {
1854 log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName());
1855 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat Env");
1857 Either<Map<String, Object>, ResultStatusEnum> eitherHeatProperties = ImportUtils
1858 .findFirstToscaMapElement(heatToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1859 if (eitherHeatProperties.isRight()) {
1860 log.debug("Invalid heat format for file:{}", heatArtifact.getArtifactName());
1861 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat");
1863 Set<String> heatPropertiesKeys = eitherHeatProperties.left().value().keySet();
1864 Set<String> heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet();
1865 heatEnvPropertiesKeys.removeAll(heatPropertiesKeys);
1866 if (!heatEnvPropertiesKeys.isEmpty()) {
1867 log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(),
1868 heatArtifact.getArtifactName());
1869 throw new ByActionStatusComponentException(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(),
1870 heatArtifact.getArtifactName());
1874 private void validateYaml(ArtifactDefinition artifactInfo) {
1875 YamlToObjectConverter yamlConverter = new YamlToObjectConverter();
1876 boolean isYamlValid = yamlConverter.isValidYamlEncoded64(artifactInfo.getPayloadData());
1878 log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName());
1879 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType());
1883 private void validateSingleDeploymentArtifactName(final String artifactName, final Component parentComponent) {
1884 boolean artifactNameFound = false;
1885 final Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, null).iterator();
1886 while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) {
1887 artifactNameFound = artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName());
1889 if (artifactNameFound) {
1890 final ComponentTypeEnum componentType = parentComponent.getComponentType();
1891 log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName);
1892 throw new ByActionStatusComponentException(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, componentType.getValue(),
1893 parentComponent.getName(), artifactName);
1897 private void validateHeatExist(String componentId, String parentRiId, Wrapper<ArtifactDefinition> heatArtifactMDWrapper,
1898 ArtifactDefinition heatEnvArtifact, ComponentTypeEnum componentType) {
1899 final Either<ArtifactDefinition, StorageOperationStatus> res = artifactToscaOperation
1900 .getHeatArtifactByHeatEnvId(parentRiId, heatEnvArtifact, componentId, componentType);
1901 if (res.isRight()) {
1902 throw new ByActionStatusComponentException(ActionStatus.MISSING_HEAT);
1904 heatArtifactMDWrapper.setInnerElement(res.left().value());
1908 void validateHeatTimeoutValue(final ArtifactDefinition artifactInfo) {
1909 log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel());
1910 // timeout > 0 for HEAT artifacts
1911 if (artifactInfo.getTimeout() == null || artifactInfo.getTimeout() < 1) {
1912 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
1914 // US649856 - Allow several HEAT files on Resource
1915 log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel());
1919 void validateResourceType(final ResourceTypeEnum resourceType, final ArtifactDefinition artifactInfo, final List<String> typeList) {
1920 if (CollectionUtils.isEmpty(typeList) || typeList.contains(resourceType.getValue())) {
1923 final String listToString = typeList.stream().collect(Collectors.joining(", "));
1924 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, artifactInfo.getArtifactGroupType().getType(),
1925 listToString, resourceType.getValue());
1929 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters(ArtifactDefinition artifactInfo, String artifactType) {
1930 if (artifactInfo.getHeatParameters() != null) {
1931 for (HeatParameterDefinition heatParam : artifactInfo.getListHeatParameters()) {
1932 String parameterType = heatParam.getType();
1933 HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType);
1934 String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType();
1935 if (heatParameterType == null) {
1936 ResponseFormat responseFormat = componentsUtils
1937 .getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam.getType());
1938 return Either.right(responseFormat);
1940 StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam);
1941 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
1942 log.debug("Heat parameter {} is invalid. Status is {}", heatParam.getName(), validateAndUpdateProperty);
1943 ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE;
1944 ResponseFormat responseFormat = componentsUtils
1945 .getResponseFormat(status, artifactTypeStr, heatParam.getType(), heatParam.getName());
1946 return Either.right(responseFormat);
1950 return Either.left(artifactInfo);
1953 public List<ArtifactDefinition> getDeploymentArtifacts(final Component component, final String ciId) {
1954 final ComponentTypeEnum componentType = component.getComponentType();
1955 if (component.getDeploymentArtifacts() == null) {
1956 return Collections.emptyList();
1958 final List<ArtifactDefinition> deploymentArtifacts = new ArrayList<>();
1959 if (ComponentTypeEnum.RESOURCE == componentType && ciId != null) {
1960 final Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(component, ciId, null, null, null);
1961 if (getRI.isRight()) {
1962 return Collections.emptyList();
1964 final ComponentInstance ri = getRI.left().value();
1965 if (ri.getDeploymentArtifacts() != null) {
1966 deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values());
1969 deploymentArtifacts.addAll(component.getDeploymentArtifacts().values());
1971 return deploymentArtifacts;
1974 private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) {
1975 // on create if null add informational to current
1976 if (artifactInfo.getArtifactGroupType() == null) {
1977 artifactInfo.setArtifactGroupType(type);
1979 if (artifactInfo.getUniqueId() != null) {
1980 log.error("artifact uniqid cannot be set ignoring");
1982 artifactInfo.setUniqueId(null);
1983 if (artifactInfo.getArtifactRef() != null) {
1984 log.error("artifact ref cannot be set ignoring");
1986 artifactInfo.setArtifactRef(null);
1987 if (artifactInfo.getArtifactRepository() != null) {
1988 log.error("artifact repository cannot be set ignoring");
1990 artifactInfo.setArtifactRepository(null);
1991 if (artifactInfo.getUserIdCreator() != null) {
1992 log.error("creator uuid cannot be set ignoring");
1994 artifactInfo.setArtifactCreator(user.getUserId());
1995 if (artifactInfo.getUserIdLastUpdater() != null) {
1996 log.error("userId of last updater cannot be set ignoring");
1998 artifactInfo.setUserIdLastUpdater(user.getUserId());
1999 if (artifactInfo.getCreatorFullName() != null) {
2000 log.error("creator Full name cannot be set ignoring");
2002 String fullName = user.getFirstName() + " " + user.getLastName();
2003 artifactInfo.setUpdaterFullName(fullName);
2004 if (artifactInfo.getUpdaterFullName() != null) {
2005 log.error("updater Full name cannot be set ignoring");
2007 artifactInfo.setUpdaterFullName(fullName);
2008 if (artifactInfo.getCreationDate() != null) {
2009 log.error("Creation Date cannot be set ignoring");
2011 long time = System.currentTimeMillis();
2012 artifactInfo.setCreationDate(time);
2013 if (artifactInfo.getLastUpdateDate() != null) {
2014 log.error("Last Update Date cannot be set ignoring");
2016 artifactInfo.setLastUpdateDate(time);
2017 if (artifactInfo.getEsId() != null) {
2018 log.error("es id cannot be set ignoring");
2020 artifactInfo.setEsId(null);
2023 private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName,
2024 String operationName) {
2025 String id = artifactId;
2026 if (artifactId == null || artifactId.isEmpty()) {
2027 String uniqueId = null;
2028 if (interfaceName != null && operationName != null) {
2029 uniqueId = UniqueIdBuilder
2030 .buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo.getArtifactLabel());
2032 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel());
2034 artifactInfo.setUniqueId(uniqueId);
2035 artifactInfo.setEsId(uniqueId);
2038 artifactInfo.setUniqueId(artifactId);
2039 artifactInfo.setEsId(artifactId);
2044 private Either<Boolean, ResponseFormat> validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2045 if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) {
2046 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD));
2048 return Either.left(true);
2052 Either<Boolean, ResponseFormat> validateAndSetArtifactName(ArtifactDefinition artifactInfo) {
2053 if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) {
2054 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2056 String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName());
2057 if (normalizeFileName == null || normalizeFileName.isEmpty()) {
2058 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2060 artifactInfo.setArtifactName(normalizeFileName);
2061 if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) {
2062 return Either.right(
2063 componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH)));
2065 return Either.left(true);
2068 private void validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2069 if (StringUtils.isEmpty(artifactInfo.getArtifactType())) {
2070 log.info("artifact type is missing operation ignored");
2071 throw new ByActionStatusComponentException(ActionStatus.MISSING_ARTIFACT_TYPE);
2073 if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) {
2074 log.info("artifact type cannot be changed operation ignored");
2075 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2079 private Either<ArtifactDefinition, ResponseFormat> validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo,
2080 ArtifactDefinition currentArtifact) {
2081 if (Objects.nonNull(artifactInfo) && Objects.nonNull(currentArtifact)) {
2082 if (artifactInfo.getArtifactGroupType() == null) {
2083 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2084 } else if (!currentArtifact.getArtifactGroupType().getType().equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) {
2085 log.info("artifact group type cannot be changed. operation failed");
2086 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2089 return Either.left(artifactInfo);
2092 private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact,
2093 ArtifactGroupTypeEnum type) {
2094 // on update if null add informational to current
2095 if (currentArtifact.getArtifactGroupType() == null && type != null) {
2096 currentArtifact.setArtifactGroupType(type);
2098 if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) {
2099 log.error("artifact uniqid cannot be set ignoring");
2101 artifactInfo.setUniqueId(currentArtifact.getUniqueId());
2102 if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef().equals(artifactInfo.getArtifactRef())) {
2103 log.error("artifact ref cannot be set ignoring");
2105 artifactInfo.setArtifactRef(currentArtifact.getArtifactRef());
2106 if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository().equals(artifactInfo.getArtifactRepository())) {
2107 log.error("artifact repository cannot be set ignoring");
2109 artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository());
2110 if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator().equals(artifactInfo.getUserIdCreator())) {
2111 log.error("creator uuid cannot be set ignoring");
2113 artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator());
2114 if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator().equals(artifactInfo.getArtifactCreator())) {
2115 log.error("artifact creator cannot be set ignoring");
2117 artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator());
2118 if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater().equals(artifactInfo.getUserIdLastUpdater())) {
2119 log.error("userId of last updater cannot be set ignoring");
2121 artifactInfo.setUserIdLastUpdater(user.getUserId());
2122 if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName().equals(artifactInfo.getCreatorFullName())) {
2123 log.error("creator Full name cannot be set ignoring");
2125 artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName());
2126 if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName().equals(artifactInfo.getUpdaterFullName())) {
2127 log.error("updater Full name cannot be set ignoring");
2129 String fullName = user.getFirstName() + " " + user.getLastName();
2130 artifactInfo.setUpdaterFullName(fullName);
2131 if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate().equals(artifactInfo.getCreationDate())) {
2132 log.error("Creation Date cannot be set ignoring");
2134 artifactInfo.setCreationDate(currentArtifact.getCreationDate());
2135 if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate().equals(artifactInfo.getLastUpdateDate())) {
2136 log.error("Last Update Date cannot be set ignoring");
2138 long time = System.currentTimeMillis();
2139 artifactInfo.setLastUpdateDate(time);
2140 if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) {
2141 log.error("es id cannot be set ignoring");
2143 artifactInfo.setEsId(currentArtifact.getUniqueId());
2144 if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName()
2145 .equals(artifactInfo.getArtifactDisplayName())) {
2146 log.error(" Artifact Display Name cannot be set ignoring");
2148 artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName());
2149 if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi().equals(artifactInfo.getServiceApi())) {
2150 log.debug("serviceApi cannot be set. ignoring.");
2152 artifactInfo.setServiceApi(currentArtifact.getServiceApi());
2153 if (artifactInfo.getArtifactGroupType() != null && currentArtifact.getArtifactGroupType() != artifactInfo.getArtifactGroupType()) {
2154 log.debug("artifact group cannot be set. ignoring.");
2156 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2157 artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion());
2158 if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID().isEmpty() && !currentArtifact.getArtifactUUID()
2159 .equals(artifactInfo.getArtifactUUID())) {
2160 log.debug("artifact UUID cannot be set. ignoring.");
2162 artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID());
2163 if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo.getHeatParameters().isEmpty()
2164 && !currentArtifact.getHeatParameters().isEmpty()) {
2165 checkAndSetUnupdatableHeatParams(artifactInfo.getListHeatParameters(), currentArtifact.getListHeatParameters());
2169 private void checkAndSetUnupdatableHeatParams(List<HeatParameterDefinition> heatParameters, List<HeatParameterDefinition> currentParameters) {
2170 Map<String, HeatParameterDefinition> currentParametersMap = getMapOfParameters(currentParameters);
2171 for (HeatParameterDefinition parameter : heatParameters) {
2172 HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId());
2173 if (currentParam != null) {
2174 if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) {
2175 log.debug("heat parameter name cannot be updated ({}). ignoring.", parameter.getName());
2176 parameter.setName(currentParam.getName());
2178 if (parameter.getDefaultValue() != null && !parameter.getDefaultValue().equalsIgnoreCase(currentParam.getDefaultValue())) {
2179 log.debug("heat parameter defaultValue cannot be updated ({}). ignoring.", parameter.getDefaultValue());
2180 parameter.setDefaultValue(currentParam.getDefaultValue());
2182 if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) {
2183 log.debug("heat parameter type cannot be updated ({}). ignoring.", parameter.getType());
2184 parameter.setType(currentParam.getType());
2186 if (parameter.getDescription() != null && !parameter.getDescription().equalsIgnoreCase(currentParam.getDescription())) {
2187 log.debug("heat parameter description cannot be updated ({}). ignoring.", parameter.getDescription());
2188 parameter.setDescription(currentParam.getDescription());
2190 // check and set current value
2191 if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) {
2192 log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue());
2193 parameter.setCurrentValue(currentParam.getDefaultValue());
2199 private Map<String, HeatParameterDefinition> getMapOfParameters(List<HeatParameterDefinition> currentParameters) {
2200 Map<String, HeatParameterDefinition> currentParamsMap = new HashMap<>();
2201 for (HeatParameterDefinition param : currentParameters) {
2202 currentParamsMap.put(param.getUniqueId(), param);
2204 return currentParamsMap;
2207 private Either<Boolean, ResponseFormat> validateAndServiceApiUrl(ArtifactDefinition artifactInfo) {
2208 if (!ValidationUtils.validateStringNotEmpty(artifactInfo.getApiUrl())) {
2209 log.debug("Artifact url cannot be empty.");
2210 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL));
2212 artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase());
2213 if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) {
2214 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL));
2216 if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) {
2218 .right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH)));
2220 return Either.left(true);
2223 private Either<Boolean, ResponseFormat> validateAndCleanDescription(ArtifactDefinition artifactInfo) {
2224 if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) {
2225 log.debug("Artifact description cannot be empty.");
2226 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION));
2228 String description = artifactInfo.getDescription();
2229 description = ValidationUtils.removeNoneUtf8Chars(description);
2230 description = ValidationUtils.normaliseWhitespace(description);
2231 description = ValidationUtils.stripOctets(description);
2232 description = ValidationUtils.removeHtmlTagsOnly(description);
2233 if (!ValidationUtils.validateIsEnglish(description)) {
2234 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2236 if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) {
2237 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION,
2238 String.valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)));
2240 artifactInfo.setDescription(description);
2241 return Either.left(true);
2244 private <T> Either<ArtifactDefinition, T> updateArtifactFlow(Component parent, String parentId, String artifactId,
2245 ArtifactDefinition artifactInfo, byte[] decodedPayload,
2246 ComponentTypeEnum componentType, AuditingActionEnum auditingAction) {
2247 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
2248 if (artifactData == null) {
2249 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2250 log.debug("Failed to create artifact object for ES.");
2251 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
2253 log.debug("Entry on graph is updated. Update artifact in ES");
2254 // Changing previous and current artifactId for auditing
2255 String currArtifactId = artifactInfo.getUniqueId();
2256 NodeTypeEnum parentType = convertParentType(componentType);
2257 if (decodedPayload == null) {
2258 if (!artifactInfo.getMandatory() || artifactInfo.getEsId() != null) {
2259 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactInfo.getEsId());
2260 if (artifactFromCassandra.isRight()) {
2261 throw new StorageException(artifactFromCassandra.right().value());
2263 // clone data to new artifact
2264 artifactData.setData(artifactFromCassandra.left().value().getData());
2265 artifactData.setId(artifactFromCassandra.left().value().getId());
2267 } else if (artifactInfo.getEsId() == null) {
2268 artifactInfo.setEsId(artifactInfo.getUniqueId());
2269 artifactData.setId(artifactInfo.getUniqueId());
2271 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
2272 .updateArtifactOnResource(artifactInfo, parent, artifactId, parentType, parentId, true);
2273 if (result.isRight()) {
2274 throw new StorageException(result.right().value());
2276 ArtifactDefinition artifactDefinition = result.left().value();
2277 updateGeneratedIdInHeatEnv(parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType);
2278 StorageOperationStatus storageOperationStatus = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
2279 if (storageOperationStatus != StorageOperationStatus.OK) {
2280 throw new StorageException(storageOperationStatus);
2282 if (artifactData.getData() != null) {
2283 if (!artifactDefinition.getDuplicated() || artifactData.getId() == null) {
2284 artifactData.setId(artifactDefinition.getEsId());
2286 saveArtifactInCassandra(artifactData, parent, artifactInfo, currArtifactId, artifactId, auditingAction, componentType);
2288 return Either.left(artifactDefinition);
2291 private String updateGeneratedIdInHeatEnv(Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo,
2292 ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2293 if (NodeTypeEnum.Resource == parentType) {
2294 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parent, parentId, artifactId, artifactInfo, artifactDefinition,
2297 return artifactDefinition.getUniqueId();
2300 private String updateGeneratedIdInHeatEnv(Map<String, ArtifactDefinition> deploymentArtifacts, Component parentComponent, String parentId,
2301 String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2302 NodeTypeEnum parentType, boolean isInstanceArtifact) {
2303 String artifactUniqueId;
2304 artifactUniqueId = artifactDefinition.getUniqueId();
2305 String artifactType = artifactInfo.getArtifactType();
2306 if ((ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType)
2307 || ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType)) && !artifactUniqueId.equals(artifactId)) {
2308 // need to update the generated id in heat env
2309 Optional<Entry<String, ArtifactDefinition>> findFirst = deploymentArtifacts.entrySet().stream()
2310 .filter(a -> artifactId.equals(a.getValue().getGeneratedFromId())).findFirst();
2311 if (findFirst.isPresent()) {
2312 ArtifactDefinition artifactEnvInfo = findFirst.get().getValue();
2313 artifactEnvInfo.setIsFromCsar(artifactDefinition.getIsFromCsar());
2314 artifactEnvInfo.setArtifactChecksum(null);
2315 if (isInstanceArtifact) {
2316 artifactToscaOperation
2317 .updateHeatEnvArtifactOnInstance(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2319 artifactToscaOperation
2320 .updateHeatEnvArtifact(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2324 return artifactUniqueId;
2327 private String updateGeneratedIdInHeatEnvOnInstance(ComponentInstance parent, Component parentComponent, String artifactId,
2328 ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2329 NodeTypeEnum parentType) {
2330 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parentComponent, parent.getUniqueId(), artifactId, artifactInfo,
2331 artifactDefinition, parentType, true);
2335 private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) {
2336 log.trace("Starting payload handling");
2337 byte[] payload = artifactInfo.getPayloadData();
2338 byte[] decodedPayload = null;
2339 if (payload != null && payload.length != 0) {
2340 // the generated artifacts were already decoded by the handler
2341 decodedPayload = artifactInfo.getGenerated() ? payload : Base64.decodeBase64(payload);
2342 if (decodedPayload.length == 0) {
2343 log.debug("Failed to decode the payload.");
2344 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
2345 return Either.right(responseFormat);
2347 String checkSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(decodedPayload);
2348 artifactInfo.setArtifactChecksum(checkSum);
2349 log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum);
2350 // Specific payload validations of different types
2351 Either<Boolean, ResponseFormat> result = Either.left(true);
2352 if (isDeploymentArtifact(artifactInfo)) {
2353 log.trace("Starting deployment artifacts payload validation");
2354 String artifactType = artifactInfo.getArtifactType();
2355 String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName());
2356 PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension);
2357 final Optional<ResponseFormat> pmDictionaryError = validateIfPmDictionary(artifactType, decodedPayload);
2358 if (pmDictionaryError.isPresent()) {
2359 return Either.right(pmDictionaryError.get());
2361 Either<Boolean, ActionStatus> isPayloadValid = payloadType.isValid(decodedPayload);
2362 if (isPayloadValid.isRight()) {
2363 ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType);
2364 return Either.right(responseFormat);
2366 if (payloadType.isHeatRelated()) {
2367 log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType);
2368 result = extractHeatParameters(artifactInfo);
2371 if (result.isRight()) {
2372 return Either.right(result.right().value());
2374 } // null/empty payload is normal if called from metadata update ONLY.
2376 // The validation of whether this is metadata/payload update case is
2378 // currently done separately
2380 if (!isArtifactMetadataUpdate) {
2381 log.debug("In artifact: {} Payload is missing.", artifactInfo.getArtifactName());
2382 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
2383 return Either.right(responseFormat);
2386 log.trace("Ended payload handling");
2387 return Either.left(decodedPayload);
2390 private Optional<ResponseFormat> validateIfPmDictionary(String artifactType, byte[] decodedPayload) {
2391 return new PMDictionaryValidator().validateIfPmDictionary(artifactType, decodedPayload).map(this::preparePmDictionaryResponse);
2394 private ResponseFormat preparePmDictionaryResponse(String errorMessage) {
2395 return componentsUtils.getResponseFormat(ActionStatus.INVALID_PM_DICTIONARY_FILE, errorMessage);
2398 public Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface(String resourceId, String userUserId, String artifactId,
2399 boolean inTransaction) {
2400 return toscaOperationFacade.getToscaElement(resourceId, JsonParseFlagEnum.ParseMetadata).right().map(componentsUtils.toResponseFormat())
2401 .left().bind(parentComponent -> {
2402 User user = new User(userUserId);
2403 return handleDelete(resourceId, artifactId, user, parentComponent, false, inTransaction);
2407 private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) {
2408 Operation op = new Operation();
2409 long time = System.currentTimeMillis();
2410 op.setCreationDate(time);
2411 String artifactName = artifactInfo.getArtifactName();
2412 artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName));
2413 op.setImplementation(artifactInfo);
2414 op.setLastUpdateDate(time);
2418 private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) {
2419 String newArtifactName = operationName + "_" + artifactName;
2420 log.trace("converting artifact name {} to {}", artifactName, newArtifactName);
2421 return newArtifactName;
2425 public byte[] downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion,
2426 String artifactName) {
2427 // General validation
2428 if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) {
2429 log.debug(NULL_PARAMETER);
2430 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2432 // Normalizing artifact name
2433 artifactName = ValidationUtils.normalizeFileName(artifactName);
2434 // Resource validation
2435 Resource resource = validateResourceNameAndVersion(resourceName, resourceVersion);
2436 String resourceId = resource.getUniqueId();
2437 // Service validation
2438 Service validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion);
2439 Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts();
2440 if (artifacts == null || artifacts.isEmpty()) {
2441 log.debug("Deployment artifacts of resource {} are not found", resourceId);
2442 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2444 ArtifactDefinition deploymentArtifact = null;
2445 for (ArtifactDefinition artifactDefinition : artifacts.values()) {
2446 if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName().equals(artifactName)) {
2447 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2448 deploymentArtifact = artifactDefinition;
2452 if (deploymentArtifact == null) {
2453 log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId);
2454 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2456 // Downloading the artifact
2457 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deploymentArtifact);
2458 log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId());
2459 return downloadArtifactEither.getRight();
2463 public byte[] downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) {
2464 // General validation
2465 if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) {
2466 log.debug(NULL_PARAMETER);
2467 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2469 // Normalizing artifact name
2470 artifactName = ValidationUtils.normalizeFileName(artifactName);
2471 // Service validation
2472 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2473 // ResourceInstance validation
2474 ComponentInstance resourceInstance = validateResourceInstance(service, resourceInstanceName);
2475 Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
2476 final String finalArtifactName = artifactName;
2477 Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName);
2478 ArtifactDefinition deployableArtifact =
2479 artifacts == null ? null : artifacts.values().stream().filter(filterArtifactByName).findFirst().orElse(null);
2480 if (deployableArtifact == null) {
2481 log.debug("Deployment artifact with name {} not found", artifactName);
2482 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
2484 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2485 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deployableArtifact);
2486 log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId());
2487 return downloadArtifactEither.getRight();
2490 private ComponentInstance validateResourceInstance(Service service, String resourceInstanceName) {
2491 List<ComponentInstance> riList = service.getComponentInstances();
2492 for (ComponentInstance ri : riList) {
2493 if (ri.getNormalizedName().equals(resourceInstanceName)) {
2497 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName);
2500 private ComponentInstance validateResourceInstanceById(Component component, String resourceInstanceId) {
2501 List<ComponentInstance> riList = component.getComponentInstances();
2502 for (ComponentInstance ri : riList) {
2503 if (ri.getUniqueId().equals(resourceInstanceId)) {
2507 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceInstanceId);
2510 private Service validateServiceNameAndVersion(String serviceName, String serviceVersion) {
2511 Either<List<Service>, StorageOperationStatus> serviceListBySystemName = toscaOperationFacade
2512 .getBySystemName(ComponentTypeEnum.SERVICE, serviceName);
2513 if (serviceListBySystemName.isRight()) {
2514 log.debug("Couldn't fetch any service with name {}", serviceName);
2515 throw new ByActionStatusComponentException(
2516 componentsUtils.convertFromStorageResponse(serviceListBySystemName.right().value(), ComponentTypeEnum.SERVICE), serviceName);
2518 List<Service> serviceList = serviceListBySystemName.left().value();
2519 if (serviceList == null || serviceList.isEmpty()) {
2520 log.debug("Couldn't fetch any service with name {}", serviceName);
2521 throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceName);
2523 Service foundService = null;
2524 for (Service service : serviceList) {
2525 if (service.getVersion().equals(serviceVersion)) {
2526 log.trace("Found service with version {}", serviceVersion);
2527 foundService = service;
2531 if (foundService == null) {
2532 log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName);
2533 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE.getValue(),
2536 return foundService;
2539 private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2540 Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade
2541 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2542 if (resourceListBySystemName.isRight()) {
2543 log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2544 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()),
2547 return resourceListBySystemName.left().value();
2550 public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2552 log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion,
2554 if (serviceName == null || serviceVersion == null || artifactName == null) {
2555 log.debug(NULL_PARAMETER);
2556 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2558 // Normalizing artifact name
2559 final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2560 // Service validation
2561 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2562 // Looking for deployment or tosca artifacts
2563 String serviceId = service.getUniqueId();
2564 if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2565 log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2566 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2568 Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2569 if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2570 foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2571 // filters artifact by name
2572 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2574 if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2575 foundArtifactOptl = service.getToscaArtifacts().values().stream()
2576 // filters TOSCA artifact by name
2577 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2579 if (!foundArtifactOptl.isPresent()) {
2580 log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2581 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2583 log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2584 // Downloading the artifact
2585 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl.get());
2586 log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2587 return downloadArtifactEither.getRight();
2590 public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2591 log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2592 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2593 if (artifactById.isRight()) {
2594 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2595 log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2596 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2598 ArtifactDefinition artifactDefinition = artifactById.left().value();
2599 if (artifactDefinition == null) {
2600 log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2601 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2603 return downloadArtifact(artifactDefinition);
2606 private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId,
2607 ComponentTypeEnum componentType, String containerComponentType) {
2608 ComponentTypeEnum componentForAudit =
2609 null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
2610 componentForAudit.getNodeType();
2611 Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaFullElement(componentId);
2612 if (componentResult.isRight()) {
2613 ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND
2614 : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
2615 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
2616 log.debug("Service not found, serviceId {}", componentId);
2617 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
2618 throw new ByActionStatusComponentException(status, componentId);
2620 return componentResult.left().value();
2623 private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId,
2624 ArtifactOperationInfo operation) {
2625 if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
2627 validateCanWorkOnComponent(component, userId);
2628 } catch (ComponentException e) {
2629 String uniqueId = component.getUniqueId();
2630 log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId);
2631 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(), component.getComponentType(),
2638 private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId,
2639 ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
2640 if (operation.isNotDownload()) {
2641 String role = user.getRole();
2642 if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
2643 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2644 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
2645 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2646 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
2651 private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId,
2652 ComponentTypeEnum componentType, boolean inTransaction) {
2655 user = validateUserExists(userId);
2656 } catch (ByResponseFormatComponentException e) {
2657 ResponseFormat responseFormat = e.getResponseFormat();
2658 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2660 } catch (ByActionStatusComponentException e) {
2661 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2662 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2668 private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId, ResponseFormat responseFormat,
2669 ComponentTypeEnum componentType, String userId) {
2670 User user = new User();
2671 user.setUserId(userId);
2672 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2675 protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
2676 AuditingActionEnum auditingAction = null;
2677 switch (operation.getArtifactOperationEnum()) {
2679 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
2682 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API
2683 : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
2686 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
2689 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
2694 return auditingAction;
2697 private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
2698 String esArtifactId = artifactDefinition.getEsId();
2699 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2700 if (artifactfromES.isRight()) {
2701 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2702 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2703 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
2704 log.debug("Error when getting artifact from ES, error: {}", actionStatus);
2705 throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
2707 DAOArtifactData DAOArtifactData = artifactfromES.left().value();
2708 byte[] data = DAOArtifactData.getDataAsArray();
2710 log.debug("Artifact data from cassandra is null");
2711 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
2713 String artifactName = artifactDefinition.getArtifactName();
2714 log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
2715 return new ImmutablePair<>(artifactName, data);
2718 public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
2719 return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
2722 private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo, String currArtifactId,
2723 String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
2724 CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
2725 if (resourceUploadStatus == CassandraOperationStatus.OK) {
2726 log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
2727 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
2728 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2729 componentType, null);
2731 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2732 log.info(FAILED_SAVE_ARTIFACT);
2733 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2734 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2735 componentType, null);
2736 throw new StorageException(resourceUploadStatus);
2740 private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
2741 return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
2744 private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
2745 return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
2748 private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
2749 return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
2752 private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
2753 final String artifactType = artifactInfo.getArtifactType();
2754 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
2755 if (artifactTypeEnum == null) {
2756 artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
2759 switch (artifactTypeEnum) {
2770 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap,
2771 String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
2772 User user = userBusinessLogic.getUser(userUserId, inTransaction);
2773 return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
2776 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
2777 ArtifactGroupTypeEnum groupType) {
2778 ArtifactDefinition artifactInfo = new ArtifactDefinition();
2779 String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
2780 String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
2781 String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
2782 artifactInfo.setArtifactDisplayName(artifactName);
2783 artifactInfo.setArtifactLabel(logicalName.toLowerCase());
2784 artifactInfo.setArtifactType(artifactType);
2785 artifactInfo.setDescription(artifactDescription);
2786 artifactInfo.setArtifactGroupType(groupType);
2787 nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
2788 setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
2789 return artifactInfo;
2792 private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
2793 String uniqueId = null;
2794 if (resourceId != null) {
2795 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
2796 artifactInfo.setUniqueId(uniqueId);
2798 artifactInfo.setUserIdCreator(user.getUserId());
2799 String fullName = user.getFullName();
2800 artifactInfo.setUpdaterFullName(fullName);
2801 long time = System.currentTimeMillis();
2802 artifactInfo.setCreatorFullName(fullName);
2803 artifactInfo.setCreationDate(time);
2804 artifactInfo.setLastUpdateDate(time);
2805 artifactInfo.setUserIdLastUpdater(user.getUserId());
2806 artifactInfo.setMandatory(true);
2809 public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType,
2810 ArtifactGroupTypeEnum groupType, String instanceId) {
2811 return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
2814 public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact,
2815 Component component, NodeTypeEnum parentType, String instanceId) {
2816 return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
2819 private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
2820 byte[] payload = payloadStr.getBytes();
2821 DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
2822 return Either.left(artifactData);
2826 * @param artifactDefinition
2829 public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType,
2830 Component component, String resourceInstanceName, User modifier,
2831 String instanceId, boolean shouldLock, boolean inTransaction) {
2832 String payload = generateHeatEnvPayload(artifactDefinition);
2833 String prevUUID = artifactDefinition.getArtifactUUID();
2834 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2835 return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2836 shouldLock, inTransaction).left()
2837 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2840 public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition,
2841 ComponentTypeEnum componentType, Component component,
2842 String resourceInstanceName, User modifier, boolean shouldLock,
2843 boolean inTransaction, String instanceId) {
2844 String payload = generateHeatEnvPayload(artifactDefinition);
2845 String prevUUID = artifactDefinition.getArtifactUUID();
2846 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2847 return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2848 shouldLock, inTransaction).left()
2849 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2853 Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID,
2854 ArtifactDefinition clonedBeforeGenerate,
2855 ArtifactDefinition updatedArtDef) {
2856 if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
2857 List<ComponentInstance> componentInstances = component.getComponentInstances();
2858 if (componentInstances != null) {
2859 Optional<ComponentInstance> findFirst = componentInstances.stream().filter(ci -> ci.getUniqueId().equals(instanceId)).findFirst();
2860 if (findFirst.isPresent()) {
2861 ComponentInstance relevantInst = findFirst.get();
2862 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate,
2863 relevantInst.getGroupInstances());
2864 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
2865 updatedGroupInstances.forEach(gi -> {
2866 gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
2867 gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
2869 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
2870 .updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
2871 if (status.isRight()) {
2872 log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
2873 ResponseFormat responseFormat = componentsUtils
2874 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(status.right().value()),
2875 clonedBeforeGenerate.getArtifactDisplayName());
2876 return Either.right(responseFormat);
2882 return Either.left(updatedArtDef);
2885 private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
2886 List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
2887 StringBuilder sb = new StringBuilder();
2888 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
2889 sb.append("parameters:\n");
2890 if (heatParameters != null) {
2891 heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2892 List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
2893 for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
2894 String heatValue = heatParameterDefinition.getCurrentValue();
2895 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2896 heatValue = heatParameterDefinition.getDefaultValue();
2897 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2898 empltyHeatValues.add(heatParameterDefinition);
2902 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
2906 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatValue))
2910 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ")
2911 .append(new BigDecimal(heatValue).toPlainString()).append("\n");
2913 case COMMA_DELIMITED_LIST:
2915 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatValue).append("\n");
2918 String value = heatValue;
2919 boolean starts = value.startsWith("\"");
2920 boolean ends = value.endsWith("\"");
2921 if (!(starts && ends)) {
2922 starts = value.startsWith("'");
2923 ends = value.endsWith("'");
2924 if (!(starts && ends)) {
2925 value = "\"" + value + "\"";
2928 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value);
2934 if (!empltyHeatValues.isEmpty()) {
2935 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2936 empltyHeatValues.forEach(hv -> {
2937 sb.append(" ").append(hv.getName()).append(":");
2938 HeatParameterType type = HeatParameterType.isValidType(hv.getType());
2939 if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv.getCurrentValue())
2940 || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
2941 sb.append(" \"\"").append("\n");
2943 sb.append(" ").append("\n");
2948 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
2950 return sb.toString().replaceAll("\\\\n", "\n");
2954 * @param artifactDefinition
2958 public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2959 ComponentTypeEnum componentType, Component component,
2960 String resourceInstanceName, User modifier, String instanceId,
2961 boolean shouldLock, boolean inTransaction) {
2962 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2963 artifactDefinition::getHeatParamsUpdateDate, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2966 public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2967 ComponentTypeEnum componentType, Component component,
2968 String resourceInstanceName, User modifier,
2969 String instanceId, boolean shouldLock,
2970 boolean inTransaction) {
2971 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2972 System::currentTimeMillis, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2975 protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition,
2976 ComponentTypeEnum componentType, Component component,
2977 String resourceInstanceName, User modifier, boolean shouldLock,
2978 boolean inTransaction, Supplier<Long> payloadUpdateDateGen,
2979 Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator,
2980 String instanceId) {
2981 log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2982 if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0
2983 || artifactDefinition.getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
2984 log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2985 Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
2986 DAOArtifactData artifactData = null;
2987 if (artifactDataRes.isLeft()) {
2988 artifactData = artifactDataRes.left().value();
2990 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2991 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
2992 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
2993 resourceInstanceName);
2994 return Either.right(artifactDataRes.right().value());
2996 String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
2998 String esArtifactId = artifactDefinition.getEsId();
2999 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
3000 DAOArtifactData DAOArtifactData;
3001 if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
3002 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
3003 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3004 if (artifactfromES.isRight()) {
3005 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3006 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3007 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3008 log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
3009 return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
3011 DAOArtifactData = artifactfromES.left().value();
3012 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3014 oldCheckSum = artifactDefinition.getArtifactChecksum();
3016 Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3019 lockComponent(component, "Update Artifact - lock resource: ");
3020 } catch (ComponentException e) {
3021 handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null,
3022 artifactDefinition.getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3027 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3028 artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3029 updateArifactDefinitionStatus = artifactToscaOperation
3030 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3032 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3033 artifactDefinition.getEsId());
3034 if (updateArifactDefinitionStatus.isRight()) {
3035 ResponseFormat responseFormat = componentsUtils
3036 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3037 artifactDefinition.getArtifactDisplayName());
3038 log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3039 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3040 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3041 resourceInstanceName);
3042 return Either.right(responseFormat);
3045 artifactDefinition.getArtifactChecksum();
3046 artifactDefinition.setArtifactChecksum(newCheckSum);
3047 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3048 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3049 artifactDefinition.getEsId());
3050 updateArifactDefinitionStatus = artifactToscaOperation
3051 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3053 log.trace("Update Payload {}", artifactDefinition.getEsId());
3055 if (updateArifactDefinitionStatus.isLeft()) {
3056 artifactDefinition = updateArifactDefinitionStatus.left().value();
3057 artifactData.setId(artifactDefinition.getUniqueId());
3058 CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3059 if (saveArtifactStatus == CassandraOperationStatus.OK) {
3060 if (!inTransaction) {
3061 janusGraphDao.commit();
3063 log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3064 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3065 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3066 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3067 resourceInstanceName);
3069 if (!inTransaction) {
3070 janusGraphDao.rollback();
3072 log.info("Failed to save artifact {}.", artifactData.getId());
3073 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3074 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3075 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3076 resourceInstanceName);
3077 return Either.right(responseFormat);
3080 ResponseFormat responseFormat = componentsUtils
3081 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3082 artifactDefinition.getArtifactDisplayName());
3083 log.debug("Failed To update artifact {}", artifactData.getId());
3084 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3085 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3086 resourceInstanceName);
3087 return Either.right(responseFormat);
3091 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
3095 return Either.left(artifactDefinition);
3098 public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType,
3099 List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3101 .buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType,
3102 artifactDef.getArtifactLabel(), artifactDef.getArtifactDisplayName(), artifactDef.getDescription(), artifactDef.getPayloadData(),
3103 updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3106 public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType,
3107 ArtifactGroupTypeEnum artifactGroupType, String label, String displayName,
3108 String description, byte[] artifactContent,
3109 List<ArtifactTemplateInfo> updatedRequiredArtifacts,
3110 List<HeatParameterDefinition> heatParameters) {
3111 Map<String, Object> json = new HashMap<>();
3112 if (artifactId != null && !artifactId.isEmpty()) {
3113 json.put(Constants.ARTIFACT_ID, artifactId);
3115 json.put(Constants.ARTIFACT_NAME, artifactName);
3116 json.put(Constants.ARTIFACT_TYPE, artifactType);
3117 json.put(Constants.ARTIFACT_DESCRIPTION, description);
3118 if (artifactContent != null) {
3119 log.debug("payload is encoded. perform decode");
3120 String encodedPayload = Base64.encodeBase64String(artifactContent);
3121 json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3123 json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3124 json.put(Constants.ARTIFACT_LABEL, label);
3125 json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3126 json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3127 : updatedRequiredArtifacts.stream().filter(
3128 e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3129 .map(ArtifactTemplateInfo::getFileName).collect(Collectors.toList()));
3130 json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>() : heatParameters);
3134 public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user,
3135 Map<String, Object> json, ArtifactOperationInfo operation,
3136 ArtifactDefinition artifactInfo) {
3137 String jsonStr = gson.toJson(json);
3138 ArtifactDefinition artifactDefinitionFromJson =
3139 artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3140 String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3141 Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE,
3142 operation, artifactUniqueId, artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3143 return Either.left(uploadArtifactToService.left().value());
3146 private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo,
3147 AuditingActionEnum auditingAction, String artifactId, User user,
3148 ComponentTypeEnum componentType, Component parent, String originData,
3149 String origMd5, ArtifactOperationInfo operation) {
3150 if (origMd5 != null) {
3151 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3152 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3153 validateDeploymentArtifact(artifactInfo, parent);
3154 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3155 } else { // duplicate
3156 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3159 return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3162 private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId,
3163 ArtifactDefinition artifactInfo, User user,
3164 AuditingActionEnum auditingAction, Component parent,
3165 ComponentTypeEnum componentType, String origMd5) {
3166 Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3167 if (getRI.isRight()) {
3168 throw new ByResponseFormatComponentException(getRI.right().value());
3170 ComponentInstance ri = getRI.left().value();
3171 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3172 if (getArtifactRes.isRight()) {
3173 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3175 ArtifactDefinition currArtifact = getArtifactRes.left().value();
3176 if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType()
3177 .equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3178 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3180 List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3181 List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3183 if (origMd5 != null) {
3184 Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction,
3185 parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams,
3186 currArtifact.getArtifactName());
3187 if (uploadParamsValidationResult.isRight()) {
3188 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3190 artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3192 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo,
3193 ArtifactTypeEnum.HEAT_ENV.getType());
3194 if (validateAndConvertHeatParamers.isRight()) {
3195 throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3197 if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3198 // fill reduced heat env parameters List for updating
3199 boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3200 if (updateRequired) {
3201 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3202 currArtifact.setListHeatParameters(currentHeatEnvParams);
3203 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3204 .updateArtifactOnResource(currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3205 if (updateArtifactRes.isRight()) {
3206 log.debug("Failed to update artifact on graph - {}", artifactId);
3207 throw new StorageException(updateArtifactRes.right().value());
3209 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(),
3210 parent.getUniqueId());
3211 if (error != StorageOperationStatus.OK) {
3212 throw new StorageException(error);
3216 updateHeatMetaDataIfNeeded(componentId, user, auditingAction, componentType, parent, ri, artifactInfo);
3217 StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3218 if (error != StorageOperationStatus.OK) {
3219 throw new StorageException(error);
3221 return Either.left(currArtifact);
3224 private void updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType,
3225 Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3226 String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3227 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId,
3228 auditingAction, user);
3229 if (getArtifactRes.isRight()) {
3230 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3232 ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3233 if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3234 validateHeatMetaData(updatedHeatEnvArtifact);
3235 updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3236 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3237 .updateArtifactOnResource(heatArtifactToUpdate, parent, heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId,
3239 if (updateArtifactRes.isRight()) {
3240 log.debug("Failed to update artifact on graph - {}", heatArtifactId);
3241 throw new StorageException(updateArtifactRes.right().value());
3243 ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3244 updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition,
3245 componentType.getNodeType());
3246 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(),
3247 parent.getUniqueId());
3248 if (error != StorageOperationStatus.OK) {
3249 throw new StorageException(error);
3254 private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3255 Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3256 Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3257 Integer updateTimeout = updatedHeatEnv.getTimeout();
3258 if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3259 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3263 private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3264 // currently only timeout metadata can be updated
3265 return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3268 private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3269 // currently only timeout metadata can be updated
3270 origHeat.setTimeout(updatedHeatEnv.getTimeout());
3273 private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams,
3274 List<HeatParameterDefinition> updatedHeatEnvParams) {
3275 boolean isUpdate = false;
3276 List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3277 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3278 String paramName = heatEnvParam.getName();
3279 validateParamName(paramName, currentParamsNames);
3280 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3281 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3282 String updatedParamValue = heatEnvParam.getCurrentValue();
3283 if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3284 currHeatParam.setCurrentValue(updatedParamValue);
3293 private void validateParamName(String paramName, List<String> heatParamsNames) {
3294 if (!heatParamsNames.contains(paramName)) {
3295 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3299 private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo,
3300 AuditingActionEnum auditingAction, Component parent,
3301 ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact,
3302 boolean needToUpdateGroup) {
3303 Either<ArtifactDefinition, Operation> insideEither = null;
3304 String currentHeatId = currHeatArtifact.getUniqueId();
3305 String esArtifactId = currHeatArtifact.getEsId();
3306 Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3307 if (artifactFromES.isRight()) {
3308 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3309 throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3311 DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3312 ArtifactDefinition updatedHeatArt = currHeatArtifact;
3313 List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3314 List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3315 List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3316 if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3317 //TODO: improve complexity - currently N^2
3319 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3320 paramName = heatEnvParam.getName();
3321 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3322 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3323 String updatedParamValue = heatEnvParam.getCurrentValue();
3324 if (updatedParamValue == null) {
3325 updatedParamValue = heatEnvParam.getDefaultValue();
3327 HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3328 if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3329 throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE, ArtifactTypeEnum.HEAT_ENV.getType(),
3330 paramType.getType(), paramName);
3332 currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3333 newHeatEnvParams.add(currHeatParam);
3338 if (!newHeatEnvParams.isEmpty()) {
3339 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3340 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation
3341 .updateArtifactOnResource(currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId,
3343 if (operationStatus.isRight()) {
3344 log.debug("Failed to update artifact on graph - {}", currHeatArtifact.getUniqueId());
3345 throw new StorageException(operationStatus.right().value());
3347 updatedHeatArt = operationStatus.left().value();
3348 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3349 DAOArtifactData.setId(updatedHeatArt.getEsId());
3351 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), auditingAction,
3353 insideEither = Either.left(updatedHeatArt);
3356 Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3357 if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3358 artifactEnvInfo.setArtifactChecksum(null);
3359 updateHeatEnvArtifact = artifactToscaOperation
3360 .updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), componentType.getNodeType(),
3363 //TODO Andrey check if componentId = parent.getUniqeId
3364 updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType.getNodeType());
3366 if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3367 ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo, updateHeatEnvArtifact.left().value(), parent);
3368 if (result != ActionStatus.OK) {
3369 throw new ByActionStatusComponentException(result);
3372 if (updatedHeatEnvParams.isEmpty()) {
3373 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3375 return insideEither;
3378 private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3379 StorageOperationStatus error = StorageOperationStatus.OK;
3380 log.debug("Need to re-generate customization UUID for group instance on component instance {}", ri.getUniqueId());
3381 List<GroupInstance> groupsInstances = ri.getGroupInstances();
3382 List<String> groupInstancesId = null;
3383 if (groupsInstances != null && !groupsInstances.isEmpty()) {
3384 groupInstancesId = groupsInstances.stream()
3385 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(artifactId))
3386 .map(GroupInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
3388 if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3389 toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3394 public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent,
3395 User user, ArtifactDefinition artifactInfo,
3396 String artifactId, ComponentTypeEnum componentType,
3398 List<HeatParameterDefinition> currentHeatEnvParams,
3399 List<HeatParameterDefinition> updatedHeatEnvParams,
3400 String currArtifactName) {
3401 if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3402 ResponseFormat responseFormat = componentsUtils
3403 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName);
3404 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3405 return Either.right(responseFormat);
3407 for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3408 String paramName = uploadedHeatParam.getName();
3409 boolean isExistsInHeat = false;
3410 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3411 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3412 isExistsInHeat = true;
3413 uploadedHeatParam.setType(currHeatParam.getType());
3414 uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3415 uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3416 uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3420 if (!isExistsInHeat) {
3421 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3422 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType,
3424 return Either.right(responseFormat);
3427 return Either.left(updatedHeatEnvParams);
3430 private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId,
3431 AuditingActionEnum auditingAction, User user) {
3432 ResponseFormat responseFormat = null;
3433 List<ComponentInstance> ris = component.getComponentInstances();
3434 for (ComponentInstance ri : ris) {
3435 if (riID.equals(ri.getUniqueId())) {
3436 return Either.left(ri);
3439 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3440 log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3441 handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3442 return Either.right(responseFormat);
3445 private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId,
3446 AuditingActionEnum auditingAction, User user) {
3447 ResponseFormat responseFormat = null;
3448 Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3449 for (ArtifactDefinition artifact : rtifactsMap.values()) {
3450 if (artifactId.equals(artifact.getUniqueId())) {
3451 return Either.left(artifact);
3454 responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3455 handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3457 return Either.right(responseFormat);
3460 public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3461 ArtifactDefinition ret;
3462 if (eitherArtifact.isLeft()) {
3463 ret = eitherArtifact.left().value();
3465 ret = eitherArtifact.right().value().getImplementationArtifact();
3470 public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
3471 ResourceCommonInfo resourceCommonInfo) {
3472 Component component = getComponentByUuid(componentType, componentUuid);
3473 resourceCommonInfo.setResourceName(component.getName());
3474 return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3478 * downloads an artifact of resource instance of component by UUIDs
3480 * @param componentType
3481 * @param componentUuid
3482 * @param resourceInstanceName
3483 * @param artifactUUID
3486 public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
3487 String artifactUUID) {
3488 ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3489 if (resourceInstance != null) {
3490 return downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, resourceInstance.getName());
3492 return downloadArtifact(null, artifactUUID, null);
3497 * uploads an artifact to a component by UUID
3501 * @param componentType
3502 * @param componentUuid
3503 * @param resourceCommonInfo
3507 public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3508 String componentUuid, ResourceCommonInfo resourceCommonInfo,
3509 ArtifactOperationInfo operation) {
3510 Either<ArtifactDefinition, Operation> actionResult;
3511 Component component;
3513 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3514 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3515 String userId = request.getHeader(Constants.USER_ID_HEADER);
3516 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3517 ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3518 componentId = componentMetadataDataDefinition.getUniqueId();
3519 String componentName = componentMetadataDataDefinition.getName();
3520 if (!componentMetadataDataDefinition.getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3521 component = checkoutParentComponent(componentType, componentId, userId);
3522 if (component != null) {
3523 componentId = component.getUniqueId();
3524 componentName = component.getName();
3527 resourceCommonInfo.setResourceName(componentName);
3528 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null,
3530 return actionResult.left().value();
3534 * upload an artifact to a resource instance by UUID
3538 * @param componentType
3539 * @param componentUuid
3540 * @param resourceInstanceName
3544 public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3545 String resourceInstanceName, ArtifactOperationInfo operation) {
3546 Either<ArtifactDefinition, Operation> actionResult;
3547 Component component = null;
3548 String componentInstanceId;
3550 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3551 String userId = request.getHeader(Constants.USER_ID_HEADER);
3552 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3553 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid,
3554 resourceInstanceName);
3555 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3556 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3558 if (component == null) {
3559 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3561 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3563 componentInstanceId = componentRiPair.getRight().getUniqueId();
3564 componentId = componentRiPair.getLeft().getUniqueId();
3565 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3566 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5,
3567 data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3568 return actionResult.left().value();
3572 * updates an artifact on a component by UUID
3576 * @param componentType
3577 * @param componentUuid
3578 * @param artifactUUID
3579 * @param resourceCommonInfo
3580 * @param operation TODO
3583 public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3584 String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3585 ArtifactOperationInfo operation) {
3586 Either<ArtifactDefinition, Operation> actionResult;
3587 Component component;
3590 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3591 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3592 String userId = request.getHeader(Constants.USER_ID_HEADER);
3593 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3594 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3595 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3596 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3597 component = checkoutParentComponent(componentType, componentId, userId);
3598 if (component != null) {
3599 componentId = component.getUniqueId();
3600 componentName = component.getName();
3603 resourceCommonInfo.setResourceName(componentName);
3604 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3605 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null,
3607 if (actionResult.isRight()) {
3608 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult.right().value());
3610 return actionResult.left().value();
3614 * updates an artifact on a resource instance by UUID
3618 * @param componentType
3619 * @param componentUuid
3620 * @param resourceInstanceName
3621 * @param artifactUUID
3622 * @param operation TODO
3625 public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3626 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3627 Either<ArtifactDefinition, Operation> actionResult;
3628 Component component = null;
3629 String componentInstanceId;
3632 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3633 String userId = request.getHeader(Constants.USER_ID_HEADER);
3634 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3635 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3636 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3637 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3639 if (component == null) {
3640 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3642 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3644 componentInstanceId = componentRiPair.getRight().getUniqueId();
3645 componentId = componentRiPair.getLeft().getUniqueId();
3646 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3647 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3648 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo,
3649 origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3650 return actionResult.left().value();
3653 private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid,
3654 ArtifactDefinition artifactInfo) {
3655 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3656 if (componentStorageOperationStatusEither.isRight()) {
3657 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3658 log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
3659 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3661 Component storedComponent = componentStorageOperationStatusEither.left().value();
3662 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3663 .getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
3664 if (!optionalInterface.isPresent()) {
3665 log.debug("Failed to get resource interface for resource Id {}", componentId);
3666 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
3668 //fetch the operation from storage
3669 InterfaceDefinition gotInterface = optionalInterface.get();
3670 Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
3671 Optional<Operation> optionalOperation = operationsMap.values().stream().filter(o -> o.getUniqueId().equals(operationUuid)).findFirst();
3672 if (!optionalOperation.isPresent()) {
3673 log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
3674 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
3675 return Either.right(responseFormat);
3677 Operation operation = optionalOperation.get();
3678 ArtifactDefinition implementationArtifact = operation.getImplementationArtifact();
3679 implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
3680 implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
3681 implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
3682 implementationArtifact.setDescription(artifactInfo.getDescription());
3683 implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
3684 implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
3685 implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
3686 implementationArtifact.setEsId(artifactInfo.getEsId());
3687 operation.setImplementation(implementationArtifact);
3688 gotInterface.setOperationsMap(operationsMap);
3689 Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = interfaceOperation
3690 .updateInterfaces(storedComponent.getUniqueId(), Collections.singletonList(gotInterface));
3691 if (interfaceDefinitionStorageOperationStatusEither.isRight()) {
3692 StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
3693 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
3694 return Either.right(componentsUtils.getResponseFormat(actionStatus));
3696 return Either.left(artifactInfo);
3700 * updates an artifact on a component by UUID
3704 * @param componentType
3705 * @param componentUuid
3706 * @param artifactUUID
3710 public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(String data, HttpServletRequest request,
3711 ComponentTypeEnum componentType,
3712 String componentUuid, String interfaceUUID,
3713 String operationUUID, String artifactUUID,
3714 ResourceCommonInfo resourceCommonInfo,
3715 ArtifactOperationInfo operation) {
3716 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
3717 Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
3718 String componentId = null;
3719 ArtifactDefinition existingArtifactInfo = null;
3720 String interfaceName = null;
3721 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3722 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3723 String userId = request.getHeader(Constants.USER_ID_HEADER);
3724 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3725 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(as));
3728 if (errorWrapper.isEmpty()) {
3729 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3730 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3731 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3732 Component component = checkoutParentComponent(componentType, componentId, userId);
3733 if (component != null) {
3734 componentId = component.getUniqueId();
3735 componentName = component.getName();
3738 resourceCommonInfo.setResourceName(componentName);
3740 if (errorWrapper.isEmpty()) {
3741 Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
3742 if (interfaceNameEither.isRight()) {
3743 errorWrapper.setInnerElement(interfaceNameEither.right().value());
3745 interfaceName = interfaceNameEither.left().value();
3747 if (errorWrapper.isEmpty()) {
3748 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
3749 if (toscaComponentEither.isRight()) {
3750 StorageOperationStatus status = toscaComponentEither.right().value();
3751 log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
3752 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
3754 if (errorWrapper.isEmpty()) {
3755 NodeTypeEnum parentType = convertParentType(componentType);
3756 final List<ArtifactDefinition> existingDeploymentArtifacts = getDeploymentArtifacts(toscaComponentEither.left().value(), null);
3757 for (ArtifactDefinition artifactDefinition : existingDeploymentArtifacts) {
3758 if (artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())) {
3759 existingArtifactInfo = artifactDefinition;
3763 if (existingArtifactInfo != null) {
3764 return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
3769 if (errorWrapper.isEmpty()) {
3770 updateArtifactResult = handleArtifactRequestAndFlatten(componentId, userId, componentType, operation, artifactUUID, artifactInfo, origMd5,
3771 data, interfaceName, operationUUID);
3773 updateArtifactResult = Either.right(errorWrapper.getInnerElement());
3775 return updateArtifactResult;
3778 private Either<ArtifactDefinition, ResponseFormat> handleArtifactRequestAndFlatten(String componentId, String userId,
3779 ComponentTypeEnum componentType,
3780 ArtifactOperationInfo operation, String artifactId,
3781 ArtifactDefinition artifactInfo, String origMd5,
3782 String originData, String interfaceName,
3783 String operationName) {
3785 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
3786 operationName, null, null).right().map(op -> {
3787 log.debug("Unexpected value returned while calling handleArtifactRequest: {}", op);
3788 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3790 } catch (ComponentException e) {
3791 return Either.right(e.getResponseFormat());
3795 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid) {
3796 return fetchLatestComponentMetadataOrThrow(componentType, componentUuid, componentUuid);
3799 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid,
3800 String resourceInstanceName) {
3801 return fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3802 throw new ByActionStatusComponentException(as, resourceInstanceName);
3806 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadata(ComponentTypeEnum componentType, String componentUuid) {
3807 return toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true).right().map(sos -> {
3808 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, sos);
3809 return componentsUtils.convertFromStorageResponse(sos, componentType);
3813 private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
3814 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3815 if (componentStorageOperationStatusEither.isRight()) {
3816 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3817 log.debug("Failed to fetch component information by component id, error {}", errorStatus);
3818 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3820 Component storedComponent = componentStorageOperationStatusEither.left().value();
3821 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3822 .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
3823 if (!optionalInterface.isPresent()) {
3824 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
3826 return Either.left(optionalInterface.get().getType());
3830 * deletes an artifact on a component by UUID
3833 * @param componentType
3834 * @param componentUuid
3835 * @param artifactUUID
3836 * @param resourceCommonInfo
3837 * @param operation TODO
3840 public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3841 String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3842 ArtifactOperationInfo operation) {
3843 Either<ArtifactDefinition, Operation> actionResult;
3844 Component component;
3847 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3848 String userId = request.getHeader(Constants.USER_ID_HEADER);
3849 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3850 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3851 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3852 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3853 component = checkoutParentComponent(componentType, componentId, userId);
3854 if (component != null) {
3855 componentId = component.getUniqueId();
3856 componentName = component.getName();
3859 resourceCommonInfo.setResourceName(componentName);
3860 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3861 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
3862 return actionResult.left().value();
3866 * deletes an artifact from a resource instance by UUID
3869 * @param componentType
3870 * @param componentUuid
3871 * @param resourceInstanceName
3872 * @param artifactUUID
3873 * @param operation TODO
3876 public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3877 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3878 Either<ArtifactDefinition, Operation> actionResult;
3879 Component component = null;
3880 String componentInstanceId;
3883 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3884 String userId = request.getHeader(Constants.USER_ID_HEADER);
3885 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3886 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3887 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3888 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3890 if (component == null) {
3891 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3893 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3895 componentInstanceId = componentRiPair.getRight().getUniqueId();
3896 componentId = componentRiPair.getLeft().getUniqueId();
3897 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3898 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5,
3899 null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3900 return actionResult.left().value();
3903 private String findArtifactId(ComponentInstance instance, String artifactUUID) {
3904 String artifactId = null;
3905 ArtifactDefinition foundArtifact = null;
3906 if (instance.getDeploymentArtifacts() != null) {
3907 foundArtifact = instance.getDeploymentArtifacts().values().stream()
3908 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3910 if (foundArtifact == null && instance.getArtifacts() != null) {
3911 foundArtifact = instance.getArtifacts().values().stream()
3912 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3914 if (foundArtifact == null) {
3915 log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
3916 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
3918 artifactId = foundArtifact.getUniqueId();
3923 @SuppressWarnings("unchecked")
3924 public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact, String envType,
3925 String parentId, NodeTypeEnum parentType, String parentName, User user, Component component,
3926 Map<String, String> existingEnvVersions) {
3927 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
3928 .getDeploymentResourceInstanceArtifacts();
3929 if (deploymentResourceArtifacts == null) {
3930 log.debug("no deployment artifacts are configured for generated artifacts");
3931 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3933 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
3934 if (placeHolderData == null) {
3935 log.debug("no env type {} are configured for generated artifacts", envType);
3936 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3938 String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
3939 ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user.getUserId(),
3940 ArtifactGroupTypeEnum.DEPLOYMENT, true);
3941 ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
3942 artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
3943 artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
3944 artifactHeatEnv.setTimeout(0);
3945 artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
3946 buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
3947 // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
3948 handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
3949 ArtifactDefinition heatEnvPlaceholder;
3950 // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
3951 if (parentType != NodeTypeEnum.ResourceInstance) {
3952 String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
3953 artifactHeatEnv.setArtifactChecksum(checkSum);
3954 Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component,
3955 parentType, parentId);
3956 if (addHeatEnvArtifact.isRight()) {
3957 log.debug("failed to create heat env artifact on resource instance");
3958 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(
3959 componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact.right().value(), false), "", null));
3961 heatEnvPlaceholder = createArtifactPlaceHolder;
3963 heatEnvPlaceholder = artifactHeatEnv;
3964 artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
3965 setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
3967 ComponentTypeEnum componentType = component.getComponentType();
3968 if (parentType == NodeTypeEnum.ResourceInstance) {
3969 componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
3971 createdArtifacts.add(heatEnvPlaceholder);
3972 componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
3973 new ResourceCommonInfo(parentName, componentType.getValue()), ResourceVersionInfo.newBuilder().build(),
3974 ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(), null, heatEnvPlaceholder, null);
3975 return heatEnvPlaceholder;
3978 private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
3979 if (artifact.getListHeatParameters() == null) {
3982 List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
3983 for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
3984 HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
3985 heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
3986 heatEnvParameter.setCurrentValue(null);
3987 heatEnvParameters.add(heatEnvParameter);
3989 artifactDefinition.setListHeatParameters(heatEnvParameters);
3992 private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
3993 String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
3994 String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
3995 String name = heatArtifact.getArtifactName();
3998 name = heatArtifact.getArtifactLabel();
3999 fileName = name + "." + envExtension;
4001 fileName = name.replaceAll("." + heatExtension, "." + envExtension);
4003 heatEnvArtifact.setArtifactName(fileName);
4006 private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
4007 if (null != existingEnvVersions) {
4008 String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
4009 if (null != prevVersion) {
4010 heatEnvArtifact.setArtifactVersion(prevVersion);
4015 public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user,
4016 List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4017 ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4018 ComponentTypeEnum componentType = component.getComponentType();
4019 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4020 Either<ArtifactDefinition, Operation> result;
4022 for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4023 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4024 uploadedArtifacts.add(result.left().value());
4026 } catch (ComponentException e) {
4027 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component.getName(), e.getResponseFormat());
4028 if (operation.isCreateOrLink()) {
4029 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4033 return uploadedArtifacts;
4036 public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Component component, User user, ArtifactOperationInfo operation,
4037 boolean shouldLock, boolean inTransaction, ComponentTypeEnum componentType,
4038 ArtifactDefinition artifactDefinition) {
4039 AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4040 String componentId = component.getUniqueId();
4041 String artifactId = artifactDefinition.getUniqueId();
4042 Either<ArtifactDefinition, Operation> result;
4043 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4044 //artifact validation
4045 artifactDefinition = validateArtifact(componentId, componentType, operation, artifactId, artifactDefinition, auditingAction, user, component,
4046 shouldLock, inTransaction);
4047 switch (operation.getArtifactOperationEnum()) {
4049 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType,
4050 component, null, null);
4051 result = createArtifact(component, componentId, artifactDefinition, validPayload, componentType, auditingAction, null, null);
4054 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component,
4056 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4057 auditingAction, user, component, true);
4060 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4063 if (artifactGenerationRequired(component, artifactDefinition)) {
4064 result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4066 result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4070 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4073 throw new UnsupportedOperationException(
4074 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4079 public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component,
4080 User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4081 ArtifactOperationInfo operation, boolean shouldLock,
4082 boolean inTransaction) {
4083 List<ArtifactDefinition> handleArtifactsResult;
4084 ComponentTypeEnum componentType = component.getComponentType();
4085 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4086 Either<ArtifactDefinition, Operation> actionResult;
4090 for (ArtifactDefinition artifact : artifactsToHandle) {
4091 originData = ArtifactUtils.buildJsonStringForCsarVfcArtifact(artifact);
4092 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4093 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact.getUniqueId(),
4094 artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4095 uploadedArtifacts.add(actionResult.left().value());
4097 handleArtifactsResult = uploadedArtifacts;
4098 } catch (ComponentException e) {
4099 if (operation.isCreateOrLink()) {
4100 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4104 return handleArtifactsResult;
4107 private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName) {
4108 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4109 Option<Component> oComponent = Option.of(getComponentByUuid(componentType, componentUuid));
4110 return oComponent.toTry(componentNotFound(componentType, componentUuid)).flatMap(
4111 component -> findFirstMatching(component, ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4112 .toTry(componentInstanceNotFound(componentType, resourceInstanceName, component))).get();
4115 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName) {
4116 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4117 ComponentInstance componentInstance = findFirstMatching(component,
4118 ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4119 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4120 return new ImmutablePair<>(component, componentInstance);
4123 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid,
4124 String resourceInstanceName) {
4125 Component component = getLatestComponentByUuid(componentType, componentUuid);
4126 ComponentInstance componentInstance = findFirstMatching(component, ci -> ci.getNormalizedName().equals(resourceInstanceName))
4127 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4128 return new ImmutablePair<>(component, componentInstance);
4131 private Supplier<Throwable> componentNotFound(ComponentTypeEnum componentType, String componentUuid) {
4133 log.debug(FAILED_FETCH_COMPONENT, componentType.getValue(), componentUuid);
4134 return new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentUuid);
4138 private Supplier<Throwable> componentInstanceNotFound(ComponentTypeEnum componentType, String resourceInstanceName, Component component) {
4140 log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4141 return new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4142 RESOURCE_INSTANCE, componentType.getValue(), component.getName());
4146 private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4147 ImmutablePair<String, byte[]> downloadArtifact;
4148 List<ArtifactDefinition> artifactsList = null;
4149 ArtifactDefinition deploymentArtifact;
4150 if (artifacts != null && !artifacts.isEmpty()) {
4151 artifactsList = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID))
4152 .collect(Collectors.toList());
4154 if (artifactsList == null || artifactsList.isEmpty()) {
4155 log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4156 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4158 deploymentArtifact = artifactsList.get(0);
4159 downloadArtifact = downloadArtifact(deploymentArtifact);
4160 log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4161 return downloadArtifact.getRight();
4164 private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4165 Component component;
4166 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4167 if (getComponentRes.isRight()) {
4168 StorageOperationStatus status = getComponentRes.right().value();
4169 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4170 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4172 component = getComponentRes.left().value();
4177 private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4178 Component component;
4179 Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4180 if (getComponentRes.isRight()) {
4181 StorageOperationStatus status = getComponentRes.right().value();
4182 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4183 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4185 List<Component> value = getComponentRes.left().value();
4186 if (value.isEmpty()) {
4187 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4188 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4189 throw new ByActionStatusComponentException(status);
4191 component = value.get(0);
4197 private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4198 ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4199 StorageOperationStatus storageStatus;
4200 ArtifactDefinition latestArtifact;
4201 List<ArtifactDefinition> artifacts;
4202 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4203 if (getArtifactsRes.isRight()) {
4204 storageStatus = getArtifactsRes.right().value();
4205 log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4206 if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4207 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4209 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4211 artifacts = getArtifactsRes.left().value().values().stream()
4212 .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList());
4213 if (artifacts == null || artifacts.isEmpty()) {
4214 log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4215 parentId, actionStatus);
4216 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4218 latestArtifact = artifacts.stream().max((a1, a2) -> {
4219 int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4220 if (compareRes == 0) {
4221 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(),
4222 a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate());
4226 if (latestArtifact == null) {
4227 log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4228 parentId, actionStatus);
4229 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4231 return latestArtifact.getUniqueId();
4234 private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4235 Component component = null;
4236 User modifier = userBusinessLogic.getUser(userId, false);
4237 LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout",
4238 LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4239 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
4240 .changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4241 if (checkoutRes.isRight()) {
4242 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId,
4243 checkoutRes.right().value().getStatus());
4244 throw new ByResponseFormatComponentException(checkoutRes.right().value());
4246 return checkoutRes.left().value();
4250 void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4251 this.nodeTemplateOperation = nodeTemplateOperation;
4254 public List<ArtifactConfiguration> getConfiguration() {
4255 return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
4258 public enum ArtifactOperationEnum {
4259 CREATE, UPDATE, DELETE, DOWNLOAD, LINK;
4261 public static boolean isCreateOrLink(ArtifactOperationEnum operation) {
4262 return operation == CREATE || operation == LINK;