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.lang3.ArrayUtils;
54 import org.apache.commons.lang3.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.ArtifactTypeDefinition;
92 import org.openecomp.sdc.be.model.Component;
93 import org.openecomp.sdc.be.model.ComponentInstance;
94 import org.openecomp.sdc.be.model.ComponentParametersView;
95 import org.openecomp.sdc.be.model.GroupDefinition;
96 import org.openecomp.sdc.be.model.GroupInstance;
97 import org.openecomp.sdc.be.model.HeatParameterDefinition;
98 import org.openecomp.sdc.be.model.InterfaceDefinition;
99 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
100 import org.openecomp.sdc.be.model.LifecycleStateEnum;
101 import org.openecomp.sdc.be.model.Operation;
102 import org.openecomp.sdc.be.model.Resource;
103 import org.openecomp.sdc.be.model.Service;
104 import org.openecomp.sdc.be.model.User;
105 import org.openecomp.sdc.be.model.heat.HeatParameterType;
106 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
107 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
108 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeTemplateOperation;
109 import org.openecomp.sdc.be.model.operations.StorageException;
110 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
111 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
112 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
113 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
114 import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation;
115 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
116 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
117 import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
118 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
119 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
120 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
121 import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation;
122 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
123 import org.openecomp.sdc.be.resources.data.DAOArtifactData;
124 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
125 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
126 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
127 import org.openecomp.sdc.be.servlets.RepresentationUtils;
128 import org.openecomp.sdc.be.tosca.CsarUtils;
129 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
130 import org.openecomp.sdc.be.user.Role;
131 import org.openecomp.sdc.be.user.UserBusinessLogic;
132 import org.openecomp.sdc.be.utils.TypeUtils;
133 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
134 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
135 import org.openecomp.sdc.common.api.Constants;
136 import org.openecomp.sdc.common.datastructure.Wrapper;
137 import org.openecomp.sdc.common.log.wrappers.Logger;
138 import org.openecomp.sdc.common.util.GeneralUtility;
139 import org.openecomp.sdc.common.util.ValidationUtils;
140 import org.openecomp.sdc.common.util.YamlToObjectConverter;
141 import org.openecomp.sdc.exception.ResponseFormat;
142 import org.springframework.beans.factory.annotation.Autowired;
143 import org.yaml.snakeyaml.Yaml;
145 @org.springframework.stereotype.Component("artifactBusinessLogic")
146 public class ArtifactsBusinessLogic extends BaseBusinessLogic {
148 public static final String HEAT_ENV_NAME = "heatEnv";
149 public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
150 public static final String HEAT_ENV_SUFFIX = "env";
151 public static final String ARTIFACT_ACTION_LOCK = "Artifact action - lock ";
152 public static final String FAILED_UPLOAD_ARTIFACT_TO_COMPONENT = "Failed to upload artifact to component with type {} and uuid {}. Status is {}. ";
153 public static final String COMPONENT_INSTANCE_NOT_FOUND = "Component instance {} was not found for component {}";
154 private static final String RESOURCE_INSTANCE = "resource instance";
155 private static final String ARTIFACT_TYPE_OTHER = "OTHER";
156 private static final String ARTIFACT_DESCRIPTION = "artifact description";
157 private static final String ARTIFACT_LABEL = "artifact label";
158 private static final String ARTIFACT_URL = "artifact url";
159 private static final String ARTIFACT_NAME = "artifact name";
160 private static final String ARTIFACT_PAYLOAD = "artifact payload";
161 private static final String ARTIFACT_PLACEHOLDER_TYPE = "type";
162 private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
163 private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
164 private static final String ARTIFACT_PLACEHOLDER_FILE_EXTENSION = "fileExtension";
165 private static final Logger log = Logger.getLogger(ArtifactsBusinessLogic.class.getName());
166 private static final String FAILED_UPDATE_GROUPS = "Failed to update groups of the component {}. ";
167 private static final String FAILED_SAVE_ARTIFACT = "Failed to save the artifact.";
168 private static final String FAILED_FETCH_COMPONENT = "Could not fetch component with type {} and uuid {}. Status is {}. ";
169 private static final String NULL_PARAMETER = "One of the function parameteres is null";
170 private static final String ROLLBACK = "all changes rollback";
171 private static final String COMMIT = "all changes committed";
172 private static final String UPDATE_ARTIFACT = "Update Artifact";
173 private static final String FOUND_DEPLOYMENT_ARTIFACT = "Found deployment artifact {}";
174 private static final String VALID_ARTIFACT_LABEL_NAME = "'A-Z', 'a-z', '0-9', '-', '@', '+' and space.";
175 private Gson gson = new GsonBuilder().setPrettyPrinting().create();
176 @javax.annotation.Resource
177 private IInterfaceLifecycleOperation interfaceLifecycleOperation;
178 @javax.annotation.Resource
179 private UserAdminOperation userOperaton;
180 @javax.annotation.Resource
181 private IElementOperation elementOperation;
182 @javax.annotation.Resource
183 private IHeatParametersOperation heatParametersOperation;
184 private final ArtifactTypeOperation artifactTypeOperation;
185 private ArtifactCassandraDao artifactCassandraDao;
186 private ToscaExportHandler toscaExportUtils;
187 private CsarUtils csarUtils;
188 private LifecycleBusinessLogic lifecycleBusinessLogic;
189 private UserBusinessLogic userBusinessLogic;
190 private ArtifactsResolver artifactsResolver;
191 private NodeTemplateOperation nodeTemplateOperation;
194 public ArtifactsBusinessLogic(ArtifactCassandraDao artifactCassandraDao, ToscaExportHandler toscaExportUtils, CsarUtils csarUtils,
195 LifecycleBusinessLogic lifecycleBusinessLogic, UserBusinessLogic userBusinessLogic,
196 ArtifactsResolver artifactsResolver, IElementOperation elementDao, IGroupOperation groupOperation,
197 IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation,
198 InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
199 ArtifactsOperations artifactToscaOperation,
200 ArtifactTypeOperation artifactTypeOperation) {
201 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
202 artifactToscaOperation);
203 this.artifactCassandraDao = artifactCassandraDao;
204 this.toscaExportUtils = toscaExportUtils;
205 this.csarUtils = csarUtils;
206 this.lifecycleBusinessLogic = lifecycleBusinessLogic;
207 this.userBusinessLogic = userBusinessLogic;
208 this.artifactsResolver = artifactsResolver;
209 this.artifactTypeOperation = artifactTypeOperation;
212 public static <R> Either<Boolean, R> ifTrue(boolean predicate, Supplier<Either<Boolean, R>> ifTrue) {
213 return predicate ? ifTrue.get() : Either.left(false);
216 public static <L, R> Either<L, R> forEach(Either<L, R> e, Consumer<L> c) {
217 return e.left().map(l -> {
223 private static Option<ComponentInstance> findFirstMatching(Component component, Predicate<ComponentInstance> filter) {
224 return Option.ofOptional(component.getComponentInstances().stream().filter(filter).findFirst());
228 public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
229 ArtifactOperationInfo operation, String artifactId,
230 ArtifactDefinition artifactInfo, String origMd5, String originData,
231 String interfaceName, String operationName, String parentId,
232 String containerComponentType, boolean shouldLock, boolean inTransaction) {
233 // step 1 - detect auditing type
234 AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
235 // step 2 - check header
236 if (userId == null) {
237 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
238 log.debug("handleArtifactRequest - no HTTP_CSP_HEADER , component id {}", componentId);
239 handleAuditing(auditingAction, null, componentId, null, null, null, artifactId, responseFormat, componentType, null);
240 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
242 // step 3 - check user existence
244 // step 4 - check user's role
245 User user = validateUserExists(userId, auditingAction, componentId, artifactId, componentType, inTransaction);
246 validateUserRole(user, auditingAction, componentId, artifactId, componentType, operation);
249 // 5. check service/resource existence
251 // 6. check service/resource check out
253 // 7. user is owner of checkout state
254 Component component = null;
255 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
256 component = validateComponentExists(realComponentId, auditingAction, user, artifactId, componentType, containerComponentType);
257 validateWorkOnComponent(component, userId, auditingAction, user, artifactId, operation);
258 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
259 validateResourceInstanceById(component, componentId);
262 return validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
263 operationName, user, component, shouldLock, inTransaction, true);
266 public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
267 ArtifactOperationInfo operation, String artifactId,
268 ArtifactDefinition artifactInfo, String origMd5, String originData,
269 String interfaceName, String operationName, String parentId,
270 String containerComponentType) {
271 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
272 operationName, parentId, containerComponentType, true, false);
276 * This Method validates only the Artifact and does not validate user / role / component ect...<br> For regular usage use <br> {@link
277 * #handleArtifactRequest(String, String, ComponentTypeEnum, ArtifactOperationInfo, String, ArtifactDefinition, String, String, String, String,
282 public Either<ArtifactDefinition, Operation> validateAndHandleArtifact(String componentUniqueId, ComponentTypeEnum componentType,
283 ArtifactOperationInfo operation, String artifactUniqueId,
284 ArtifactDefinition artifactDefinition, String origMd5, String originData,
285 String interfaceName, String operationName, User user, Component component,
286 boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
287 AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
288 artifactDefinition = validateArtifact(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, auditingAction, user,
289 component, shouldLock, inTransaction);
291 Either<ArtifactDefinition, Operation> result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition,
292 origMd5, originData, interfaceName, operationName, auditingAction, user, component, shouldLock, inTransaction, needUpdateGroup);
293 //TODO: audit positive action
298 ArtifactDefinition validateArtifact(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId,
299 ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, User user, Component component,
300 boolean shouldLock, boolean inTransaction) {
301 ArtifactDefinition artifactInfoToReturn = artifactInfo;
302 ArtifactOperationEnum operationEnum = operation.getArtifactOperationEnum();
303 if (operationEnum == ArtifactOperationEnum.UPDATE || operationEnum == ArtifactOperationEnum.DELETE
304 || operationEnum == ArtifactOperationEnum.DOWNLOAD) {
305 ArtifactDefinition dbArtifact = getArtifactIfBelongsToComponent(componentId, componentType, artifactId, component);
306 if (operation.isDownload()) {
307 artifactInfoToReturn = dbArtifact;
308 handleHeatEnvDownload(componentId, componentType, user, component, dbArtifact, shouldLock, inTransaction);
311 return artifactInfoToReturn;
315 void handleHeatEnvDownload(String componentId, ComponentTypeEnum componentType, User user, Component component,
316 ArtifactDefinition artifactDefinition, boolean shouldLock, boolean inTransaction) {
317 if (artifactDefinition.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType()) && ComponentTypeEnum.SERVICE == component
318 .getComponentType()) {
319 ComponentInstance componentInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId))
320 .findAny().orElse(null);
321 if (componentInstance == null) {
322 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentId, "instance", "Service",
323 component.getName());
325 Map<String, ArtifactDefinition> deploymentArtifacts = componentInstance.getDeploymentArtifacts();
326 ArtifactDefinition heatEnvWithHeatParams = deploymentArtifacts.values().stream()
327 .filter(p -> p.getUniqueId().equals(artifactDefinition.getUniqueId())).findAny().orElse(null);
328 Either<ArtifactDefinition, ResponseFormat> eitherGenerated = generateHeatEnvArtifact(heatEnvWithHeatParams, componentType, component,
329 componentInstance.getName(), user, componentId, shouldLock, inTransaction);
330 if (eitherGenerated.isRight()) {
331 throw new ByResponseFormatComponentException((eitherGenerated.right().value()));
336 private boolean artifactGenerationRequired(Component component, ArtifactDefinition artifactInfo) {
337 boolean needGenerate;
338 needGenerate = artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && (
339 component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN
340 || component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
341 needGenerate = needGenerate || (ComponentTypeEnum.RESOURCE == component.getComponentType() && (
342 artifactInfo.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType()) || isAbstractVfcEmptyCsar((Resource) component,
347 private boolean isAbstractVfcEmptyCsar(Resource resource, ArtifactDefinition artifactInfo) {
348 return resource.isAbstract() && artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && artifactInfo.getArtifactType()
349 .equals(ArtifactTypeEnum.TOSCA_CSAR.getType()) && StringUtils.isEmpty(artifactInfo.getArtifactChecksum());
352 public Either<ArtifactDefinition, Operation> generateAndSaveToscaArtifact(ArtifactDefinition artifactDefinition, Component component, User user,
353 boolean isInCertificationRequest, boolean shouldLock,
354 boolean inTransaction, boolean fetchTemplatesFromDB) {
355 return decodeToscaArtifactPayload(component, isInCertificationRequest, fetchTemplatesFromDB, artifactDefinition.getArtifactType()).left()
357 // TODO: Avoid output argument
358 artifactDefinition.setPayload(payload);
359 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
360 artifactDefinition.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(payload));
361 return lockComponentAndUpdateArtifact(component.getUniqueId(), artifactDefinition, AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE,
362 artifactDefinition.getUniqueId(), user, component.getComponentType(), component, payload, shouldLock, inTransaction);
363 }).right().map(ex -> {
364 // TODO: This should not be done but in order to keep this refactoring small enough, we stop here.
366 // Bubble up this exception
371 private Either<byte[], ComponentException> decodeToscaArtifactPayload(Component parent, boolean isInCertificationRequest,
372 boolean fetchTemplatesFromDB, String artifactType) {
373 log.debug("tosca artifact generation");
374 if (ArtifactTypeEnum.TOSCA_CSAR.getType().equals(artifactType)) {
375 return csarUtils.createCsar(parent, fetchTemplatesFromDB, isInCertificationRequest).right().map(error -> {
376 log.debug("Failed to generate tosca csar for component {} error {}", parent.getUniqueId(), error);
377 return new ByResponseFormatComponentException(error);
380 return toscaExportUtils.exportComponent(parent).left().map(toscaRepresentation -> {
381 log.debug("Tosca yaml exported for component {} ", parent.getUniqueId());
382 return toscaRepresentation.getMainYaml();
383 }).right().map(toscaError -> {
384 log.debug("Failed export tosca yaml for component {} error {}", parent.getUniqueId(), toscaError);
385 return new ByActionStatusComponentException(componentsUtils.convertFromToscaError(toscaError));
390 private Either<ArtifactDefinition, Operation> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
391 String artifactId, ArtifactDefinition artifactInfo, String origMd5, String originData,
392 String interfaceName, String operationName, AuditingActionEnum auditingAction, User user,
393 Component parent, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
394 if (interfaceName != null && operationName != null) {
395 interfaceName = interfaceName.toLowerCase();
396 operationName = operationName.toLowerCase();
399 lockComponent(componentType, artifactId, auditingAction, user, parent);
401 Either<ArtifactDefinition, Operation> result;
402 boolean operationSucceeded = false;
404 switch (operation.getArtifactOperationEnum()) {
406 if (artifactGenerationRequired(parent, artifactInfo)) {
407 result = Either.left(generateNotSavedArtifact(parent, artifactInfo));
409 result = Either.left(handleDownload(componentId, artifactId, componentType, parent));
413 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, parent));
416 result = handleUpdate(componentId, componentType, operation, artifactId, artifactInfo, null, origMd5, originData, interfaceName,
417 operationName, auditingAction, user, parent, needUpdateGroup);
420 result = handleCreate(componentId, artifactInfo, operation, auditingAction, user, componentType, parent, origMd5, originData,
421 interfaceName, operationName);
424 result = Either.left(handleLink(componentId, artifactInfo, componentType, parent));
427 throw new UnsupportedOperationException(
428 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
430 operationSucceeded = true;
433 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
437 private void lockComponent(ComponentTypeEnum componentType, String artifactId, AuditingActionEnum auditingAction, User user, Component parent) {
439 lockComponent(parent, ARTIFACT_ACTION_LOCK);
440 } catch (ComponentException e) {
441 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, null, null, artifactId, e.getResponseFormat(), componentType, null);
447 public Either<ArtifactDefinition, Operation> handleUpdate(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
448 String artifactId, ArtifactDefinition artifactInfo, byte[] decodedPayload,
449 String origMd5, String originData, String interfaceName, String operationName,
450 AuditingActionEnum auditingAction, User user, Component parent,
451 boolean needUpdateGroup) {
452 Either<ArtifactDefinition, Operation> result;
453 validateArtifactType(artifactInfo);
454 final String artifactType = artifactInfo.getArtifactType();
455 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && (ArtifactTypeEnum.HEAT.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_VOL
456 .getType().equals(artifactType) || ArtifactTypeEnum.HEAT_NET.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_ENV.getType()
457 .equals(artifactType))) {
458 result = handleUpdateHeatEnvAndHeatMeta(componentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, originData,
460 if (needUpdateGroup) {
461 ActionStatus error = updateGroupInstance(artifactInfo, result.left().value(), parent, componentId);
462 if (error != ActionStatus.OK) {
463 throw new ByActionStatusComponentException(error);
466 } else if (componentType == ComponentTypeEnum.RESOURCE && ArtifactTypeEnum.HEAT_ENV.getType().equals(artifactType)) {
467 result = handleUpdateHeatWithHeatEnvParams(componentId, artifactInfo, auditingAction, componentType, parent, originData, origMd5,
468 operation, needUpdateGroup);
470 if (decodedPayload == null) {
471 decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5,
472 originData, interfaceName, operationName);
474 result = updateArtifactFlow(parent, componentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
475 if (needUpdateGroup && result.isLeft()) {
476 ArtifactDefinition updatedArtifact = result.left().value();
477 updateGroupForHeat(artifactInfo, updatedArtifact, parent);
483 private void validateArtifactType(final ArtifactDefinition artifactInfo) {
484 if (!isArtifactSupported(artifactInfo.getArtifactType())) {
485 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
489 private void validateArtifactType(final ArtifactDefinition artifactInfo, final ComponentTypeEnum componentType) {
490 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactInfo.getArtifactType()).orElse(null);
491 if (artifactConfiguration == null) {
492 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
493 log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName());
494 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE);
495 throw new ByResponseFormatComponentException(responseFormat);
497 final ArtifactGroupTypeEnum artifactGroupType = artifactInfo.getArtifactGroupType();
499 validateArtifactType(componentType, artifactGroupType, artifactConfiguration);
500 } catch (final ComponentException e) {
501 log.debug("Artifact is invalid", e);
502 BeEcompErrorManager.getInstance()
503 .logBeInvalidTypeError("Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(),
504 "Artifact " + artifactInfo.getArtifactName());
505 log.debug("Not supported artifact type = {}", artifactInfo.getArtifactType());
506 final ResponseFormat responseFormat = componentsUtils
507 .getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
508 throw new ByResponseFormatComponentException(responseFormat);
512 private void validateArtifactType(final ComponentTypeEnum componentType, final ArtifactGroupTypeEnum groupType,
513 final ArtifactConfiguration artifactConfiguration) {
514 final boolean supportComponentType =
515 CollectionUtils.isNotEmpty(artifactConfiguration.getComponentTypes()) && artifactConfiguration.getComponentTypes().stream()
516 .anyMatch(componentType1 -> componentType1.getValue().equalsIgnoreCase(componentType.getValue()));
517 if (!supportComponentType) {
518 log.debug("Artifact Type '{}' not supported for Component Type '{}'", artifactConfiguration.getType(), componentType.getValue());
519 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
521 final boolean supportResourceType = artifactConfiguration.hasSupport(groupType);
522 if (!supportResourceType) {
523 log.debug("Artifact Type '{}' not supported for Component Type '{}' and Category '{}'", artifactConfiguration.getType(),
524 componentType.getValue(), groupType.getType());
525 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
529 private boolean isArtifactSupported(final String artifactType) {
530 final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
531 final List<ArtifactConfiguration> artifactConfigurationList = configuration.getArtifacts();
532 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
535 return artifactConfigurationList.stream().anyMatch(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType));
539 public ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent) {
540 List<GroupDefinition> groups = parent.getGroups();
541 if (groups != null && !groups.isEmpty()) {
542 List<GroupDataDefinition> groupToUpdate = groups.stream()
543 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfo.getUniqueId())).collect(Collectors.toList());
544 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
545 groupToUpdate.forEach(g -> {
546 g.getArtifacts().remove(artifactInfo.getUniqueId());
547 g.getArtifactsUuid().remove(artifactInfo.getArtifactUUID());
548 g.getArtifacts().add(artAfterUpdate.getUniqueId());
549 g.getArtifactsUuid().add(artAfterUpdate.getArtifactUUID());
550 if (!artifactInfo.getArtifactUUID().equals(artAfterUpdate.getArtifactUUID())) {
551 g.setGroupUUID(UniqueIdBuilder.generateUUID());
554 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
555 if (status.isRight()) {
556 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
557 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status.right().value()));
561 return ActionStatus.OK;
565 ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfoHeat, ArtifactDefinition artHeatAfterUpdate, ArtifactDefinition artifactInfoHeatE,
566 ArtifactDefinition artHEAfterUpdate, Component parent) {
567 List<GroupDefinition> groups = parent.getGroups();
568 if (groups != null && !groups.isEmpty()) {
569 List<GroupDataDefinition> groupToUpdate = groups.stream()
570 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfoHeat.getUniqueId())).collect(Collectors.toList());
571 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
572 groupToUpdate.forEach(g -> {
573 g.getArtifacts().remove(artifactInfoHeat.getUniqueId());
574 g.getArtifactsUuid().remove(artifactInfoHeat.getArtifactUUID());
575 g.getArtifacts().remove(artifactInfoHeatE.getUniqueId());
576 g.getArtifacts().add(artHeatAfterUpdate.getUniqueId());
577 g.getArtifactsUuid().add(artHeatAfterUpdate.getArtifactUUID());
578 g.getArtifacts().add(artHEAfterUpdate.getUniqueId());
580 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
581 if (status.isRight()) {
582 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
583 return componentsUtils.convertFromStorageResponse(status.right().value());
587 return ActionStatus.OK;
590 private ActionStatus updateGroupInstance(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent, String parentId) {
591 List<GroupInstance> updatedGroupInstances = new ArrayList<>();
592 List<GroupInstance> groupInstances = null;
593 Optional<ComponentInstance> componentInstOp = parent.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(parentId))
595 if (componentInstOp.isPresent()) {
596 groupInstances = componentInstOp.get().getGroupInstances();
598 if (CollectionUtils.isNotEmpty(groupInstances)) {
599 boolean isUpdated = false;
600 for (GroupInstance groupInstance : groupInstances) {
602 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifacts()) && groupInstance.getGroupInstanceArtifacts()
603 .contains(artifactInfo.getUniqueId())) {
604 groupInstance.getGroupInstanceArtifacts().remove(artifactInfo.getUniqueId());
605 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getUniqueId());
608 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifactsUuid()) && groupInstance.getGroupInstanceArtifactsUuid()
609 .contains(artifactInfo.getArtifactUUID())) {
610 groupInstance.getGroupInstanceArtifactsUuid().remove(artifactInfo.getArtifactUUID());
611 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getArtifactUUID());
615 updatedGroupInstances.add(groupInstance);
619 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
620 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
621 if (status.isRight()) {
622 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
623 return componentsUtils.convertFromStorageResponse(status.right().value());
625 return ActionStatus.OK;
628 ArtifactDefinition generateNotSavedArtifact(Component parent, ArtifactDefinition artifactDefinition) {
629 if (artifactDefinition.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA) {
630 Either<byte[], ComponentException> decodedPayload = decodeToscaArtifactPayload(parent, false, false,
631 artifactDefinition.getArtifactType());
632 // TODO: This should not be done, but in order to keep this refactoring relatively small, we stop here
633 if (decodedPayload.isRight()) {
634 throw decodedPayload.right().value();
636 artifactDefinition.setPayload(decodedPayload.left().value());
637 return artifactDefinition;
640 String heatArtifactId = artifactDefinition.getGeneratedFromId();
641 Either<ArtifactDefinition, StorageOperationStatus> heatRes = artifactToscaOperation.getArtifactById(parent.getUniqueId(), heatArtifactId);
642 if (heatRes.isRight()) {
643 log.debug("Failed to fetch heat artifact by generated id {} for heat env {}", heatArtifactId, artifactDefinition.getUniqueId());
644 throw new StorageException(heatRes.right().value());
646 String generatedPayload = generateHeatEnvPayload(heatRes.left().value());
647 artifactDefinition.setPayloadData(generatedPayload);
648 return artifactDefinition;
652 private Either<ArtifactDefinition, Operation> handleUpdateHeatWithHeatEnvParams(String componentId, ArtifactDefinition artifactInfo,
653 AuditingActionEnum auditingAction,
654 ComponentTypeEnum componentType, Component parent,
655 String originData, String origMd5,
656 ArtifactOperationInfo operation, boolean needToUpdateGroup) {
657 Either<ArtifactDefinition, StorageOperationStatus> artifactHeatRes = artifactToscaOperation
658 .getArtifactById(componentId, artifactInfo.getGeneratedFromId());
659 ArtifactDefinition currHeatArtifact = artifactHeatRes.left().value();
660 if (origMd5 != null) {
661 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
662 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
663 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
664 } else { // duplicate
665 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
668 return updateHeatParams(componentId, artifactInfo, auditingAction, parent, componentType, currHeatArtifact, needToUpdateGroup);
671 private void handleLockingAndCommit(Component parent, boolean shouldLock, boolean inTransaction, boolean actionSucceeded) {
672 if (actionSucceeded) {
674 if (!inTransaction) {
675 janusGraphDao.commit();
679 if (!inTransaction) {
680 janusGraphDao.rollback();
684 graphLockOperation.unlockComponent(parent.getUniqueId(), parent.getComponentType().getNodeType());
688 public ImmutablePair<String, byte[]> handleDownloadToscaModelRequest(Component component, ArtifactDefinition csarArtifact) {
689 if (artifactGenerationRequired(component, csarArtifact)) {
690 Either<byte[], ResponseFormat> generated = csarUtils.createCsar(component, false, false);
691 if (generated.isRight()) {
692 log.debug("Failed to export tosca csar for component {} error {}", component.getUniqueId(), generated.right().value());
693 throw new ByResponseFormatComponentException(generated.right().value());
695 return new ImmutablePair<>(csarArtifact.getArtifactName(), generated.left().value());
697 return downloadArtifact(csarArtifact);
700 public ImmutablePair<String, byte[]> handleDownloadRequestById(String componentId, String artifactId, String userId,
701 ComponentTypeEnum componentType, String parentId, String containerComponentType) {
702 // perform all validation in common flow
703 Either<ArtifactDefinition, Operation> result = handleArtifactRequest(componentId, userId, componentType,
704 new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DOWNLOAD), artifactId, null, null, null, null, null, parentId,
705 containerComponentType);
706 ArtifactDefinition artifactDefinition;
707 Either<ArtifactDefinition, Operation> insideValue = result;
708 if (insideValue.isLeft()) {
709 artifactDefinition = insideValue.left().value();
711 artifactDefinition = insideValue.right().value().getImplementationArtifact();
713 // for tosca artifacts and heat env on VF level generated on download without saving
714 if (artifactDefinition.getPayloadData() != null) {
715 return (new ImmutablePair<>(artifactDefinition.getArtifactName(), artifactDefinition.getPayloadData()));
717 return downloadArtifact(artifactDefinition);
720 public Map<String, ArtifactDefinition> handleGetArtifactsByType(String containerComponentType, String parentId, ComponentTypeEnum componentType,
721 String componentId, String artifactGroupType, String userId) {
724 // detect auditing type
725 Map<String, ArtifactDefinition> resMap = null;
730 if (userId == null) {
731 log.debug("handleGetArtifactsByType - no HTTP_CSP_HEADER , component id {}", componentId);
732 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
736 // check user existence
741 validateUserExists(userId);
744 // 5. check service/resource existence
746 // 6. check service/resource check out
748 // 7. user is owner of checkout state
749 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
750 ComponentParametersView componentFilter = new ComponentParametersView();
751 componentFilter.disableAll();
752 componentFilter.setIgnoreArtifacts(false);
753 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
754 componentFilter.setIgnoreComponentInstances(false);
756 Component component = validateComponentExistsByFilter(realComponentId, ComponentTypeEnum.findByParamName(containerComponentType),
758 lockComponent(component, ARTIFACT_ACTION_LOCK);
759 boolean failed = false;
761 ArtifactGroupTypeEnum groupType = ArtifactGroupTypeEnum.findType(artifactGroupType);
762 if (groupType == null) {
763 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
764 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
766 if (parentId == null && groupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
767 List<ArtifactDefinition> list = getDeploymentArtifacts(component, componentId);
768 if (list != null && !list.isEmpty()) {
769 resMap = list.stream().collect(Collectors.toMap(ArtifactDataDefinition::getArtifactLabel, Function.identity()));
771 resMap = new HashMap<>();
775 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsMapStatus = getArtifacts(realComponentId,
776 componentType.getNodeType(), groupType, componentId);
777 if (artifactsMapStatus.isRight()) {
778 if (artifactsMapStatus.right().value() != StorageOperationStatus.NOT_FOUND) {
779 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
780 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
782 resMap = new HashMap<>();
785 resMap = artifactsMapStatus.left().value();
789 } catch (ComponentException e) {
796 janusGraphDao.rollback();
799 janusGraphDao.commit();
801 componentType = component.getComponentType();
802 NodeTypeEnum nodeType = componentType.getNodeType();
803 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
807 private ArtifactDefinition getArtifactIfBelongsToComponent(String componentId, ComponentTypeEnum componentType, String artifactId,
808 Component component) {
809 // check artifact existence
810 Either<ArtifactDefinition, StorageOperationStatus> artifactResult = artifactToscaOperation
811 .getArtifactById(componentId, artifactId, componentType, component.getUniqueId());
812 if (artifactResult.isRight()) {
813 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentId);
815 // verify artifact belongs to component
817 switch (componentType) {
820 found = ComponentUtils.checkArtifactInComponent(component, artifactId);
822 case RESOURCE_INSTANCE:
823 found = ComponentUtils.checkArtifactInResourceInstance(component, componentId, artifactId);
829 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentType.name().toLowerCase());
831 return artifactResult.left().value();
834 private Either<ArtifactDefinition, Operation> handleCreate(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
835 AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType,
836 Component parent, String origMd5, String originData, String interfaceType,
837 String operationName) {
838 byte[] decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, null, user, componentType, parent, origMd5,
839 originData, interfaceType, operationName);
840 return createArtifact(parent, componentId, artifactInfo, decodedPayload, componentType, auditingAction, interfaceType, operationName);
843 private ArtifactDefinition handleLink(String componentId, ArtifactDefinition artifactInfo, ComponentTypeEnum componentType, Component parent) {
844 ComponentInstance foundInstance = findComponentInstance(componentId, parent);
845 String instanceId = null;
846 if (foundInstance != null) {
847 instanceId = foundInstance.getUniqueId();
849 NodeTypeEnum nodeType = convertParentType(componentType);
850 Either<ArtifactDefinition, StorageOperationStatus> artifactDefinitionEither = artifactToscaOperation
851 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
852 if (artifactDefinitionEither.isRight()) {
853 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
855 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), componentId, componentType) != StorageOperationStatus.OK) {
856 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
858 return artifactDefinitionEither.left().value();
861 private <T> Either<ArtifactDefinition, T> lockComponentAndUpdateArtifact(String parentId, ArtifactDefinition artifactInfo,
862 AuditingActionEnum auditingAction, String artifactId, User user,
863 ComponentTypeEnum componentType, Component parent, byte[] decodedPayload,
864 boolean shouldLock, boolean inTransaction) {
865 boolean failed = false;
866 boolean writeAudit = true;
868 lockComponent(parent, shouldLock, ARTIFACT_ACTION_LOCK);
870 return updateArtifactFlow(parent, parentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
871 } catch (ComponentException ce) {
873 handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, ce.getResponseFormat(), componentType, null);
877 } catch (StorageException se) {
883 unlockComponent(failed, parent, inTransaction);
888 private byte[] validateInput(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
889 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
890 String origMd5, String originData, String interfaceType, String operationName) {
891 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
892 return getValidPayload(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, interfaceType,
896 private byte[] getValidPayload(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
897 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
898 String interfaceType, String operationName) {
900 Either<ArtifactDefinition, ResponseFormat> validateResult = validateInput(componentId, artifactInfo, operation, artifactId, user,
901 interfaceType, operationName, componentType, parent);
902 if (validateResult.isRight()) {
903 ResponseFormat responseFormat = validateResult.right().value();
904 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
905 throw new ByResponseFormatComponentException(responseFormat);
907 Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
908 if (payloadEither.isRight()) {
909 ResponseFormat responseFormat = payloadEither.right().value();
910 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
911 log.debug("Error during handle payload");
912 throw new ByResponseFormatComponentException(responseFormat);
914 // validate heat parameters. this part must be after the parameters are
916 // extracted in "handlePayload"
917 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters = validateAndConvertHeatParameters(artifactInfo,
918 artifactInfo.getArtifactType());
919 if (validateAndConvertHeatParameters.isRight()) {
920 ResponseFormat responseFormat = validateAndConvertHeatParameters.right().value();
921 handleAuditing(auditingAction, parent, componentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null);
922 log.debug("Error during handle payload");
923 throw new ByResponseFormatComponentException(responseFormat);
925 return payloadEither.left().value();
928 public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
929 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
930 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
931 if (componentsUtils.isExternalApiEvent(auditingActionEnum)) {
936 user.setUserId("UNKNOWN");
938 handleInternalAuditEvent(auditingActionEnum, component, componentId, user, artifactDefinition, prevArtifactUuid, currentArtifactUuid,
939 responseFormat, componentTypeEnum, resourceInstanceName);
942 private void handleInternalAuditEvent(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
943 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
944 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
945 switch (componentTypeEnum) {
947 Resource resource = (Resource) component;
948 if (resource == null) {
949 // In that case, component ID should be instead of name
950 resource = new Resource();
951 resource.setName(componentId);
953 componentsUtils.auditResource(responseFormat, user, resource, resource.getName(), auditingActionEnum,
954 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(), currentArtifactUuid, artifactDefinition);
957 Service service = (Service) component;
958 if (service == null) {
959 // In that case, component ID should be instead of name
960 service = new Service();
961 service.setName(componentId);
964 .auditComponent(responseFormat, user, service, auditingActionEnum, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
965 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
966 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
968 case RESOURCE_INSTANCE:
969 if (resourceInstanceName == null) {
970 resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId);
972 componentsUtils.auditComponent(responseFormat, user, component, auditingActionEnum,
973 new ResourceCommonInfo(resourceInstanceName, ComponentTypeEnum.RESOURCE_INSTANCE.getValue()),
974 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
975 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
982 private String getResourceInstanceNameFromComponent(Component component, String componentId) {
983 ComponentInstance resourceInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findFirst()
985 String resourceInstanceName = null;
986 if (resourceInstance != null) {
987 resourceInstanceName = resourceInstance.getName();
989 return resourceInstanceName;
992 private void validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperationInfo operation) {
993 if (origMd5 == null) {
994 if (operation.isCreateOrLink() && ArrayUtils.isNotEmpty(payload)) {
995 log.debug("Missing md5 header during artifact create");
996 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
999 if (ArrayUtils.isNotEmpty(payload)) {
1000 log.debug("Cannot have payload while md5 header is missing");
1001 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
1004 String encodeBase64Str = GeneralUtility.calculateMD5Base64EncodedByString(originData);
1005 if (!encodeBase64Str.equals(origMd5)) {
1006 log.debug("The calculated md5 is different then the received one");
1007 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1012 private Either<ArtifactDefinition, ResponseFormat> validateInput(final String componentId, final ArtifactDefinition artifactInfo,
1013 final ArtifactOperationInfo operation, final String artifactId, final User user,
1014 String interfaceName, String operationName,
1015 final ComponentTypeEnum componentType, final Component parentComponent) {
1016 final ArtifactDefinition existingArtifactInfo = findArtifact(parentComponent, componentType, componentId, operation, artifactId);
1017 final boolean isCreateOrLinkOperation = ArtifactOperationEnum.isCreateOrLink(operation.getArtifactOperationEnum());
1018 if (!isCreateOrLinkOperation && existingArtifactInfo == null) {
1019 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1021 final Component component;
1022 if (parentComponent.getUniqueId().equals(componentId)) {
1023 component = parentComponent;
1025 final ComponentInstance componentInstance = findComponentInstance(componentId, parentComponent);
1026 component = findComponent(componentInstance.getComponentUid());
1027 component.setComponentType(componentType);
1029 if (!isCreateOrLinkOperation) {
1030 ignoreUnupdateableFieldsInUpdate(operation, artifactInfo, existingArtifactInfo);
1032 if (isInformationalArtifact(artifactInfo)) {
1033 validateInformationalArtifact(artifactInfo, component);
1035 Either<Boolean, ResponseFormat> validateAndSetArtifactname = validateAndSetArtifactName(artifactInfo);
1036 if (validateAndSetArtifactname.isRight()) {
1037 return Either.right(validateAndSetArtifactname.right().value());
1039 if (!validateArtifactNameUniqueness(componentId, parentComponent, artifactInfo, componentType)) {
1040 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST));
1042 if (operationName != null && interfaceName != null) {
1043 operationName = operationName.toLowerCase();
1044 interfaceName = interfaceName.toLowerCase();
1046 Either<ActionStatus, ResponseFormat> logicalNameStatus = handleArtifactLabel(componentId, parentComponent, operation, artifactInfo,
1047 operationName, componentType);
1048 if (logicalNameStatus.isRight()) {
1049 return Either.right(logicalNameStatus.right().value());
1051 // This is a patch to block possibility of updating service api fields
1053 // through other artifacts flow
1054 final ArtifactGroupTypeEnum artifactGroupType =
1055 operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL;
1056 if (operation.isNotCreateOrLink()) {
1057 checkAndSetUnUpdatableFields(user, artifactInfo, existingArtifactInfo, artifactGroupType);
1059 checkCreateFields(user, artifactInfo, artifactGroupType);
1061 composeArtifactId(componentId, artifactId, artifactInfo, interfaceName, operationName);
1062 if (existingArtifactInfo != null) {
1063 artifactInfo.setMandatory(existingArtifactInfo.getMandatory());
1064 if (operation.isNotCreateOrLink()) {
1065 validateArtifactTypeNotChanged(artifactInfo, existingArtifactInfo);
1068 // artifactGroupType is not allowed to be updated
1069 if (operation.isNotCreateOrLink()) {
1070 Either<ArtifactDefinition, ResponseFormat> validateGroupType = validateOrSetArtifactGroupType(artifactInfo, existingArtifactInfo);
1071 if (validateGroupType.isRight()) {
1072 return Either.right(validateGroupType.right().value());
1075 setArtifactTimeout(artifactInfo, existingArtifactInfo);
1076 if (isHeatArtifact(artifactInfo)) {
1077 validateHeatArtifact(parentComponent, componentId, artifactInfo);
1079 if (isDeploymentArtifact(artifactInfo)) {
1080 if (componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1081 final String artifactName = artifactInfo.getArtifactName();
1082 final String existingArtifactName = (existingArtifactInfo == null) ? null : existingArtifactInfo.getArtifactName();
1083 if (operation.isCreateOrLink() || ((artifactName != null) && !artifactName.equalsIgnoreCase(existingArtifactName))) {
1084 validateSingleDeploymentArtifactName(artifactName, parentComponent);
1087 validateDeploymentArtifact(artifactInfo, component);
1089 Either<Boolean, ResponseFormat> descriptionResult = validateAndCleanDescription(artifactInfo);
1090 if (descriptionResult.isRight()) {
1091 return Either.right(descriptionResult.right().value());
1093 validateArtifactType(artifactInfo, component.getComponentType());
1094 artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase());
1095 if (existingArtifactInfo != null && existingArtifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.SERVICE_API) {
1096 // Change of type is not allowed and should be ignored
1097 artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER);
1098 Either<Boolean, ResponseFormat> validateUrl = validateAndServiceApiUrl(artifactInfo);
1099 if (validateUrl.isRight()) {
1100 return Either.right(validateUrl.right().value());
1102 Either<Boolean, ResponseFormat> validateUpdate = validateFirstUpdateHasPayload(artifactInfo, existingArtifactInfo);
1103 if (validateUpdate.isRight()) {
1104 log.debug("serviceApi first update cnnot be without payload.");
1105 return Either.right(validateUpdate.right().value());
1108 if (artifactInfo.getApiUrl() != null) {
1109 artifactInfo.setApiUrl(null);
1110 log.error("Artifact URL cannot be set through this API - ignoring");
1112 if (Boolean.TRUE.equals(artifactInfo.getServiceApi())) {
1113 artifactInfo.setServiceApi(false);
1114 log.error("Artifact service API flag cannot be changed - ignoring");
1117 return Either.left(artifactInfo);
1120 private Component findComponent(final String componentId) {
1121 Either<? extends Component, StorageOperationStatus> component = toscaOperationFacade.getToscaFullElement(componentId);
1122 if (component.isRight()) {
1123 log.debug("Component '{}' not found ", componentId);
1124 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentId);
1126 return component.left().value();
1129 private void ignoreUnupdateableFieldsInUpdate(final ArtifactOperationInfo operation, final ArtifactDefinition artifactInfo,
1130 final ArtifactDefinition currentArtifactInfo) {
1131 if (operation.isUpdate()) {
1132 artifactInfo.setArtifactType(currentArtifactInfo.getArtifactType());
1133 artifactInfo.setArtifactGroupType(currentArtifactInfo.getArtifactGroupType());
1134 artifactInfo.setArtifactLabel(currentArtifactInfo.getArtifactLabel());
1138 private ArtifactDefinition findArtifact(final Component parentComponent, final ComponentTypeEnum componentType, final String parentId,
1139 final ArtifactOperationInfo operation, final String artifactId) {
1140 ArtifactDefinition foundArtifact = null;
1141 if (StringUtils.isNotEmpty(artifactId)) {
1142 foundArtifact = findArtifact(parentComponent, componentType, parentId, artifactId);
1144 if (foundArtifact != null && operation.isCreateOrLink()) {
1145 log.debug("Artifact {} already exist", artifactId);
1146 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, foundArtifact.getArtifactLabel());
1148 if (foundArtifact == null && operation.isNotCreateOrLink()) {
1149 log.debug("The artifact {} was not found on parent component or instance {}. ", artifactId, parentId);
1150 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, "");
1152 return foundArtifact;
1155 private ArtifactDefinition findArtifact(Component parentComponent, ComponentTypeEnum componentType, String parentId, String artifactId) {
1156 ArtifactDefinition foundArtifact;
1157 if (parentComponent.getUniqueId().equals(parentId)) {
1158 foundArtifact = artifactsResolver.findArtifactOnComponent(parentComponent, componentType, artifactId);
1160 ComponentInstance instance = findComponentInstance(parentId, parentComponent);
1161 foundArtifact = artifactsResolver.findArtifactOnComponentInstance(instance, artifactId);
1163 return foundArtifact;
1166 private void validateInformationalArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1167 final ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
1168 if (groupType != ArtifactGroupTypeEnum.INFORMATIONAL) {
1171 final ComponentTypeEnum parentComponentType = component.getComponentType();
1172 final String artifactType = artifactInfo.getArtifactType();
1173 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1174 if (artifactConfiguration == null) {
1175 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1177 validateArtifactType(parentComponentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1178 if (component.getComponentType() == ComponentTypeEnum.RESOURCE || component.getComponentType() == ComponentTypeEnum.RESOURCE_INSTANCE) {
1179 final ResourceTypeEnum resourceType = ((Resource) component).getResourceType();
1180 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1182 validateArtifactExtension(artifactConfiguration, artifactInfo);
1185 private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) {
1186 if (componentType == ComponentTypeEnum.RESOURCE) {
1187 return NodeTypeEnum.Resource;
1188 } else if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1189 return NodeTypeEnum.ResourceInstance;
1191 return NodeTypeEnum.Service;
1195 // This method is here for backward compatibility - when other parts of the code are cleaned can change to use the internal version
1196 public Either<ArtifactDefinition, ResponseFormat> handleDelete(String parentId, String artifactId, User user, Component parent,
1197 boolean shouldLock, boolean inTransaction) {
1198 ResponseFormat responseFormat;
1199 boolean operationSucceeded = false;
1201 lockComponent(ComponentTypeEnum.RESOURCE, artifactId, AuditingActionEnum.ARTIFACT_DELETE, user, parent);
1204 ArtifactDefinition artifactDefinition = handleDeleteInternal(parentId, artifactId, ComponentTypeEnum.RESOURCE, parent);
1205 operationSucceeded = true;
1206 return Either.left(artifactDefinition);
1207 } catch (ComponentException ce) {
1208 responseFormat = componentsUtils.getResponseFormat(ce);
1209 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1210 ComponentTypeEnum.RESOURCE, null);
1211 return Either.right(responseFormat);
1212 } catch (StorageException se) {
1213 responseFormat = componentsUtils.getResponseFormat(se);
1214 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1215 ComponentTypeEnum.RESOURCE, null);
1216 return Either.right(responseFormat);
1218 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
1222 private ArtifactDefinition handleDeleteInternal(String parentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1223 NodeTypeEnum parentType = convertParentType(componentType);
1224 log.debug("Going to find the artifact {} on the component {}", artifactId, parent.getUniqueId());
1225 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> getArtifactRes = findArtifact(artifactId, parent, parentId,
1227 if (getArtifactRes.isRight()) {
1228 log.debug("Failed to find the artifact {} belonging to {} on the component {}", artifactId, parentId, parent.getUniqueId());
1229 throw new ByActionStatusComponentException(getArtifactRes.right().value(), artifactId);
1231 ArtifactDefinition foundArtifact = getArtifactRes.left().value().getLeft();
1232 ComponentInstance foundInstance = getArtifactRes.left().value().getRight();
1233 String esId = foundArtifact.getEsId();
1234 Either<Boolean, StorageOperationStatus> needClone = ifTrue(StringUtils.isNotEmpty(esId),
1235 () -> forEach(artifactToscaOperation.isCloneNeeded(parent.getUniqueId(), foundArtifact, parentType), b -> log
1236 .debug("handleDelete: clone is needed for deleting {} held by {} in component {} {}? {}", foundArtifact.getArtifactName(), parentType,
1237 parent.getUniqueId(), parent.getName(), b)));
1238 boolean needToClone = false;
1239 // TODO: This should not be done, but in order to keep this refactoring small, we stop here.
1241 // Remove this block once the above refactoring is merged.
1242 if (needClone.isLeft()) {
1243 needToClone = needClone.left().value();
1245 throw new StorageException(needClone.right().value(), foundArtifact.getArtifactDisplayName());
1247 boolean isNeedToDeleteArtifactFromDB =
1248 componentType == ComponentTypeEnum.RESOURCE_INSTANCE && isArtifactOnlyResourceInstanceArtifact(foundArtifact, parent, parentId);
1249 boolean isDuplicated = false;
1250 ArtifactDataDefinition updatedArtifact = deleteOrUpdateArtifactOnGraph(parent, parentId, artifactId, parentType, foundArtifact, needToClone);
1251 isDuplicated = updatedArtifact.getDuplicated();
1252 if (!needToClone && !isDuplicated && isNeedToDeleteArtifactFromDB) {
1253 log.debug("Going to delete the artifact {} from the database. ", artifactId);
1254 CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(esId);
1255 if (cassandraStatus != CassandraOperationStatus.OK) {
1256 log.debug("Failed to delete the artifact {} from the database. ", artifactId);
1257 throw new StorageException(convertToStorageOperationStatus(cassandraStatus), foundArtifact.getArtifactDisplayName());
1260 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1261 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(artifactId, foundArtifact, foundInstance.getGroupInstances());
1262 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
1263 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
1264 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
1265 if (status.isRight()) {
1266 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1267 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1270 StorageOperationStatus status = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
1271 if (status != StorageOperationStatus.OK) {
1272 log.debug("Failed to generate new customization UUID for the component instance {}. ", parentId);
1273 throw new StorageException(status, foundArtifact.getArtifactDisplayName());
1276 List<GroupDataDefinition> updatedGroups = getUpdatedGroups(artifactId, foundArtifact, parent.getGroups());
1277 if (CollectionUtils.isNotEmpty(updatedGroups)) {
1278 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, updatedGroups);
1279 if (status.isRight()) {
1280 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1281 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1285 return foundArtifact;
1288 private boolean isArtifactOnlyResourceInstanceArtifact(ArtifactDefinition foundArtifact, Component parent, String instanceId) {
1289 Optional<ComponentInstance> componentInstanceOpt = parent.getComponentInstanceById(instanceId);
1290 if (!componentInstanceOpt.isPresent()) {
1291 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "", "", parent.getName());
1293 ComponentInstance foundInstance = componentInstanceOpt.get();
1294 String componentUid = foundInstance.getComponentUid();
1295 Either<Component, StorageOperationStatus> getContainerRes = toscaOperationFacade.getToscaElement(componentUid);
1296 if (getContainerRes.isRight()) {
1297 log.debug("Failed to fetch the container component {}. ", componentUid);
1298 throw new StorageException(getContainerRes.right().value());
1300 Component origComponent = getContainerRes.left().value();
1301 Map<String, ArtifactDefinition> deploymentArtifacts = origComponent.getDeploymentArtifacts();
1302 if (MapUtils.isNotEmpty(deploymentArtifacts)) {
1303 Optional<String> op = deploymentArtifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1304 if (op.isPresent()) {
1308 Map<String, ArtifactDefinition> artifacts = origComponent.getArtifacts();
1309 if (MapUtils.isNotEmpty(artifacts)) {
1310 Optional<String> op = artifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1311 if (op.isPresent()) {
1318 private List<GroupDataDefinition> getUpdatedGroups(String artifactId, ArtifactDefinition foundArtifact, List<GroupDefinition> groups) {
1319 List<GroupDataDefinition> updatedGroups = new ArrayList<>();
1320 boolean isUpdated = false;
1321 if (groups != null) {
1322 for (GroupDefinition group : groups) {
1324 if (CollectionUtils.isNotEmpty(group.getArtifacts()) && group.getArtifacts().contains(artifactId)) {
1325 group.getArtifacts().remove(artifactId);
1328 if (CollectionUtils.isNotEmpty(group.getArtifactsUuid()) && group.getArtifactsUuid().contains(foundArtifact.getArtifactUUID())) {
1329 group.getArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1333 updatedGroups.add(group);
1337 return updatedGroups;
1340 private List<GroupInstance> getUpdatedGroupInstances(String artifactId, ArtifactDefinition foundArtifact, List<GroupInstance> groupInstances) {
1341 if (CollectionUtils.isEmpty(groupInstances)) {
1342 return new ArrayList<>();
1344 // TODO: A defensive copy should be created here for groupInstances. Modifying
1346 // arguments (aka output arguments) is overall a bad practice as explained in
1348 // Clean Code by Robert Martin.
1350 // A better approach would be to use Lenses.
1351 return groupInstances.stream().filter(gi -> {
1352 boolean groupInstanceArtifactRemoved = gi.getGroupInstanceArtifacts() != null && gi.getGroupInstanceArtifacts().remove(artifactId);
1353 boolean groupInstanceArtifactUUIDRemoved =
1354 gi.getGroupInstanceArtifactsUuid() != null && gi.getGroupInstanceArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1355 return groupInstanceArtifactRemoved || groupInstanceArtifactUUIDRemoved;
1356 }).collect(Collectors.toList());
1359 private ArtifactDataDefinition deleteOrUpdateArtifactOnGraph(Component component, String parentId, String artifactId, NodeTypeEnum parentType,
1360 ArtifactDefinition foundArtifact, Boolean cloneIsNeeded) {
1361 Either<ArtifactDataDefinition, StorageOperationStatus> result;
1362 boolean isMandatory = foundArtifact.getMandatory() || foundArtifact.getServiceApi();
1363 String componentId = component.getUniqueId();
1364 String instanceId = componentId.equals(parentId) ? null : parentId;
1366 log.debug("Going to update mandatory artifact {} from the component {}", artifactId, parentId);
1367 resetMandatoryArtifactFields(foundArtifact);
1368 result = artifactToscaOperation.updateArtifactOnGraph(component, foundArtifact, parentType, artifactId, instanceId, true, true);
1369 } else if (cloneIsNeeded) {
1370 log.debug("Going to clone artifacts and to delete the artifact {} from the component {}", artifactId, parentId);
1371 result = artifactToscaOperation.deleteArtifactWithCloningOnGraph(componentId, foundArtifact, parentType, instanceId, false);
1373 log.debug("Going to delete the artifact {} from the component {}", artifactId, parentId);
1374 result = artifactToscaOperation.removeArtifactOnGraph(foundArtifact, componentId, instanceId, parentType, false);
1376 if (result.isRight()) {
1377 throw new StorageException(result.right().value(), foundArtifact.getArtifactDisplayName());
1379 return result.left().value();
1382 private Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> findArtifact(String artifactId,
1383 Component fetchedContainerComponent,
1385 ComponentTypeEnum componentType) {
1386 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> result = null;
1387 Map<String, ArtifactDefinition> artifacts = new HashMap<>();
1388 ComponentInstance foundInstance = null;
1389 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && StringUtils.isNotEmpty(parentId)) {
1390 Optional<ComponentInstance> componentInstanceOpt = fetchedContainerComponent.getComponentInstances().stream()
1391 .filter(i -> i.getUniqueId().equals(parentId)).findFirst();
1392 if (!componentInstanceOpt.isPresent()) {
1393 result = Either.right(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER);
1395 foundInstance = componentInstanceOpt.get();
1396 fetchArtifactsFromInstance(artifactId, artifacts, foundInstance);
1399 fetchArtifactsFromComponent(artifactId, fetchedContainerComponent, artifacts);
1401 if (result == null) {
1402 if (artifacts.containsKey(artifactId)) {
1403 result = Either.left(new ImmutablePair<>(artifacts.get(artifactId), foundInstance));
1405 result = Either.right(ActionStatus.ARTIFACT_NOT_FOUND);
1411 private void fetchArtifactsFromComponent(String artifactId, Component component, Map<String, ArtifactDefinition> artifacts) {
1412 Map<String, ArtifactDefinition> currArtifacts;
1413 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
1414 currArtifacts = component.getDeploymentArtifacts().values().stream()
1415 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, i -> i));
1416 if (MapUtils.isNotEmpty(currArtifacts)) {
1417 artifacts.putAll(currArtifacts);
1420 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1421 currArtifacts = component.getArtifacts().values().stream()
1422 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1423 if (MapUtils.isNotEmpty(currArtifacts)) {
1424 artifacts.putAll(currArtifacts);
1427 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1428 currArtifacts = component.getToscaArtifacts().values().stream()
1429 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1430 if (MapUtils.isNotEmpty(currArtifacts)) {
1431 artifacts.putAll(currArtifacts);
1436 private void fetchArtifactsFromInstance(String artifactId, Map<String, ArtifactDefinition> artifacts, ComponentInstance instance) {
1437 Map<String, ArtifactDefinition> currArtifacts;
1438 if (MapUtils.isNotEmpty(instance.getDeploymentArtifacts())) {
1439 currArtifacts = instance.getDeploymentArtifacts().values().stream()
1440 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1441 if (MapUtils.isNotEmpty(currArtifacts)) {
1442 artifacts.putAll(currArtifacts);
1445 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(instance.getArtifacts())) {
1446 currArtifacts = instance.getArtifacts().values().stream()
1447 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1448 if (MapUtils.isNotEmpty(currArtifacts)) {
1449 artifacts.putAll(currArtifacts);
1454 private StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) {
1455 StorageOperationStatus result;
1456 switch (cassandraStatus) {
1458 result = StorageOperationStatus.OK;
1461 result = StorageOperationStatus.NOT_FOUND;
1463 case CLUSTER_NOT_CONNECTED:
1464 case KEYSPACE_NOT_CONNECTED:
1465 result = StorageOperationStatus.CONNECTION_FAILURE;
1468 result = StorageOperationStatus.GENERAL_ERROR;
1474 private void resetMandatoryArtifactFields(ArtifactDefinition fetchedArtifact) {
1475 if (fetchedArtifact != null) {
1476 log.debug("Going to reset mandatory artifact {} fields. ", fetchedArtifact.getUniqueId());
1477 fetchedArtifact.setEsId(null);
1478 fetchedArtifact.setArtifactName(null);
1479 fetchedArtifact.setDescription(null);
1480 fetchedArtifact.setApiUrl(null);
1481 fetchedArtifact.setArtifactChecksum(null);
1482 nodeTemplateOperation.setDefaultArtifactTimeout(fetchedArtifact.getArtifactGroupType(), fetchedArtifact);
1483 fetchedArtifact.setArtifactUUID(null);
1484 long time = System.currentTimeMillis();
1485 fetchedArtifact.setPayloadUpdateDate(time);
1486 fetchedArtifact.setHeatParameters(null);
1487 fetchedArtifact.setHeatParamsUpdateDate(null);
1491 private StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId, ComponentTypeEnum componentType) {
1492 StorageOperationStatus error = StorageOperationStatus.OK;
1493 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1494 log.debug("Need to re-generate customization UUID for instance {}", instanceId);
1495 error = toscaOperationFacade.generateCustomizationUUIDOnInstance(componentId, instanceId);
1500 private ArtifactDefinition handleDownload(String componentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1501 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation
1502 .getArtifactById(componentId, artifactId, componentType, parent.getUniqueId());
1503 if (artifactById.isRight()) {
1504 throw new StorageException(artifactById.right().value());
1506 ArtifactDefinition artifactDefinition = artifactById.left().value();
1507 if (artifactDefinition == null) {
1508 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1510 return artifactDefinition;
1513 private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String componentId, Component parentComponent, ArtifactOperationInfo operation,
1514 ArtifactDefinition artifactInfo, String operationName,
1515 ComponentTypeEnum componentType) {
1516 String artifactLabel = artifactInfo.getArtifactLabel();
1517 if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) {
1518 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
1519 log.debug("missing artifact logical name for component {}", componentId);
1520 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1522 if (operation.isCreateOrLink() && !artifactInfo.getMandatory()) {
1523 if (operationName != null) {
1524 if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) {
1525 log.debug("artifact label cannot be set {}", artifactLabel);
1526 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED));
1528 artifactLabel = operationName;
1531 String displayName = artifactInfo.getArtifactDisplayName();
1532 if (displayName == null || displayName.isEmpty()) {
1533 displayName = artifactLabel;
1535 displayName = ValidationUtils.cleanArtifactDisplayName(displayName);
1536 artifactInfo.setArtifactDisplayName(displayName);
1537 if (!ValidationUtils.validateArtifactLabel(artifactLabel)) {
1538 log.debug("Invalid format form Artifact label : {}", artifactLabel);
1539 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_ARTIFACT_LABEL_NAME, VALID_ARTIFACT_LABEL_NAME));
1541 artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel);
1542 if (artifactLabel.isEmpty()) {
1543 log.debug("missing normalized artifact logical name for component {}", componentId);
1544 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1546 if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) {
1547 log.debug("Invalid lenght form Artifact label : {}", artifactLabel);
1548 return Either.right(componentsUtils
1549 .getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH)));
1551 if (!validateLabelUniqueness(componentId, parentComponent, artifactLabel, componentType)) {
1552 log.debug("Non unique Artifact label : {}", artifactLabel);
1553 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel));
1556 artifactInfo.setArtifactLabel(artifactLabel);
1557 return Either.left(ActionStatus.OK);
1560 private boolean validateLabelUniqueness(String componentId, Component parentComponent, String artifactLabel, ComponentTypeEnum componentType) {
1561 boolean isUnique = true;
1562 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts;
1563 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1564 artifacts = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1566 artifacts = artifactToscaOperation.getArtifacts(componentId);
1568 if (artifacts.isLeft()) {
1569 for (String label : artifacts.left().value().keySet()) {
1570 if (label.equals(artifactLabel)) {
1576 if (componentType == ComponentTypeEnum.RESOURCE && isUnique) {
1577 isUnique = isUniqueLabelInResourceInterfaces(componentId, artifactLabel);
1582 boolean validateArtifactNameUniqueness(String componentId, Component parentComponent, ArtifactDefinition artifactInfo,
1583 ComponentTypeEnum componentType) {
1584 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = getArtifacts(componentType, parentComponent, componentId,
1585 artifactInfo.getArtifactGroupType());
1586 String artifactName = artifactInfo.getArtifactName();
1587 if (artifacts.isLeft() && Objects.nonNull(artifacts.left().value())) {
1588 if (artifacts.left().value().values().stream().anyMatch(ad -> artifactName.equals(ad.getArtifactName())
1589 //check whether it is the same artifact we hold (by label)
1590 && !artifactInfo.getArtifactLabel().equals(ad.getArtifactLabel()))) {
1594 if (ComponentTypeEnum.RESOURCE == componentType) {
1595 return isUniqueArtifactNameInResourceInterfaces(componentId, artifactName, artifactInfo.getArtifactLabel());
1600 private boolean isUniqueArtifactNameInResourceInterfaces(String componentId, String artifactName, String artifactLabel) {
1601 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1602 .getAllInterfacesOfResource(componentId, true, true);
1603 if (allInterfacesOfResource.isLeft()) {
1604 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1605 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1606 .noneMatch(add -> artifactName.equals(add.getArtifactName()) && !artifactLabel.equals(add.getArtifactLabel()));
1611 private boolean isUniqueLabelInResourceInterfaces(String componentId, String artifactLabel) {
1612 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1613 .getAllInterfacesOfResource(componentId, true, true);
1614 if (allInterfacesOfResource.isLeft()) {
1615 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1616 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1617 .noneMatch(add -> artifactLabel.equals(add.getArtifactLabel()));
1622 private Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(ComponentTypeEnum componentType, Component parentComponent,
1624 ArtifactGroupTypeEnum artifactGroupType) {
1625 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse;
1626 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1627 artifactsResponse = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1629 artifactsResponse = artifactToscaOperation.getArtifacts(componentId);
1631 if (artifactsResponse.isRight() && artifactsResponse.right().value() == StorageOperationStatus.NOT_FOUND) {
1632 log.debug("failed to retrieve artifacts for {} ", componentId);
1633 return Either.right(artifactsResponse.right().value());
1635 return Either.left(artifactsResponse.left().value().entrySet().stream().filter(x -> artifactGroupType == x.getValue().getArtifactGroupType())
1636 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
1639 // ***************************************************************
1640 private Either<ArtifactDefinition, Operation> createArtifact(Component parent, String parentId, ArtifactDefinition artifactInfo,
1641 byte[] decodedPayload, ComponentTypeEnum componentTypeEnum,
1642 AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) {
1643 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
1644 if (artifactData == null) {
1645 BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact");
1646 log.debug("Failed to create artifact object for ES.");
1647 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1649 ComponentInstance foundInstance = findComponentInstance(parentId, parent);
1650 String instanceId = null;
1651 if (foundInstance != null) {
1652 if (foundInstance.isArtifactExists(artifactInfo.getArtifactGroupType(), artifactInfo.getArtifactLabel())) {
1653 log.debug("Failed to create artifact, already exists");
1654 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, artifactInfo.getArtifactLabel());
1656 instanceId = foundInstance.getUniqueId();
1658 // set on graph object id of artifact in ES!
1659 artifactInfo.setEsId(artifactData.getId());
1660 Either<ArtifactDefinition, Operation> operationResult;
1661 if (interfaceType != null && operationName != null) {
1662 // lifecycle artifact
1663 Operation operation = convertToOperation(artifactInfo, operationName);
1664 Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation
1665 .updateInterfaceOperation(parentId, interfaceType, operationName, operation);
1666 if (result.isRight()) {
1667 throw new StorageException(result.right().value());
1669 operationResult = Either.right(result.left().value());
1671 // information/deployment/api artifacts
1672 NodeTypeEnum nodeType = convertParentType(componentTypeEnum);
1673 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
1674 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
1675 if (result.isRight()) {
1676 throw new StorageException(result.right().value());
1678 ArtifactDefinition artifactDefinition = result.left().value();
1679 artifactData.setId(artifactDefinition.getEsId());
1680 operationResult = Either.left(artifactDefinition);
1681 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum) != StorageOperationStatus.OK) {
1682 throw new StorageException(generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum));
1685 saveArtifactInCassandra(artifactData, parent, artifactInfo, "", "", auditingActionEnum, componentTypeEnum);
1686 return operationResult;
1689 private ComponentInstance findComponentInstance(String componentInstanceId, Component containerComponent) {
1690 ComponentInstance foundInstance = null;
1691 if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
1692 foundInstance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst()
1695 return foundInstance;
1698 private void validateDeploymentArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1699 final ComponentTypeEnum componentType = component.getComponentType();
1700 if (componentType != ComponentTypeEnum.RESOURCE && componentType != ComponentTypeEnum.SERVICE
1701 && componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1702 log.debug("Invalid component type '{}' for artifact. " + "Expected Resource, Component or Resource Instance", componentType.getValue());
1703 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, componentType.getValue(),
1704 "Service, Resource or ResourceInstance", componentType.getValue());
1706 final String artifactType = artifactInfo.getArtifactType();
1707 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1708 if (artifactConfiguration == null) {
1709 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1711 validateArtifactType(componentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1712 if (componentType == ComponentTypeEnum.RESOURCE || componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1713 final Resource resource = (Resource) component;
1714 final ResourceTypeEnum resourceType = resource.getResourceType();
1715 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1717 validateArtifactExtension(artifactConfiguration, artifactInfo);
1720 private void validateHeatArtifact(final Component parentComponent, final String componentId, final ArtifactDefinition artifactDefinition) {
1721 final String artifactType = artifactDefinition.getArtifactType();
1722 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1723 if (artifactTypeEnum == null) {
1726 switch (artifactTypeEnum) {
1730 validateHeatTimeoutValue(artifactDefinition);
1733 validateHeatEnvDeploymentArtifact(parentComponent, componentId, artifactDefinition);
1740 private void setArtifactTimeout(final ArtifactDefinition newArtifactInfo, final ArtifactDefinition existingArtifactInfo) {
1741 final String artifactType = newArtifactInfo.getArtifactType();
1742 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1743 if (artifactTypeEnum == null) {
1744 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1747 switch (artifactTypeEnum) {
1751 if (newArtifactInfo.getTimeout() == null) {
1752 if (existingArtifactInfo == null) {
1753 newArtifactInfo.setTimeout(NodeTemplateOperation.getDefaultHeatTimeout());
1755 newArtifactInfo.setTimeout(existingArtifactInfo.getTimeout());
1760 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1766 void validateDeploymentArtifactTypeIsLegalForParent(ArtifactDefinition artifactInfo, ArtifactTypeEnum artifactType,
1767 Map<String, ArtifactTypeConfig> resourceDeploymentArtifacts) {
1768 if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) {
1769 log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType());
1770 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
1774 Optional<ArtifactConfiguration> loadArtifactTypeConfig(final String artifactType) {
1775 if (artifactType == null) {
1776 return Optional.empty();
1778 final List<ArtifactConfiguration> artifactConfigurationList = ConfigurationManager.getConfigurationManager().getConfiguration()
1780 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
1781 return Optional.empty();
1783 return artifactConfigurationList.stream().filter(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType))
1787 private Either<Boolean, ResponseFormat> extractHeatParameters(ArtifactDefinition artifactInfo) {
1788 // extract heat parameters
1789 if (artifactInfo.getPayloadData() != null) {
1790 String heatDecodedPayload = new String(Base64.decodeBase64(artifactInfo.getPayloadData()));
1791 Either<List<HeatParameterDefinition>, ResultStatusEnum> heatParameters = ImportUtils
1792 .getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo.getArtifactType());
1793 if (heatParameters.isRight() && (heatParameters.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND)) {
1794 log.info("failed to parse heat parameters ");
1795 ResponseFormat responseFormat = componentsUtils
1796 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactType());
1797 return Either.right(responseFormat);
1798 } else if (heatParameters.isLeft() && heatParameters.left().value() != null) {
1799 artifactInfo.setListHeatParameters(heatParameters.left().value());
1802 return Either.left(true);
1806 void validateArtifactExtension(final ArtifactConfiguration artifactConfiguration, final ArtifactDefinition artifactDefinition) {
1807 final List<String> acceptedTypes = artifactConfiguration.getAcceptedTypes();
1809 * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted.
1811 if (CollectionUtils.isEmpty(acceptedTypes)) {
1814 final String artifactName = artifactDefinition.getArtifactName();
1815 final String fileExtension = FilenameUtils.getExtension(artifactName);
1816 if (fileExtension == null || !acceptedTypes.contains(fileExtension.toLowerCase())) {
1817 final String artifactType = artifactDefinition.getArtifactType();
1818 log.debug("File extension \"{}\" is not allowed for artifact type \"{}\"", fileExtension, artifactType);
1819 throw new ByActionStatusComponentException(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, artifactType);
1824 void validateHeatEnvDeploymentArtifact(final Component parentComponent, final String parentId, final ArtifactDefinition artifactInfo) {
1825 final Wrapper<ArtifactDefinition> heatMDWrapper = new Wrapper<>();
1826 final Wrapper<byte[]> payloadWrapper = new Wrapper<>();
1827 validateYaml(artifactInfo);
1828 validateHeatExist(parentComponent.getUniqueId(), parentId, heatMDWrapper, artifactInfo, parentComponent.getComponentType());
1829 if (!heatMDWrapper.isEmpty()) {
1830 fillArtifactPayload(payloadWrapper, heatMDWrapper.getInnerElement());
1832 if (!heatMDWrapper.isEmpty()) {
1833 validateEnvVsHeat(artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement());
1837 public void fillArtifactPayload(Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactDefinition) {
1838 if (ArrayUtils.isEmpty(artifactDefinition.getPayloadData())) {
1839 Either<DAOArtifactData, CassandraOperationStatus> eitherArtifactData = artifactCassandraDao.getArtifact(artifactDefinition.getEsId());
1840 if (eitherArtifactData.isLeft()) {
1841 byte[] data = eitherArtifactData.left().value().getDataAsArray();
1842 payloadWrapper.setInnerElement(Base64.encodeBase64(data));
1844 log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName());
1845 throw new StorageException(DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()));
1848 payloadWrapper.setInnerElement(artifactDefinition.getPayloadData());
1852 private void validateEnvVsHeat(ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) {
1853 String envPayload = new String(Base64.decodeBase64(envArtifact.getPayloadData()));
1854 Map<String, Object> heatEnvToscaJson = (Map<String, Object>) new Yaml().load(envPayload);
1855 String heatDecodedPayload = new String(Base64.decodeBase64(heatPayloadData));
1856 Map<String, Object> heatToscaJson = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
1857 Either<Map<String, Object>, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils
1858 .findFirstToscaMapElement(heatEnvToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1859 if (eitherHeatEnvProperties.isRight()) {
1860 log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName());
1861 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat Env");
1863 Either<Map<String, Object>, ResultStatusEnum> eitherHeatProperties = ImportUtils
1864 .findFirstToscaMapElement(heatToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1865 if (eitherHeatProperties.isRight()) {
1866 log.debug("Invalid heat format for file:{}", heatArtifact.getArtifactName());
1867 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat");
1869 Set<String> heatPropertiesKeys = eitherHeatProperties.left().value().keySet();
1870 Set<String> heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet();
1871 heatEnvPropertiesKeys.removeAll(heatPropertiesKeys);
1872 if (!heatEnvPropertiesKeys.isEmpty()) {
1873 log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(),
1874 heatArtifact.getArtifactName());
1875 throw new ByActionStatusComponentException(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(),
1876 heatArtifact.getArtifactName());
1880 private void validateYaml(ArtifactDefinition artifactInfo) {
1881 YamlToObjectConverter yamlConverter = new YamlToObjectConverter();
1882 boolean isYamlValid = yamlConverter.isValidYamlEncoded64(artifactInfo.getPayloadData());
1884 log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName());
1885 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType());
1889 private void validateSingleDeploymentArtifactName(final String artifactName, final Component parentComponent) {
1890 boolean artifactNameFound = false;
1891 final Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, null).iterator();
1892 while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) {
1893 artifactNameFound = artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName());
1895 if (artifactNameFound) {
1896 final ComponentTypeEnum componentType = parentComponent.getComponentType();
1897 log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName);
1898 throw new ByActionStatusComponentException(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, componentType.getValue(),
1899 parentComponent.getName(), artifactName);
1903 private void validateHeatExist(String componentId, String parentRiId, Wrapper<ArtifactDefinition> heatArtifactMDWrapper,
1904 ArtifactDefinition heatEnvArtifact, ComponentTypeEnum componentType) {
1905 final Either<ArtifactDefinition, StorageOperationStatus> res = artifactToscaOperation
1906 .getHeatArtifactByHeatEnvId(parentRiId, heatEnvArtifact, componentId, componentType);
1907 if (res.isRight()) {
1908 throw new ByActionStatusComponentException(ActionStatus.MISSING_HEAT);
1910 heatArtifactMDWrapper.setInnerElement(res.left().value());
1914 void validateHeatTimeoutValue(final ArtifactDefinition artifactInfo) {
1915 log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel());
1916 // timeout > 0 for HEAT artifacts
1917 if (artifactInfo.getTimeout() == null || artifactInfo.getTimeout() < 1) {
1918 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
1920 // US649856 - Allow several HEAT files on Resource
1921 log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel());
1925 void validateResourceType(final ResourceTypeEnum resourceType, final ArtifactDefinition artifactInfo, final List<String> typeList) {
1926 if (CollectionUtils.isEmpty(typeList) || typeList.contains(resourceType.getValue())) {
1929 final String listToString = typeList.stream().collect(Collectors.joining(", "));
1930 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, artifactInfo.getArtifactGroupType().getType(),
1931 listToString, resourceType.getValue());
1935 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters(ArtifactDefinition artifactInfo, String artifactType) {
1936 if (artifactInfo.getHeatParameters() != null) {
1937 for (HeatParameterDefinition heatParam : artifactInfo.getListHeatParameters()) {
1938 String parameterType = heatParam.getType();
1939 HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType);
1940 String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType();
1941 if (heatParameterType == null) {
1942 ResponseFormat responseFormat = componentsUtils
1943 .getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam.getType());
1944 return Either.right(responseFormat);
1946 StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam);
1947 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
1948 log.debug("Heat parameter {} is invalid. Status is {}", heatParam.getName(), validateAndUpdateProperty);
1949 ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE;
1950 ResponseFormat responseFormat = componentsUtils
1951 .getResponseFormat(status, artifactTypeStr, heatParam.getType(), heatParam.getName());
1952 return Either.right(responseFormat);
1956 return Either.left(artifactInfo);
1959 public List<ArtifactDefinition> getDeploymentArtifacts(final Component component, final String ciId) {
1960 final ComponentTypeEnum componentType = component.getComponentType();
1961 if (component.getDeploymentArtifacts() == null) {
1962 return Collections.emptyList();
1964 final List<ArtifactDefinition> deploymentArtifacts = new ArrayList<>();
1965 if (ComponentTypeEnum.RESOURCE == componentType && ciId != null) {
1966 final Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(component, ciId, null, null, null);
1967 if (getRI.isRight()) {
1968 return Collections.emptyList();
1970 final ComponentInstance ri = getRI.left().value();
1971 if (ri.getDeploymentArtifacts() != null) {
1972 deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values());
1975 deploymentArtifacts.addAll(component.getDeploymentArtifacts().values());
1977 return deploymentArtifacts;
1980 private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) {
1981 // on create if null add informational to current
1982 if (artifactInfo.getArtifactGroupType() == null) {
1983 artifactInfo.setArtifactGroupType(type);
1985 if (artifactInfo.getUniqueId() != null) {
1986 log.error("artifact uniqid cannot be set ignoring");
1988 artifactInfo.setUniqueId(null);
1989 if (artifactInfo.getArtifactRef() != null) {
1990 log.error("artifact ref cannot be set ignoring");
1992 artifactInfo.setArtifactRef(null);
1993 if (artifactInfo.getArtifactRepository() != null) {
1994 log.error("artifact repository cannot be set ignoring");
1996 artifactInfo.setArtifactRepository(null);
1997 if (artifactInfo.getUserIdCreator() != null) {
1998 log.error("creator uuid cannot be set ignoring");
2000 artifactInfo.setArtifactCreator(user.getUserId());
2001 if (artifactInfo.getUserIdLastUpdater() != null) {
2002 log.error("userId of last updater cannot be set ignoring");
2004 artifactInfo.setUserIdLastUpdater(user.getUserId());
2005 if (artifactInfo.getCreatorFullName() != null) {
2006 log.error("creator Full name cannot be set ignoring");
2008 String fullName = user.getFirstName() + " " + user.getLastName();
2009 artifactInfo.setUpdaterFullName(fullName);
2010 if (artifactInfo.getUpdaterFullName() != null) {
2011 log.error("updater Full name cannot be set ignoring");
2013 artifactInfo.setUpdaterFullName(fullName);
2014 if (artifactInfo.getCreationDate() != null) {
2015 log.error("Creation Date cannot be set ignoring");
2017 long time = System.currentTimeMillis();
2018 artifactInfo.setCreationDate(time);
2019 if (artifactInfo.getLastUpdateDate() != null) {
2020 log.error("Last Update Date cannot be set ignoring");
2022 artifactInfo.setLastUpdateDate(time);
2023 if (artifactInfo.getEsId() != null) {
2024 log.error("es id cannot be set ignoring");
2026 artifactInfo.setEsId(null);
2029 private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName,
2030 String operationName) {
2031 String id = artifactId;
2032 if (artifactId == null || artifactId.isEmpty()) {
2033 String uniqueId = null;
2034 if (interfaceName != null && operationName != null) {
2035 uniqueId = UniqueIdBuilder
2036 .buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo.getArtifactLabel());
2038 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel());
2040 artifactInfo.setUniqueId(uniqueId);
2041 artifactInfo.setEsId(uniqueId);
2044 artifactInfo.setUniqueId(artifactId);
2045 artifactInfo.setEsId(artifactId);
2050 private Either<Boolean, ResponseFormat> validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2051 if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) {
2052 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD));
2054 return Either.left(true);
2058 Either<Boolean, ResponseFormat> validateAndSetArtifactName(ArtifactDefinition artifactInfo) {
2059 if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) {
2060 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2062 String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName());
2063 if (normalizeFileName == null || normalizeFileName.isEmpty()) {
2064 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2066 artifactInfo.setArtifactName(normalizeFileName);
2067 if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) {
2068 return Either.right(
2069 componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH)));
2071 return Either.left(true);
2074 private void validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2075 if (StringUtils.isEmpty(artifactInfo.getArtifactType())) {
2076 log.info("artifact type is missing operation ignored");
2077 throw new ByActionStatusComponentException(ActionStatus.MISSING_ARTIFACT_TYPE);
2079 if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) {
2080 log.info("artifact type cannot be changed operation ignored");
2081 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2085 private Either<ArtifactDefinition, ResponseFormat> validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo,
2086 ArtifactDefinition currentArtifact) {
2087 if (Objects.nonNull(artifactInfo) && Objects.nonNull(currentArtifact)) {
2088 if (artifactInfo.getArtifactGroupType() == null) {
2089 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2090 } else if (!currentArtifact.getArtifactGroupType().getType().equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) {
2091 log.info("artifact group type cannot be changed. operation failed");
2092 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2095 return Either.left(artifactInfo);
2098 private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact,
2099 ArtifactGroupTypeEnum type) {
2100 // on update if null add informational to current
2101 if (currentArtifact.getArtifactGroupType() == null && type != null) {
2102 currentArtifact.setArtifactGroupType(type);
2104 if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) {
2105 log.error("artifact uniqid cannot be set ignoring");
2107 artifactInfo.setUniqueId(currentArtifact.getUniqueId());
2108 if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef().equals(artifactInfo.getArtifactRef())) {
2109 log.error("artifact ref cannot be set ignoring");
2111 artifactInfo.setArtifactRef(currentArtifact.getArtifactRef());
2112 if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository().equals(artifactInfo.getArtifactRepository())) {
2113 log.error("artifact repository cannot be set ignoring");
2115 artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository());
2116 if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator().equals(artifactInfo.getUserIdCreator())) {
2117 log.error("creator uuid cannot be set ignoring");
2119 artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator());
2120 if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator().equals(artifactInfo.getArtifactCreator())) {
2121 log.error("artifact creator cannot be set ignoring");
2123 artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator());
2124 if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater().equals(artifactInfo.getUserIdLastUpdater())) {
2125 log.error("userId of last updater cannot be set ignoring");
2127 artifactInfo.setUserIdLastUpdater(user.getUserId());
2128 if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName().equals(artifactInfo.getCreatorFullName())) {
2129 log.error("creator Full name cannot be set ignoring");
2131 artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName());
2132 if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName().equals(artifactInfo.getUpdaterFullName())) {
2133 log.error("updater Full name cannot be set ignoring");
2135 String fullName = user.getFirstName() + " " + user.getLastName();
2136 artifactInfo.setUpdaterFullName(fullName);
2137 if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate().equals(artifactInfo.getCreationDate())) {
2138 log.error("Creation Date cannot be set ignoring");
2140 artifactInfo.setCreationDate(currentArtifact.getCreationDate());
2141 if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate().equals(artifactInfo.getLastUpdateDate())) {
2142 log.error("Last Update Date cannot be set ignoring");
2144 long time = System.currentTimeMillis();
2145 artifactInfo.setLastUpdateDate(time);
2146 if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) {
2147 log.error("es id cannot be set ignoring");
2149 artifactInfo.setEsId(currentArtifact.getUniqueId());
2150 if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName()
2151 .equals(artifactInfo.getArtifactDisplayName())) {
2152 log.error(" Artifact Display Name cannot be set ignoring");
2154 artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName());
2155 if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi().equals(artifactInfo.getServiceApi())) {
2156 log.debug("serviceApi cannot be set. ignoring.");
2158 artifactInfo.setServiceApi(currentArtifact.getServiceApi());
2159 if (artifactInfo.getArtifactGroupType() != null && currentArtifact.getArtifactGroupType() != artifactInfo.getArtifactGroupType()) {
2160 log.debug("artifact group cannot be set. ignoring.");
2162 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2163 artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion());
2164 if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID().isEmpty() && !currentArtifact.getArtifactUUID()
2165 .equals(artifactInfo.getArtifactUUID())) {
2166 log.debug("artifact UUID cannot be set. ignoring.");
2168 artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID());
2169 if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo.getHeatParameters().isEmpty()
2170 && !currentArtifact.getHeatParameters().isEmpty()) {
2171 checkAndSetUnupdatableHeatParams(artifactInfo.getListHeatParameters(), currentArtifact.getListHeatParameters());
2175 private void checkAndSetUnupdatableHeatParams(List<HeatParameterDefinition> heatParameters, List<HeatParameterDefinition> currentParameters) {
2176 Map<String, HeatParameterDefinition> currentParametersMap = getMapOfParameters(currentParameters);
2177 for (HeatParameterDefinition parameter : heatParameters) {
2178 HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId());
2179 if (currentParam != null) {
2180 if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) {
2181 log.debug("heat parameter name cannot be updated ({}). ignoring.", parameter.getName());
2182 parameter.setName(currentParam.getName());
2184 if (parameter.getDefaultValue() != null && !parameter.getDefaultValue().equalsIgnoreCase(currentParam.getDefaultValue())) {
2185 log.debug("heat parameter defaultValue cannot be updated ({}). ignoring.", parameter.getDefaultValue());
2186 parameter.setDefaultValue(currentParam.getDefaultValue());
2188 if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) {
2189 log.debug("heat parameter type cannot be updated ({}). ignoring.", parameter.getType());
2190 parameter.setType(currentParam.getType());
2192 if (parameter.getDescription() != null && !parameter.getDescription().equalsIgnoreCase(currentParam.getDescription())) {
2193 log.debug("heat parameter description cannot be updated ({}). ignoring.", parameter.getDescription());
2194 parameter.setDescription(currentParam.getDescription());
2196 // check and set current value
2197 if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) {
2198 log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue());
2199 parameter.setCurrentValue(currentParam.getDefaultValue());
2205 private Map<String, HeatParameterDefinition> getMapOfParameters(List<HeatParameterDefinition> currentParameters) {
2206 Map<String, HeatParameterDefinition> currentParamsMap = new HashMap<>();
2207 for (HeatParameterDefinition param : currentParameters) {
2208 currentParamsMap.put(param.getUniqueId(), param);
2210 return currentParamsMap;
2213 private Either<Boolean, ResponseFormat> validateAndServiceApiUrl(ArtifactDefinition artifactInfo) {
2214 if (!ValidationUtils.validateStringNotEmpty(artifactInfo.getApiUrl())) {
2215 log.debug("Artifact url cannot be empty.");
2216 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL));
2218 artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase());
2219 if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) {
2220 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL));
2222 if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) {
2224 .right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH)));
2226 return Either.left(true);
2229 private Either<Boolean, ResponseFormat> validateAndCleanDescription(ArtifactDefinition artifactInfo) {
2230 if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) {
2231 log.debug("Artifact description cannot be empty.");
2232 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION));
2234 String description = artifactInfo.getDescription();
2235 description = ValidationUtils.removeNoneUtf8Chars(description);
2236 description = ValidationUtils.normaliseWhitespace(description);
2237 description = ValidationUtils.stripOctets(description);
2238 description = ValidationUtils.removeHtmlTagsOnly(description);
2239 if (!ValidationUtils.validateIsEnglish(description)) {
2240 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2242 if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) {
2243 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION,
2244 String.valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)));
2246 artifactInfo.setDescription(description);
2247 return Either.left(true);
2250 private <T> Either<ArtifactDefinition, T> updateArtifactFlow(Component parent, String parentId, String artifactId,
2251 ArtifactDefinition artifactInfo, byte[] decodedPayload,
2252 ComponentTypeEnum componentType, AuditingActionEnum auditingAction) {
2253 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
2254 if (artifactData == null) {
2255 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2256 log.debug("Failed to create artifact object for ES.");
2257 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
2259 log.debug("Entry on graph is updated. Update artifact in ES");
2260 // Changing previous and current artifactId for auditing
2261 String currArtifactId = artifactInfo.getUniqueId();
2262 NodeTypeEnum parentType = convertParentType(componentType);
2263 if (decodedPayload == null) {
2264 if (!artifactInfo.getMandatory() || artifactInfo.getEsId() != null) {
2265 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactInfo.getEsId());
2266 if (artifactFromCassandra.isRight()) {
2267 throw new StorageException(artifactFromCassandra.right().value());
2269 // clone data to new artifact
2270 artifactData.setData(artifactFromCassandra.left().value().getData());
2271 artifactData.setId(artifactFromCassandra.left().value().getId());
2273 } else if (artifactInfo.getEsId() == null) {
2274 artifactInfo.setEsId(artifactInfo.getUniqueId());
2275 artifactData.setId(artifactInfo.getUniqueId());
2277 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
2278 .updateArtifactOnResource(artifactInfo, parent, artifactId, parentType, parentId, true);
2279 if (result.isRight()) {
2280 throw new StorageException(result.right().value());
2282 ArtifactDefinition artifactDefinition = result.left().value();
2283 updateGeneratedIdInHeatEnv(parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType);
2284 StorageOperationStatus storageOperationStatus = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
2285 if (storageOperationStatus != StorageOperationStatus.OK) {
2286 throw new StorageException(storageOperationStatus);
2288 if (artifactData.getData() != null) {
2289 if (!artifactDefinition.getDuplicated() || artifactData.getId() == null) {
2290 artifactData.setId(artifactDefinition.getEsId());
2292 saveArtifactInCassandra(artifactData, parent, artifactInfo, currArtifactId, artifactId, auditingAction, componentType);
2294 return Either.left(artifactDefinition);
2297 private String updateGeneratedIdInHeatEnv(Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo,
2298 ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2299 if (NodeTypeEnum.Resource == parentType) {
2300 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parent, parentId, artifactId, artifactInfo, artifactDefinition,
2303 return artifactDefinition.getUniqueId();
2306 private String updateGeneratedIdInHeatEnv(Map<String, ArtifactDefinition> deploymentArtifacts, Component parentComponent, String parentId,
2307 String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2308 NodeTypeEnum parentType, boolean isInstanceArtifact) {
2309 String artifactUniqueId;
2310 artifactUniqueId = artifactDefinition.getUniqueId();
2311 String artifactType = artifactInfo.getArtifactType();
2312 if ((ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType)
2313 || ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType)) && !artifactUniqueId.equals(artifactId)) {
2314 // need to update the generated id in heat env
2315 Optional<Entry<String, ArtifactDefinition>> findFirst = deploymentArtifacts.entrySet().stream()
2316 .filter(a -> artifactId.equals(a.getValue().getGeneratedFromId())).findFirst();
2317 if (findFirst.isPresent()) {
2318 ArtifactDefinition artifactEnvInfo = findFirst.get().getValue();
2319 artifactEnvInfo.setIsFromCsar(artifactDefinition.getIsFromCsar());
2320 artifactEnvInfo.setArtifactChecksum(null);
2321 if (isInstanceArtifact) {
2322 artifactToscaOperation
2323 .updateHeatEnvArtifactOnInstance(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2325 artifactToscaOperation
2326 .updateHeatEnvArtifact(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2330 return artifactUniqueId;
2333 private String updateGeneratedIdInHeatEnvOnInstance(ComponentInstance parent, Component parentComponent, String artifactId,
2334 ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2335 NodeTypeEnum parentType) {
2336 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parentComponent, parent.getUniqueId(), artifactId, artifactInfo,
2337 artifactDefinition, parentType, true);
2341 private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) {
2342 log.trace("Starting payload handling");
2343 byte[] payload = artifactInfo.getPayloadData();
2344 byte[] decodedPayload = null;
2345 if (payload != null && payload.length != 0) {
2346 // the generated artifacts were already decoded by the handler
2347 decodedPayload = artifactInfo.getGenerated() ? payload : Base64.decodeBase64(payload);
2348 if (decodedPayload.length == 0) {
2349 log.debug("Failed to decode the payload.");
2350 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
2351 return Either.right(responseFormat);
2353 String checkSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(decodedPayload);
2354 artifactInfo.setArtifactChecksum(checkSum);
2355 log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum);
2356 // Specific payload validations of different types
2357 Either<Boolean, ResponseFormat> result = Either.left(true);
2358 if (isDeploymentArtifact(artifactInfo)) {
2359 log.trace("Starting deployment artifacts payload validation");
2360 String artifactType = artifactInfo.getArtifactType();
2361 String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName());
2362 PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension);
2363 final Optional<ResponseFormat> pmDictionaryError = validateIfPmDictionary(artifactType, decodedPayload);
2364 if (pmDictionaryError.isPresent()) {
2365 return Either.right(pmDictionaryError.get());
2367 Either<Boolean, ActionStatus> isPayloadValid = payloadType.isValid(decodedPayload);
2368 if (isPayloadValid.isRight()) {
2369 ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType);
2370 return Either.right(responseFormat);
2372 if (payloadType.isHeatRelated()) {
2373 log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType);
2374 result = extractHeatParameters(artifactInfo);
2377 if (result.isRight()) {
2378 return Either.right(result.right().value());
2380 } // null/empty payload is normal if called from metadata update ONLY.
2382 // The validation of whether this is metadata/payload update case is
2384 // currently done separately
2386 if (!isArtifactMetadataUpdate) {
2387 log.debug("In artifact: {} Payload is missing.", artifactInfo.getArtifactName());
2388 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
2389 return Either.right(responseFormat);
2392 log.trace("Ended payload handling");
2393 return Either.left(decodedPayload);
2396 private Optional<ResponseFormat> validateIfPmDictionary(String artifactType, byte[] decodedPayload) {
2397 return new PMDictionaryValidator().validateIfPmDictionary(artifactType, decodedPayload).map(this::preparePmDictionaryResponse);
2400 private ResponseFormat preparePmDictionaryResponse(String errorMessage) {
2401 return componentsUtils.getResponseFormat(ActionStatus.INVALID_PM_DICTIONARY_FILE, errorMessage);
2404 public Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface(String resourceId, String userUserId, String artifactId,
2405 boolean inTransaction) {
2406 return toscaOperationFacade.getToscaElement(resourceId, JsonParseFlagEnum.ParseMetadata).right().map(componentsUtils.toResponseFormat())
2407 .left().bind(parentComponent -> {
2408 User user = new User(userUserId);
2409 return handleDelete(resourceId, artifactId, user, parentComponent, false, inTransaction);
2413 private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) {
2414 Operation op = new Operation();
2415 long time = System.currentTimeMillis();
2416 op.setCreationDate(time);
2417 String artifactName = artifactInfo.getArtifactName();
2418 artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName));
2419 op.setImplementation(artifactInfo);
2420 op.setLastUpdateDate(time);
2424 private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) {
2425 String newArtifactName = operationName + "_" + artifactName;
2426 log.trace("converting artifact name {} to {}", artifactName, newArtifactName);
2427 return newArtifactName;
2431 public byte[] downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion,
2432 String artifactName) {
2433 // General validation
2434 if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) {
2435 log.debug(NULL_PARAMETER);
2436 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2438 // Normalizing artifact name
2439 artifactName = ValidationUtils.normalizeFileName(artifactName);
2440 // Resource validation
2441 Resource resource = validateResourceNameAndVersion(resourceName, resourceVersion);
2442 String resourceId = resource.getUniqueId();
2443 // Service validation
2444 Service validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion);
2445 Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts();
2446 if (artifacts == null || artifacts.isEmpty()) {
2447 log.debug("Deployment artifacts of resource {} are not found", resourceId);
2448 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2450 ArtifactDefinition deploymentArtifact = null;
2451 for (ArtifactDefinition artifactDefinition : artifacts.values()) {
2452 if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName().equals(artifactName)) {
2453 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2454 deploymentArtifact = artifactDefinition;
2458 if (deploymentArtifact == null) {
2459 log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId);
2460 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2462 // Downloading the artifact
2463 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deploymentArtifact);
2464 log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId());
2465 return downloadArtifactEither.getRight();
2469 public byte[] downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) {
2470 // General validation
2471 if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) {
2472 log.debug(NULL_PARAMETER);
2473 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2475 // Normalizing artifact name
2476 artifactName = ValidationUtils.normalizeFileName(artifactName);
2477 // Service validation
2478 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2479 // ResourceInstance validation
2480 ComponentInstance resourceInstance = validateResourceInstance(service, resourceInstanceName);
2481 Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
2482 final String finalArtifactName = artifactName;
2483 Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName);
2484 ArtifactDefinition deployableArtifact =
2485 artifacts == null ? null : artifacts.values().stream().filter(filterArtifactByName).findFirst().orElse(null);
2486 if (deployableArtifact == null) {
2487 log.debug("Deployment artifact with name {} not found", artifactName);
2488 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
2490 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2491 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deployableArtifact);
2492 log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId());
2493 return downloadArtifactEither.getRight();
2496 private ComponentInstance validateResourceInstance(Service service, String resourceInstanceName) {
2497 List<ComponentInstance> riList = service.getComponentInstances();
2498 for (ComponentInstance ri : riList) {
2499 if (ri.getNormalizedName().equals(resourceInstanceName)) {
2503 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName);
2506 private ComponentInstance validateResourceInstanceById(Component component, String resourceInstanceId) {
2507 List<ComponentInstance> riList = component.getComponentInstances();
2508 for (ComponentInstance ri : riList) {
2509 if (ri.getUniqueId().equals(resourceInstanceId)) {
2513 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceInstanceId);
2516 private Service validateServiceNameAndVersion(String serviceName, String serviceVersion) {
2517 Either<List<Service>, StorageOperationStatus> serviceListBySystemName = toscaOperationFacade
2518 .getBySystemName(ComponentTypeEnum.SERVICE, serviceName);
2519 if (serviceListBySystemName.isRight()) {
2520 log.debug("Couldn't fetch any service with name {}", serviceName);
2521 throw new ByActionStatusComponentException(
2522 componentsUtils.convertFromStorageResponse(serviceListBySystemName.right().value(), ComponentTypeEnum.SERVICE), serviceName);
2524 List<Service> serviceList = serviceListBySystemName.left().value();
2525 if (serviceList == null || serviceList.isEmpty()) {
2526 log.debug("Couldn't fetch any service with name {}", serviceName);
2527 throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceName);
2529 Service foundService = null;
2530 for (Service service : serviceList) {
2531 if (service.getVersion().equals(serviceVersion)) {
2532 log.trace("Found service with version {}", serviceVersion);
2533 foundService = service;
2537 if (foundService == null) {
2538 log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName);
2539 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE.getValue(),
2542 return foundService;
2545 private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2546 Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade
2547 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2548 if (resourceListBySystemName.isRight()) {
2549 log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2550 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()),
2553 return resourceListBySystemName.left().value();
2556 public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2558 log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion,
2560 if (serviceName == null || serviceVersion == null || artifactName == null) {
2561 log.debug(NULL_PARAMETER);
2562 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2564 // Normalizing artifact name
2565 final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2566 // Service validation
2567 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2568 // Looking for deployment or tosca artifacts
2569 String serviceId = service.getUniqueId();
2570 if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2571 log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2572 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2574 Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2575 if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2576 foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2577 // filters artifact by name
2578 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2580 if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2581 foundArtifactOptl = service.getToscaArtifacts().values().stream()
2582 // filters TOSCA artifact by name
2583 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2585 if (!foundArtifactOptl.isPresent()) {
2586 log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2587 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2589 log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2590 // Downloading the artifact
2591 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl.get());
2592 log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2593 return downloadArtifactEither.getRight();
2596 public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2597 log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2598 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2599 if (artifactById.isRight()) {
2600 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2601 log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2602 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2604 ArtifactDefinition artifactDefinition = artifactById.left().value();
2605 if (artifactDefinition == null) {
2606 log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2607 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2609 return downloadArtifact(artifactDefinition);
2612 private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId,
2613 ComponentTypeEnum componentType, String containerComponentType) {
2614 ComponentTypeEnum componentForAudit =
2615 null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
2616 componentForAudit.getNodeType();
2617 Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaFullElement(componentId);
2618 if (componentResult.isRight()) {
2619 ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND
2620 : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
2621 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
2622 log.debug("Service not found, serviceId {}", componentId);
2623 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
2624 throw new ByActionStatusComponentException(status, componentId);
2626 return componentResult.left().value();
2629 private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId,
2630 ArtifactOperationInfo operation) {
2631 if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
2633 validateCanWorkOnComponent(component, userId);
2634 } catch (ComponentException e) {
2635 String uniqueId = component.getUniqueId();
2636 log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId);
2637 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(), component.getComponentType(),
2644 private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId,
2645 ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
2646 if (operation.isNotDownload()) {
2647 String role = user.getRole();
2648 if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
2649 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2650 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
2651 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2652 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
2657 private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId,
2658 ComponentTypeEnum componentType, boolean inTransaction) {
2661 user = validateUserExists(userId);
2662 } catch (ByResponseFormatComponentException e) {
2663 ResponseFormat responseFormat = e.getResponseFormat();
2664 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2666 } catch (ByActionStatusComponentException e) {
2667 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2668 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2674 private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId, ResponseFormat responseFormat,
2675 ComponentTypeEnum componentType, String userId) {
2676 User user = new User();
2677 user.setUserId(userId);
2678 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2681 protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
2682 AuditingActionEnum auditingAction = null;
2683 switch (operation.getArtifactOperationEnum()) {
2685 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
2688 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API
2689 : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
2692 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
2695 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
2700 return auditingAction;
2703 private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
2704 String esArtifactId = artifactDefinition.getEsId();
2705 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2706 if (artifactfromES.isRight()) {
2707 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2708 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2709 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
2710 log.debug("Error when getting artifact from ES, error: {}", actionStatus);
2711 throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
2713 DAOArtifactData DAOArtifactData = artifactfromES.left().value();
2714 byte[] data = DAOArtifactData.getDataAsArray();
2716 log.debug("Artifact data from cassandra is null");
2717 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
2719 String artifactName = artifactDefinition.getArtifactName();
2720 log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
2721 return new ImmutablePair<>(artifactName, data);
2724 public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
2725 return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
2728 private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo, String currArtifactId,
2729 String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
2730 CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
2731 if (resourceUploadStatus == CassandraOperationStatus.OK) {
2732 log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
2733 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
2734 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2735 componentType, null);
2737 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2738 log.info(FAILED_SAVE_ARTIFACT);
2739 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2740 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2741 componentType, null);
2742 throw new StorageException(resourceUploadStatus);
2746 private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
2747 return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
2750 private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
2751 return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
2754 private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
2755 return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
2758 private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
2759 final String artifactType = artifactInfo.getArtifactType();
2760 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
2761 if (artifactTypeEnum == null) {
2762 artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
2765 switch (artifactTypeEnum) {
2776 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap,
2777 String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
2778 User user = userBusinessLogic.getUser(userUserId, inTransaction);
2779 return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
2782 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
2783 ArtifactGroupTypeEnum groupType) {
2784 ArtifactDefinition artifactInfo = new ArtifactDefinition();
2785 String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
2786 String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
2787 String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
2788 artifactInfo.setArtifactDisplayName(artifactName);
2789 artifactInfo.setArtifactLabel(logicalName.toLowerCase());
2790 artifactInfo.setArtifactType(artifactType);
2791 artifactInfo.setDescription(artifactDescription);
2792 artifactInfo.setArtifactGroupType(groupType);
2793 nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
2794 setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
2795 return artifactInfo;
2798 private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
2799 String uniqueId = null;
2800 if (resourceId != null) {
2801 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
2802 artifactInfo.setUniqueId(uniqueId);
2804 artifactInfo.setUserIdCreator(user.getUserId());
2805 String fullName = user.getFullName();
2806 artifactInfo.setUpdaterFullName(fullName);
2807 long time = System.currentTimeMillis();
2808 artifactInfo.setCreatorFullName(fullName);
2809 artifactInfo.setCreationDate(time);
2810 artifactInfo.setLastUpdateDate(time);
2811 artifactInfo.setUserIdLastUpdater(user.getUserId());
2812 artifactInfo.setMandatory(true);
2815 public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType,
2816 ArtifactGroupTypeEnum groupType, String instanceId) {
2817 return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
2820 public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact,
2821 Component component, NodeTypeEnum parentType, String instanceId) {
2822 return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
2825 private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
2826 byte[] payload = payloadStr.getBytes();
2827 DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
2828 return Either.left(artifactData);
2832 * @param artifactDefinition
2835 public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType,
2836 Component component, String resourceInstanceName, User modifier,
2837 String instanceId, boolean shouldLock, boolean inTransaction) {
2838 String payload = generateHeatEnvPayload(artifactDefinition);
2839 String prevUUID = artifactDefinition.getArtifactUUID();
2840 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2841 return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2842 shouldLock, inTransaction).left()
2843 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2846 public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition,
2847 ComponentTypeEnum componentType, Component component,
2848 String resourceInstanceName, User modifier, boolean shouldLock,
2849 boolean inTransaction, String instanceId) {
2850 String payload = generateHeatEnvPayload(artifactDefinition);
2851 String prevUUID = artifactDefinition.getArtifactUUID();
2852 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2853 return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2854 shouldLock, inTransaction).left()
2855 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2859 Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID,
2860 ArtifactDefinition clonedBeforeGenerate,
2861 ArtifactDefinition updatedArtDef) {
2862 if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
2863 List<ComponentInstance> componentInstances = component.getComponentInstances();
2864 if (componentInstances != null) {
2865 Optional<ComponentInstance> findFirst = componentInstances.stream().filter(ci -> ci.getUniqueId().equals(instanceId)).findFirst();
2866 if (findFirst.isPresent()) {
2867 ComponentInstance relevantInst = findFirst.get();
2868 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate,
2869 relevantInst.getGroupInstances());
2870 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
2871 updatedGroupInstances.forEach(gi -> {
2872 gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
2873 gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
2875 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
2876 .updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
2877 if (status.isRight()) {
2878 log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
2879 ResponseFormat responseFormat = componentsUtils
2880 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(status.right().value()),
2881 clonedBeforeGenerate.getArtifactDisplayName());
2882 return Either.right(responseFormat);
2888 return Either.left(updatedArtDef);
2891 private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
2892 List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
2893 StringBuilder sb = new StringBuilder();
2894 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
2895 sb.append("parameters:\n");
2896 if (heatParameters != null) {
2897 heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2898 List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
2899 for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
2900 String heatValue = heatParameterDefinition.getCurrentValue();
2901 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2902 heatValue = heatParameterDefinition.getDefaultValue();
2903 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2904 empltyHeatValues.add(heatParameterDefinition);
2908 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
2912 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatValue))
2916 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ")
2917 .append(new BigDecimal(heatValue).toPlainString()).append("\n");
2919 case COMMA_DELIMITED_LIST:
2921 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatValue).append("\n");
2924 String value = heatValue;
2925 boolean starts = value.startsWith("\"");
2926 boolean ends = value.endsWith("\"");
2927 if (!(starts && ends)) {
2928 starts = value.startsWith("'");
2929 ends = value.endsWith("'");
2930 if (!(starts && ends)) {
2931 value = "\"" + value + "\"";
2934 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value);
2940 if (!empltyHeatValues.isEmpty()) {
2941 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2942 empltyHeatValues.forEach(hv -> {
2943 sb.append(" ").append(hv.getName()).append(":");
2944 HeatParameterType type = HeatParameterType.isValidType(hv.getType());
2945 if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv.getCurrentValue())
2946 || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
2947 sb.append(" \"\"").append("\n");
2949 sb.append(" ").append("\n");
2954 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
2956 return sb.toString().replace("\\\\n", "\n");
2960 * @param artifactDefinition
2964 public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2965 ComponentTypeEnum componentType, Component component,
2966 String resourceInstanceName, User modifier, String instanceId,
2967 boolean shouldLock, boolean inTransaction) {
2968 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2969 artifactDefinition::getHeatParamsUpdateDate, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2972 public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2973 ComponentTypeEnum componentType, Component component,
2974 String resourceInstanceName, User modifier,
2975 String instanceId, boolean shouldLock,
2976 boolean inTransaction) {
2977 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2978 System::currentTimeMillis, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2981 protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition,
2982 ComponentTypeEnum componentType, Component component,
2983 String resourceInstanceName, User modifier, boolean shouldLock,
2984 boolean inTransaction, Supplier<Long> payloadUpdateDateGen,
2985 Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator,
2986 String instanceId) {
2987 log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2988 if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0
2989 || artifactDefinition.getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
2990 log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2991 Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
2992 DAOArtifactData artifactData = null;
2993 if (artifactDataRes.isLeft()) {
2994 artifactData = artifactDataRes.left().value();
2996 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2997 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
2998 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
2999 resourceInstanceName);
3000 return Either.right(artifactDataRes.right().value());
3002 String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
3004 String esArtifactId = artifactDefinition.getEsId();
3005 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
3006 DAOArtifactData DAOArtifactData;
3007 if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
3008 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
3009 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3010 if (artifactfromES.isRight()) {
3011 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3012 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3013 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3014 log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
3015 return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
3017 DAOArtifactData = artifactfromES.left().value();
3018 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3020 oldCheckSum = artifactDefinition.getArtifactChecksum();
3022 Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3025 lockComponent(component, "Update Artifact - lock resource: ");
3026 } catch (ComponentException e) {
3027 handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null,
3028 artifactDefinition.getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3033 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3034 artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3035 updateArifactDefinitionStatus = artifactToscaOperation
3036 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3038 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3039 artifactDefinition.getEsId());
3040 if (updateArifactDefinitionStatus.isRight()) {
3041 ResponseFormat responseFormat = componentsUtils
3042 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3043 artifactDefinition.getArtifactDisplayName());
3044 log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3045 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3046 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3047 resourceInstanceName);
3048 return Either.right(responseFormat);
3051 artifactDefinition.getArtifactChecksum();
3052 artifactDefinition.setArtifactChecksum(newCheckSum);
3053 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3054 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3055 artifactDefinition.getEsId());
3056 updateArifactDefinitionStatus = artifactToscaOperation
3057 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3059 log.trace("Update Payload {}", artifactDefinition.getEsId());
3061 if (updateArifactDefinitionStatus.isLeft()) {
3062 artifactDefinition = updateArifactDefinitionStatus.left().value();
3063 artifactData.setId(artifactDefinition.getUniqueId());
3064 CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3065 if (saveArtifactStatus == CassandraOperationStatus.OK) {
3066 if (!inTransaction) {
3067 janusGraphDao.commit();
3069 log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3070 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3071 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3072 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3073 resourceInstanceName);
3075 if (!inTransaction) {
3076 janusGraphDao.rollback();
3078 log.info("Failed to save artifact {}.", artifactData.getId());
3079 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3080 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3081 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3082 resourceInstanceName);
3083 return Either.right(responseFormat);
3086 ResponseFormat responseFormat = componentsUtils
3087 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3088 artifactDefinition.getArtifactDisplayName());
3089 log.debug("Failed To update artifact {}", artifactData.getId());
3090 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3091 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3092 resourceInstanceName);
3093 return Either.right(responseFormat);
3097 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
3101 return Either.left(artifactDefinition);
3104 public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType,
3105 List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3107 .buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType,
3108 artifactDef.getArtifactLabel(), artifactDef.getArtifactDisplayName(), artifactDef.getDescription(), artifactDef.getPayloadData(),
3109 updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3112 public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType,
3113 ArtifactGroupTypeEnum artifactGroupType, String label, String displayName,
3114 String description, byte[] artifactContent,
3115 List<ArtifactTemplateInfo> updatedRequiredArtifacts,
3116 List<HeatParameterDefinition> heatParameters) {
3117 Map<String, Object> json = new HashMap<>();
3118 if (artifactId != null && !artifactId.isEmpty()) {
3119 json.put(Constants.ARTIFACT_ID, artifactId);
3121 json.put(Constants.ARTIFACT_NAME, artifactName);
3122 json.put(Constants.ARTIFACT_TYPE, artifactType);
3123 json.put(Constants.ARTIFACT_DESCRIPTION, description);
3124 if (artifactContent != null) {
3125 log.debug("payload is encoded. perform decode");
3126 String encodedPayload = Base64.encodeBase64String(artifactContent);
3127 json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3129 json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3130 json.put(Constants.ARTIFACT_LABEL, label);
3131 json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3132 json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3133 : updatedRequiredArtifacts.stream().filter(
3134 e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3135 .map(ArtifactTemplateInfo::getFileName).collect(Collectors.toList()));
3136 json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>() : heatParameters);
3140 public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user,
3141 Map<String, Object> json, ArtifactOperationInfo operation,
3142 ArtifactDefinition artifactInfo) {
3143 String jsonStr = gson.toJson(json);
3144 ArtifactDefinition artifactDefinitionFromJson =
3145 artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3146 String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3147 Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE,
3148 operation, artifactUniqueId, artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3149 return Either.left(uploadArtifactToService.left().value());
3152 private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo,
3153 AuditingActionEnum auditingAction, String artifactId, User user,
3154 ComponentTypeEnum componentType, Component parent, String originData,
3155 String origMd5, ArtifactOperationInfo operation) {
3156 if (origMd5 != null) {
3157 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3158 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3159 validateDeploymentArtifact(artifactInfo, parent);
3160 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3161 } else { // duplicate
3162 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3165 return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3168 private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId,
3169 ArtifactDefinition artifactInfo, User user,
3170 AuditingActionEnum auditingAction, Component parent,
3171 ComponentTypeEnum componentType, String origMd5) {
3172 Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3173 if (getRI.isRight()) {
3174 throw new ByResponseFormatComponentException(getRI.right().value());
3176 ComponentInstance ri = getRI.left().value();
3177 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3178 if (getArtifactRes.isRight()) {
3179 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3181 ArtifactDefinition currArtifact = getArtifactRes.left().value();
3182 if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType()
3183 .equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3184 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3186 List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3187 List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3189 if (origMd5 != null) {
3190 Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction,
3191 parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams,
3192 currArtifact.getArtifactName());
3193 if (uploadParamsValidationResult.isRight()) {
3194 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3196 artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3198 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo,
3199 ArtifactTypeEnum.HEAT_ENV.getType());
3200 if (validateAndConvertHeatParamers.isRight()) {
3201 throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3203 if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3204 // fill reduced heat env parameters List for updating
3205 boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3206 if (updateRequired) {
3207 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3208 currArtifact.setListHeatParameters(currentHeatEnvParams);
3209 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3210 .updateArtifactOnResource(currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3211 if (updateArtifactRes.isRight()) {
3212 log.debug("Failed to update artifact on graph - {}", artifactId);
3213 throw new StorageException(updateArtifactRes.right().value());
3215 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(),
3216 parent.getUniqueId());
3217 if (error != StorageOperationStatus.OK) {
3218 throw new StorageException(error);
3222 updateHeatMetaDataIfNeeded(componentId, user, auditingAction, componentType, parent, ri, artifactInfo);
3223 StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3224 if (error != StorageOperationStatus.OK) {
3225 throw new StorageException(error);
3227 return Either.left(currArtifact);
3230 private void updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType,
3231 Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3232 String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3233 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId,
3234 auditingAction, user);
3235 if (getArtifactRes.isRight()) {
3236 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3238 ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3239 if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3240 validateHeatMetaData(updatedHeatEnvArtifact);
3241 updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3242 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3243 .updateArtifactOnResource(heatArtifactToUpdate, parent, heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId,
3245 if (updateArtifactRes.isRight()) {
3246 log.debug("Failed to update artifact on graph - {}", heatArtifactId);
3247 throw new StorageException(updateArtifactRes.right().value());
3249 ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3250 updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition,
3251 componentType.getNodeType());
3252 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(),
3253 parent.getUniqueId());
3254 if (error != StorageOperationStatus.OK) {
3255 throw new StorageException(error);
3260 private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3261 Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3262 Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3263 Integer updateTimeout = updatedHeatEnv.getTimeout();
3264 if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3265 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3269 private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3270 // currently only timeout metadata can be updated
3271 return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3274 private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3275 // currently only timeout metadata can be updated
3276 origHeat.setTimeout(updatedHeatEnv.getTimeout());
3279 private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams,
3280 List<HeatParameterDefinition> updatedHeatEnvParams) {
3281 boolean isUpdate = false;
3282 List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3283 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3284 String paramName = heatEnvParam.getName();
3285 validateParamName(paramName, currentParamsNames);
3286 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3287 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3288 String updatedParamValue = heatEnvParam.getCurrentValue();
3289 if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3290 currHeatParam.setCurrentValue(updatedParamValue);
3299 private void validateParamName(String paramName, List<String> heatParamsNames) {
3300 if (!heatParamsNames.contains(paramName)) {
3301 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3305 private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo,
3306 AuditingActionEnum auditingAction, Component parent,
3307 ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact,
3308 boolean needToUpdateGroup) {
3309 Either<ArtifactDefinition, Operation> insideEither = null;
3310 String currentHeatId = currHeatArtifact.getUniqueId();
3311 String esArtifactId = currHeatArtifact.getEsId();
3312 Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3313 if (artifactFromES.isRight()) {
3314 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3315 throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3317 DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3318 ArtifactDefinition updatedHeatArt = currHeatArtifact;
3319 List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3320 List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3321 List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3322 if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3323 //TODO: improve complexity - currently N^2
3325 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3326 paramName = heatEnvParam.getName();
3327 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3328 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3329 String updatedParamValue = heatEnvParam.getCurrentValue();
3330 if (updatedParamValue == null) {
3331 updatedParamValue = heatEnvParam.getDefaultValue();
3333 HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3334 if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3335 throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE, ArtifactTypeEnum.HEAT_ENV.getType(),
3336 paramType.getType(), paramName);
3338 currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3339 newHeatEnvParams.add(currHeatParam);
3344 if (!newHeatEnvParams.isEmpty()) {
3345 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3346 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation
3347 .updateArtifactOnResource(currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId,
3349 if (operationStatus.isRight()) {
3350 log.debug("Failed to update artifact on graph - {}", currHeatArtifact.getUniqueId());
3351 throw new StorageException(operationStatus.right().value());
3353 updatedHeatArt = operationStatus.left().value();
3354 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3355 DAOArtifactData.setId(updatedHeatArt.getEsId());
3357 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), auditingAction,
3359 insideEither = Either.left(updatedHeatArt);
3362 Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3363 if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3364 artifactEnvInfo.setArtifactChecksum(null);
3365 updateHeatEnvArtifact = artifactToscaOperation
3366 .updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), componentType.getNodeType(),
3369 //TODO Andrey check if componentId = parent.getUniqeId
3370 updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType.getNodeType());
3372 if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3373 ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo, updateHeatEnvArtifact.left().value(), parent);
3374 if (result != ActionStatus.OK) {
3375 throw new ByActionStatusComponentException(result);
3378 if (updatedHeatEnvParams.isEmpty()) {
3379 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3381 return insideEither;
3384 private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3385 StorageOperationStatus error = StorageOperationStatus.OK;
3386 log.debug("Need to re-generate customization UUID for group instance on component instance {}", ri.getUniqueId());
3387 List<GroupInstance> groupsInstances = ri.getGroupInstances();
3388 List<String> groupInstancesId = null;
3389 if (groupsInstances != null && !groupsInstances.isEmpty()) {
3390 groupInstancesId = groupsInstances.stream()
3391 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(artifactId))
3392 .map(GroupInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
3394 if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3395 toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3400 public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent,
3401 User user, ArtifactDefinition artifactInfo,
3402 String artifactId, ComponentTypeEnum componentType,
3404 List<HeatParameterDefinition> currentHeatEnvParams,
3405 List<HeatParameterDefinition> updatedHeatEnvParams,
3406 String currArtifactName) {
3407 if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3408 ResponseFormat responseFormat = componentsUtils
3409 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName);
3410 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3411 return Either.right(responseFormat);
3413 for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3414 String paramName = uploadedHeatParam.getName();
3415 boolean isExistsInHeat = false;
3416 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3417 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3418 isExistsInHeat = true;
3419 uploadedHeatParam.setType(currHeatParam.getType());
3420 uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3421 uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3422 uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3426 if (!isExistsInHeat) {
3427 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3428 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType,
3430 return Either.right(responseFormat);
3433 return Either.left(updatedHeatEnvParams);
3436 private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId,
3437 AuditingActionEnum auditingAction, User user) {
3438 ResponseFormat responseFormat = null;
3439 List<ComponentInstance> ris = component.getComponentInstances();
3440 for (ComponentInstance ri : ris) {
3441 if (riID.equals(ri.getUniqueId())) {
3442 return Either.left(ri);
3445 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3446 log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3447 handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3448 return Either.right(responseFormat);
3451 private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId,
3452 AuditingActionEnum auditingAction, User user) {
3453 ResponseFormat responseFormat = null;
3454 Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3455 for (ArtifactDefinition artifact : rtifactsMap.values()) {
3456 if (artifactId.equals(artifact.getUniqueId())) {
3457 return Either.left(artifact);
3460 responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3461 handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3463 return Either.right(responseFormat);
3466 public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3467 ArtifactDefinition ret;
3468 if (eitherArtifact.isLeft()) {
3469 ret = eitherArtifact.left().value();
3471 ret = eitherArtifact.right().value().getImplementationArtifact();
3476 public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
3477 ResourceCommonInfo resourceCommonInfo) {
3478 Component component = getComponentByUuid(componentType, componentUuid);
3479 resourceCommonInfo.setResourceName(component.getName());
3480 return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3484 * downloads an artifact of resource instance of component by UUIDs
3486 * @param componentType
3487 * @param componentUuid
3488 * @param resourceInstanceName
3489 * @param artifactUUID
3492 public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
3493 String artifactUUID) {
3494 ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3495 if (resourceInstance != null) {
3496 return downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, resourceInstance.getName());
3498 return downloadArtifact(null, artifactUUID, null);
3503 * uploads an artifact to a component by UUID
3507 * @param componentType
3508 * @param componentUuid
3509 * @param resourceCommonInfo
3513 public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3514 String componentUuid, ResourceCommonInfo resourceCommonInfo,
3515 ArtifactOperationInfo operation) {
3516 Either<ArtifactDefinition, Operation> actionResult;
3517 Component component;
3519 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3520 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3521 String userId = request.getHeader(Constants.USER_ID_HEADER);
3522 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3523 ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3524 componentId = componentMetadataDataDefinition.getUniqueId();
3525 String componentName = componentMetadataDataDefinition.getName();
3526 if (!componentMetadataDataDefinition.getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3527 component = checkoutParentComponent(componentType, componentId, userId);
3528 if (component != null) {
3529 componentId = component.getUniqueId();
3530 componentName = component.getName();
3533 resourceCommonInfo.setResourceName(componentName);
3534 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null,
3536 return actionResult.left().value();
3540 * upload an artifact to a resource instance by UUID
3544 * @param componentType
3545 * @param componentUuid
3546 * @param resourceInstanceName
3550 public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3551 String resourceInstanceName, ArtifactOperationInfo operation) {
3552 Either<ArtifactDefinition, Operation> actionResult;
3553 Component component = null;
3554 String componentInstanceId;
3556 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3557 String userId = request.getHeader(Constants.USER_ID_HEADER);
3558 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3559 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid,
3560 resourceInstanceName);
3561 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3562 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3564 if (component == null) {
3565 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3567 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3569 componentInstanceId = componentRiPair.getRight().getUniqueId();
3570 componentId = componentRiPair.getLeft().getUniqueId();
3571 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3572 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5,
3573 data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3574 return actionResult.left().value();
3578 * updates an artifact on a component by UUID
3582 * @param componentType
3583 * @param componentUuid
3584 * @param artifactUUID
3585 * @param resourceCommonInfo
3586 * @param operation TODO
3589 public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3590 String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3591 ArtifactOperationInfo operation) {
3592 Either<ArtifactDefinition, Operation> actionResult;
3593 Component component;
3596 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3597 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3598 String userId = request.getHeader(Constants.USER_ID_HEADER);
3599 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3600 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3601 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3602 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3603 component = checkoutParentComponent(componentType, componentId, userId);
3604 if (component != null) {
3605 componentId = component.getUniqueId();
3606 componentName = component.getName();
3609 resourceCommonInfo.setResourceName(componentName);
3610 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3611 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null,
3613 if (actionResult.isRight()) {
3614 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult.right().value());
3616 return actionResult.left().value();
3620 * updates an artifact on a resource instance by UUID
3624 * @param componentType
3625 * @param componentUuid
3626 * @param resourceInstanceName
3627 * @param artifactUUID
3628 * @param operation TODO
3631 public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3632 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3633 Either<ArtifactDefinition, Operation> actionResult;
3634 Component component = null;
3635 String componentInstanceId;
3638 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3639 String userId = request.getHeader(Constants.USER_ID_HEADER);
3640 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3641 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3642 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3643 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3645 if (component == null) {
3646 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3648 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3650 componentInstanceId = componentRiPair.getRight().getUniqueId();
3651 componentId = componentRiPair.getLeft().getUniqueId();
3652 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3653 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3654 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo,
3655 origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3656 return actionResult.left().value();
3659 private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid,
3660 ArtifactDefinition artifactInfo) {
3661 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3662 if (componentStorageOperationStatusEither.isRight()) {
3663 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3664 log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
3665 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3667 Component storedComponent = componentStorageOperationStatusEither.left().value();
3668 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3669 .getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
3670 if (!optionalInterface.isPresent()) {
3671 log.debug("Failed to get resource interface for resource Id {}", componentId);
3672 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
3674 //fetch the operation from storage
3675 InterfaceDefinition gotInterface = optionalInterface.get();
3676 Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
3677 Optional<Operation> optionalOperation = operationsMap.values().stream().filter(o -> o.getUniqueId().equals(operationUuid)).findFirst();
3678 if (!optionalOperation.isPresent()) {
3679 log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
3680 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
3681 return Either.right(responseFormat);
3683 Operation operation = optionalOperation.get();
3684 ArtifactDefinition implementationArtifact = operation.getImplementationArtifact();
3685 implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
3686 implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
3687 implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
3688 implementationArtifact.setDescription(artifactInfo.getDescription());
3689 implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
3690 implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
3691 implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
3692 implementationArtifact.setEsId(artifactInfo.getEsId());
3693 operation.setImplementation(implementationArtifact);
3694 gotInterface.setOperationsMap(operationsMap);
3695 Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = interfaceOperation
3696 .updateInterfaces(storedComponent.getUniqueId(), Collections.singletonList(gotInterface));
3697 if (interfaceDefinitionStorageOperationStatusEither.isRight()) {
3698 StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
3699 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
3700 return Either.right(componentsUtils.getResponseFormat(actionStatus));
3702 return Either.left(artifactInfo);
3706 * updates an artifact on a component by UUID
3710 * @param componentType
3711 * @param componentUuid
3712 * @param artifactUUID
3716 public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(String data, HttpServletRequest request,
3717 ComponentTypeEnum componentType,
3718 String componentUuid, String interfaceUUID,
3719 String operationUUID, String artifactUUID,
3720 ResourceCommonInfo resourceCommonInfo,
3721 ArtifactOperationInfo operation) {
3722 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
3723 Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
3724 String componentId = null;
3725 ArtifactDefinition existingArtifactInfo = null;
3726 String interfaceName = null;
3727 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3728 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3729 String userId = request.getHeader(Constants.USER_ID_HEADER);
3730 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3731 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(as));
3734 if (errorWrapper.isEmpty()) {
3735 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3736 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3737 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3738 Component component = checkoutParentComponent(componentType, componentId, userId);
3739 if (component != null) {
3740 componentId = component.getUniqueId();
3741 componentName = component.getName();
3744 resourceCommonInfo.setResourceName(componentName);
3746 if (errorWrapper.isEmpty()) {
3747 Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
3748 if (interfaceNameEither.isRight()) {
3749 errorWrapper.setInnerElement(interfaceNameEither.right().value());
3751 interfaceName = interfaceNameEither.left().value();
3753 if (errorWrapper.isEmpty()) {
3754 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
3755 if (toscaComponentEither.isRight()) {
3756 StorageOperationStatus status = toscaComponentEither.right().value();
3757 log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
3758 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
3760 if (errorWrapper.isEmpty()) {
3761 NodeTypeEnum parentType = convertParentType(componentType);
3762 final List<ArtifactDefinition> existingDeploymentArtifacts = getDeploymentArtifacts(toscaComponentEither.left().value(), null);
3763 for (ArtifactDefinition artifactDefinition : existingDeploymentArtifacts) {
3764 if (artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())) {
3765 existingArtifactInfo = artifactDefinition;
3769 if (existingArtifactInfo != null) {
3770 return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
3775 if (errorWrapper.isEmpty()) {
3776 updateArtifactResult = handleArtifactRequestAndFlatten(componentId, userId, componentType, operation, artifactUUID, artifactInfo, origMd5,
3777 data, interfaceName, operationUUID);
3779 updateArtifactResult = Either.right(errorWrapper.getInnerElement());
3781 return updateArtifactResult;
3784 private Either<ArtifactDefinition, ResponseFormat> handleArtifactRequestAndFlatten(String componentId, String userId,
3785 ComponentTypeEnum componentType,
3786 ArtifactOperationInfo operation, String artifactId,
3787 ArtifactDefinition artifactInfo, String origMd5,
3788 String originData, String interfaceName,
3789 String operationName) {
3791 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
3792 operationName, null, null).right().map(op -> {
3793 log.debug("Unexpected value returned while calling handleArtifactRequest: {}", op);
3794 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3796 } catch (ComponentException e) {
3797 return Either.right(e.getResponseFormat());
3801 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid) {
3802 return fetchLatestComponentMetadataOrThrow(componentType, componentUuid, componentUuid);
3805 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid,
3806 String resourceInstanceName) {
3807 return fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3808 throw new ByActionStatusComponentException(as, resourceInstanceName);
3812 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadata(ComponentTypeEnum componentType, String componentUuid) {
3813 return toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true).right().map(sos -> {
3814 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, sos);
3815 return componentsUtils.convertFromStorageResponse(sos, componentType);
3819 private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
3820 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3821 if (componentStorageOperationStatusEither.isRight()) {
3822 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3823 log.debug("Failed to fetch component information by component id, error {}", errorStatus);
3824 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3826 Component storedComponent = componentStorageOperationStatusEither.left().value();
3827 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3828 .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
3829 if (!optionalInterface.isPresent()) {
3830 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
3832 return Either.left(optionalInterface.get().getType());
3836 * deletes an artifact on a component by UUID
3839 * @param componentType
3840 * @param componentUuid
3841 * @param artifactUUID
3842 * @param resourceCommonInfo
3843 * @param operation TODO
3846 public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3847 String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3848 ArtifactOperationInfo operation) {
3849 Either<ArtifactDefinition, Operation> actionResult;
3850 Component component;
3853 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3854 String userId = request.getHeader(Constants.USER_ID_HEADER);
3855 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3856 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3857 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3858 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3859 component = checkoutParentComponent(componentType, componentId, userId);
3860 if (component != null) {
3861 componentId = component.getUniqueId();
3862 componentName = component.getName();
3865 resourceCommonInfo.setResourceName(componentName);
3866 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3867 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
3868 return actionResult.left().value();
3872 * deletes an artifact from a resource instance by UUID
3875 * @param componentType
3876 * @param componentUuid
3877 * @param resourceInstanceName
3878 * @param artifactUUID
3879 * @param operation TODO
3882 public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3883 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3884 Either<ArtifactDefinition, Operation> actionResult;
3885 Component component = null;
3886 String componentInstanceId;
3889 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3890 String userId = request.getHeader(Constants.USER_ID_HEADER);
3891 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3892 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3893 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3894 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3896 if (component == null) {
3897 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3899 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3901 componentInstanceId = componentRiPair.getRight().getUniqueId();
3902 componentId = componentRiPair.getLeft().getUniqueId();
3903 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3904 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5,
3905 null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3906 return actionResult.left().value();
3909 private String findArtifactId(ComponentInstance instance, String artifactUUID) {
3910 String artifactId = null;
3911 ArtifactDefinition foundArtifact = null;
3912 if (instance.getDeploymentArtifacts() != null) {
3913 foundArtifact = instance.getDeploymentArtifacts().values().stream()
3914 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3916 if (foundArtifact == null && instance.getArtifacts() != null) {
3917 foundArtifact = instance.getArtifacts().values().stream()
3918 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3920 if (foundArtifact == null) {
3921 log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
3922 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
3924 artifactId = foundArtifact.getUniqueId();
3929 @SuppressWarnings("unchecked")
3930 public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact, String envType,
3931 String parentId, NodeTypeEnum parentType, String parentName, User user, Component component,
3932 Map<String, String> existingEnvVersions) {
3933 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
3934 .getDeploymentResourceInstanceArtifacts();
3935 if (deploymentResourceArtifacts == null) {
3936 log.debug("no deployment artifacts are configured for generated artifacts");
3937 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3939 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
3940 if (placeHolderData == null) {
3941 log.debug("no env type {} are configured for generated artifacts", envType);
3942 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3944 String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
3945 ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user.getUserId(),
3946 ArtifactGroupTypeEnum.DEPLOYMENT, true);
3947 ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
3948 artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
3949 artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
3950 artifactHeatEnv.setTimeout(0);
3951 artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
3952 buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
3953 // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
3954 handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
3955 ArtifactDefinition heatEnvPlaceholder;
3956 // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
3957 if (parentType != NodeTypeEnum.ResourceInstance) {
3958 String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
3959 artifactHeatEnv.setArtifactChecksum(checkSum);
3960 Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component,
3961 parentType, parentId);
3962 if (addHeatEnvArtifact.isRight()) {
3963 log.debug("failed to create heat env artifact on resource instance");
3964 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(
3965 componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact.right().value(), false), "", null));
3967 heatEnvPlaceholder = createArtifactPlaceHolder;
3969 heatEnvPlaceholder = artifactHeatEnv;
3970 artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
3971 setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
3973 ComponentTypeEnum componentType = component.getComponentType();
3974 if (parentType == NodeTypeEnum.ResourceInstance) {
3975 componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
3977 createdArtifacts.add(heatEnvPlaceholder);
3978 componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
3979 new ResourceCommonInfo(parentName, componentType.getValue()), ResourceVersionInfo.newBuilder().build(),
3980 ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(), null, heatEnvPlaceholder, null);
3981 return heatEnvPlaceholder;
3984 private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
3985 if (artifact.getListHeatParameters() == null) {
3988 List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
3989 for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
3990 HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
3991 heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
3992 heatEnvParameter.setCurrentValue(null);
3993 heatEnvParameters.add(heatEnvParameter);
3995 artifactDefinition.setListHeatParameters(heatEnvParameters);
3998 private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
3999 String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
4000 String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
4001 String name = heatArtifact.getArtifactName();
4004 name = heatArtifact.getArtifactLabel();
4005 fileName = name + "." + envExtension;
4007 fileName = name.replaceAll("." + heatExtension, "." + envExtension);
4009 heatEnvArtifact.setArtifactName(fileName);
4012 private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
4013 if (null != existingEnvVersions) {
4014 String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
4015 if (null != prevVersion) {
4016 heatEnvArtifact.setArtifactVersion(prevVersion);
4021 public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user,
4022 List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4023 ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4024 ComponentTypeEnum componentType = component.getComponentType();
4025 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4026 Either<ArtifactDefinition, Operation> result;
4028 for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4029 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4030 uploadedArtifacts.add(result.left().value());
4032 } catch (ComponentException e) {
4033 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component.getName(), e.getResponseFormat());
4034 if (operation.isCreateOrLink()) {
4035 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4039 return uploadedArtifacts;
4042 public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Component component, User user, ArtifactOperationInfo operation,
4043 boolean shouldLock, boolean inTransaction, ComponentTypeEnum componentType,
4044 ArtifactDefinition artifactDefinition) {
4045 AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4046 String componentId = component.getUniqueId();
4047 String artifactId = artifactDefinition.getUniqueId();
4048 Either<ArtifactDefinition, Operation> result;
4049 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4050 //artifact validation
4051 artifactDefinition = validateArtifact(componentId, componentType, operation, artifactId, artifactDefinition, auditingAction, user, component,
4052 shouldLock, inTransaction);
4053 switch (operation.getArtifactOperationEnum()) {
4055 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType,
4056 component, null, null);
4057 result = createArtifact(component, componentId, artifactDefinition, validPayload, componentType, auditingAction, null, null);
4060 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component,
4062 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4063 auditingAction, user, component, true);
4066 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4069 if (artifactGenerationRequired(component, artifactDefinition)) {
4070 result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4072 result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4076 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4079 throw new UnsupportedOperationException(
4080 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4085 public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component,
4086 User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4087 ArtifactOperationInfo operation, boolean shouldLock,
4088 boolean inTransaction) {
4089 List<ArtifactDefinition> handleArtifactsResult;
4090 ComponentTypeEnum componentType = component.getComponentType();
4091 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4092 Either<ArtifactDefinition, Operation> actionResult;
4096 for (ArtifactDefinition artifact : artifactsToHandle) {
4097 originData = ArtifactUtils.buildJsonStringForCsarVfcArtifact(artifact);
4098 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4099 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact.getUniqueId(),
4100 artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4101 uploadedArtifacts.add(actionResult.left().value());
4103 handleArtifactsResult = uploadedArtifacts;
4104 } catch (ComponentException e) {
4105 if (operation.isCreateOrLink()) {
4106 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4110 return handleArtifactsResult;
4113 private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName) {
4114 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4115 Option<Component> oComponent = Option.of(getComponentByUuid(componentType, componentUuid));
4116 return oComponent.toTry(componentNotFound(componentType, componentUuid)).flatMap(
4117 component -> findFirstMatching(component, ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4118 .toTry(componentInstanceNotFound(componentType, resourceInstanceName, component))).get();
4121 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName) {
4122 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4123 ComponentInstance componentInstance = findFirstMatching(component,
4124 ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4125 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4126 return new ImmutablePair<>(component, componentInstance);
4129 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid,
4130 String resourceInstanceName) {
4131 Component component = getLatestComponentByUuid(componentType, componentUuid);
4132 ComponentInstance componentInstance = findFirstMatching(component, ci -> ci.getNormalizedName().equals(resourceInstanceName))
4133 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4134 return new ImmutablePair<>(component, componentInstance);
4137 private Supplier<Throwable> componentNotFound(ComponentTypeEnum componentType, String componentUuid) {
4139 log.debug(FAILED_FETCH_COMPONENT, componentType.getValue(), componentUuid);
4140 return new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentUuid);
4144 private Supplier<Throwable> componentInstanceNotFound(ComponentTypeEnum componentType, String resourceInstanceName, Component component) {
4146 log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4147 return new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4148 RESOURCE_INSTANCE, componentType.getValue(), component.getName());
4152 private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4153 ImmutablePair<String, byte[]> downloadArtifact;
4154 List<ArtifactDefinition> artifactsList = null;
4155 ArtifactDefinition deploymentArtifact;
4156 if (artifacts != null && !artifacts.isEmpty()) {
4157 artifactsList = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID))
4158 .collect(Collectors.toList());
4160 if (artifactsList == null || artifactsList.isEmpty()) {
4161 log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4162 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4164 deploymentArtifact = artifactsList.get(0);
4165 downloadArtifact = downloadArtifact(deploymentArtifact);
4166 log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4167 return downloadArtifact.getRight();
4170 private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4171 Component component;
4172 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4173 if (getComponentRes.isRight()) {
4174 StorageOperationStatus status = getComponentRes.right().value();
4175 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4176 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4178 component = getComponentRes.left().value();
4183 private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4184 Component component;
4185 Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4186 if (getComponentRes.isRight()) {
4187 StorageOperationStatus status = getComponentRes.right().value();
4188 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4189 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4191 List<Component> value = getComponentRes.left().value();
4192 if (value.isEmpty()) {
4193 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4194 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4195 throw new ByActionStatusComponentException(status);
4197 component = value.get(0);
4203 private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4204 ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4205 StorageOperationStatus storageStatus;
4206 ArtifactDefinition latestArtifact;
4207 List<ArtifactDefinition> artifacts;
4208 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4209 if (getArtifactsRes.isRight()) {
4210 storageStatus = getArtifactsRes.right().value();
4211 log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4212 if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4213 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4215 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4217 artifacts = getArtifactsRes.left().value().values().stream()
4218 .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList());
4219 if (artifacts == null || artifacts.isEmpty()) {
4220 log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4221 parentId, actionStatus);
4222 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4224 latestArtifact = artifacts.stream().max((a1, a2) -> {
4225 int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4226 if (compareRes == 0) {
4227 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(),
4228 a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate());
4232 if (latestArtifact == null) {
4233 log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4234 parentId, actionStatus);
4235 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4237 return latestArtifact.getUniqueId();
4240 private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4241 Component component = null;
4242 User modifier = userBusinessLogic.getUser(userId, false);
4243 LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout",
4244 LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4245 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
4246 .changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4247 if (checkoutRes.isRight()) {
4248 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId,
4249 checkoutRes.right().value().getStatus());
4250 throw new ByResponseFormatComponentException(checkoutRes.right().value());
4252 return checkoutRes.left().value();
4256 void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4257 this.nodeTemplateOperation = nodeTemplateOperation;
4260 public List<ArtifactConfiguration> getConfiguration() {
4261 return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
4264 public enum ArtifactOperationEnum {
4265 CREATE, UPDATE, DELETE, DOWNLOAD, LINK;
4267 public static boolean isCreateOrLink(ArtifactOperationEnum operation) {
4268 return operation == CREATE || operation == LINK;
4272 public Map<String, ArtifactTypeDefinition> getAllToscaArtifacts(final String modelName) {
4273 if (StringUtils.isNotEmpty(modelName)) {
4274 artifactTypeOperation.validateModel(modelName);
4276 return artifactTypeOperation.getAllArtifactTypes(modelName);