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 final ArtifactTypeOperation artifactTypeOperation;
176 private Gson gson = new GsonBuilder().setPrettyPrinting().create();
177 @javax.annotation.Resource
178 private IInterfaceLifecycleOperation interfaceLifecycleOperation;
179 @javax.annotation.Resource
180 private UserAdminOperation userOperaton;
181 @javax.annotation.Resource
182 private IElementOperation elementOperation;
183 @javax.annotation.Resource
184 private IHeatParametersOperation heatParametersOperation;
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 if (result.isLeft()) {
708 artifactDefinition = result.left().value();
710 artifactDefinition = result.right().value().getImplementationArtifact();
712 // for tosca artifacts and heat env on VF level generated on download without saving
713 if (artifactDefinition.getPayloadData() != null) {
714 return (new ImmutablePair<>(artifactDefinition.getArtifactName(), artifactDefinition.getPayloadData()));
716 return downloadArtifact(artifactDefinition);
719 public Map<String, ArtifactDefinition> handleGetArtifactsByType(String containerComponentType, String parentId, ComponentTypeEnum componentType,
720 String componentId, String artifactGroupType, String userId) {
723 // detect auditing type
724 Map<String, ArtifactDefinition> resMap = null;
729 if (userId == null) {
730 log.debug("handleGetArtifactsByType - no HTTP_CSP_HEADER , component id {}", componentId);
731 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
735 // check user existence
740 validateUserExists(userId);
743 // 5. check service/resource existence
745 // 6. check service/resource check out
747 // 7. user is owner of checkout state
748 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
749 ComponentParametersView componentFilter = new ComponentParametersView();
750 componentFilter.disableAll();
751 componentFilter.setIgnoreArtifacts(false);
752 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
753 componentFilter.setIgnoreComponentInstances(false);
755 Component component = validateComponentExistsByFilter(realComponentId, ComponentTypeEnum.findByParamName(containerComponentType),
757 lockComponent(component, ARTIFACT_ACTION_LOCK);
758 boolean failed = false;
760 ArtifactGroupTypeEnum groupType = ArtifactGroupTypeEnum.findType(artifactGroupType);
761 if (groupType == null) {
762 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
763 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
765 if (parentId == null && groupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
766 List<ArtifactDefinition> list = getDeploymentArtifacts(component, componentId);
767 if (list != null && !list.isEmpty()) {
768 resMap = list.stream().collect(Collectors.toMap(ArtifactDataDefinition::getArtifactLabel, Function.identity()));
770 resMap = new HashMap<>();
774 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsMapStatus = getArtifacts(realComponentId,
775 componentType.getNodeType(), groupType, componentId);
776 if (artifactsMapStatus.isRight()) {
777 if (artifactsMapStatus.right().value() != StorageOperationStatus.NOT_FOUND) {
778 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
779 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
781 resMap = new HashMap<>();
784 resMap = artifactsMapStatus.left().value();
788 } catch (ComponentException e) {
795 janusGraphDao.rollback();
798 janusGraphDao.commit();
800 componentType = component.getComponentType();
801 NodeTypeEnum nodeType = componentType.getNodeType();
802 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
806 private ArtifactDefinition getArtifactIfBelongsToComponent(String componentId, ComponentTypeEnum componentType, String artifactId,
807 Component component) {
808 // check artifact existence
809 Either<ArtifactDefinition, StorageOperationStatus> artifactResult = artifactToscaOperation
810 .getArtifactById(componentId, artifactId, componentType, component.getUniqueId());
811 if (artifactResult.isRight()) {
812 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentId);
814 // verify artifact belongs to component
816 switch (componentType) {
819 found = ComponentUtils.checkArtifactInComponent(component, artifactId);
821 case RESOURCE_INSTANCE:
822 found = ComponentUtils.checkArtifactInResourceInstance(component, componentId, artifactId);
828 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentType.name().toLowerCase());
830 return artifactResult.left().value();
833 private Either<ArtifactDefinition, Operation> handleCreate(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
834 AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType,
835 Component parent, String origMd5, String originData, String interfaceType,
836 String operationName) {
837 byte[] decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, null, user, componentType, parent, origMd5,
838 originData, interfaceType, operationName);
839 return createArtifact(parent, componentId, artifactInfo, decodedPayload, componentType, auditingAction, interfaceType, operationName);
842 private ArtifactDefinition handleLink(String componentId, ArtifactDefinition artifactInfo, ComponentTypeEnum componentType, Component parent) {
843 ComponentInstance foundInstance = findComponentInstance(componentId, parent);
844 String instanceId = null;
845 if (foundInstance != null) {
846 instanceId = foundInstance.getUniqueId();
848 NodeTypeEnum nodeType = convertParentType(componentType);
849 Either<ArtifactDefinition, StorageOperationStatus> artifactDefinitionEither = artifactToscaOperation
850 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
851 if (artifactDefinitionEither.isRight()) {
852 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
854 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), componentId, componentType) != StorageOperationStatus.OK) {
855 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
857 return artifactDefinitionEither.left().value();
860 private <T> Either<ArtifactDefinition, T> lockComponentAndUpdateArtifact(String parentId, ArtifactDefinition artifactInfo,
861 AuditingActionEnum auditingAction, String artifactId, User user,
862 ComponentTypeEnum componentType, Component parent, byte[] decodedPayload,
863 boolean shouldLock, boolean inTransaction) {
864 boolean failed = false;
865 boolean writeAudit = true;
867 lockComponent(parent, shouldLock, ARTIFACT_ACTION_LOCK);
869 return updateArtifactFlow(parent, parentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
870 } catch (ComponentException ce) {
872 handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, ce.getResponseFormat(), componentType, null);
876 } catch (StorageException se) {
882 unlockComponent(failed, parent, inTransaction);
887 private byte[] validateInput(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
888 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
889 String origMd5, String originData, String interfaceType, String operationName) {
890 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
891 return getValidPayload(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, interfaceType,
895 private byte[] getValidPayload(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
896 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
897 String interfaceType, String operationName) {
899 Either<ArtifactDefinition, ResponseFormat> validateResult = validateInput(componentId, artifactInfo, operation, artifactId, user,
900 interfaceType, operationName, componentType, parent);
901 if (validateResult.isRight()) {
902 ResponseFormat responseFormat = validateResult.right().value();
903 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
904 throw new ByResponseFormatComponentException(responseFormat);
906 Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
907 if (payloadEither.isRight()) {
908 ResponseFormat responseFormat = payloadEither.right().value();
909 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
910 log.debug("Error during handle payload");
911 throw new ByResponseFormatComponentException(responseFormat);
913 // validate heat parameters. this part must be after the parameters are
915 // extracted in "handlePayload"
916 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters = validateAndConvertHeatParameters(artifactInfo,
917 artifactInfo.getArtifactType());
918 if (validateAndConvertHeatParameters.isRight()) {
919 ResponseFormat responseFormat = validateAndConvertHeatParameters.right().value();
920 handleAuditing(auditingAction, parent, componentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null);
921 log.debug("Error during handle payload");
922 throw new ByResponseFormatComponentException(responseFormat);
924 return payloadEither.left().value();
927 public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
928 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
929 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
930 if (componentsUtils.isExternalApiEvent(auditingActionEnum)) {
935 user.setUserId("UNKNOWN");
937 handleInternalAuditEvent(auditingActionEnum, component, componentId, user, artifactDefinition, prevArtifactUuid, currentArtifactUuid,
938 responseFormat, componentTypeEnum, resourceInstanceName);
941 private void handleInternalAuditEvent(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
942 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
943 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
944 switch (componentTypeEnum) {
946 Resource resource = (Resource) component;
947 if (resource == null) {
948 // In that case, component ID should be instead of name
949 resource = new Resource();
950 resource.setName(componentId);
952 componentsUtils.auditResource(responseFormat, user, resource, resource.getName(), auditingActionEnum,
953 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(), currentArtifactUuid, artifactDefinition);
956 Service service = (Service) component;
957 if (service == null) {
958 // In that case, component ID should be instead of name
959 service = new Service();
960 service.setName(componentId);
963 .auditComponent(responseFormat, user, service, auditingActionEnum, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
964 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
965 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
967 case RESOURCE_INSTANCE:
968 if (resourceInstanceName == null) {
969 resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId);
971 componentsUtils.auditComponent(responseFormat, user, component, auditingActionEnum,
972 new ResourceCommonInfo(resourceInstanceName, ComponentTypeEnum.RESOURCE_INSTANCE.getValue()),
973 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
974 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
981 private String getResourceInstanceNameFromComponent(Component component, String componentId) {
982 ComponentInstance resourceInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findFirst()
984 String resourceInstanceName = null;
985 if (resourceInstance != null) {
986 resourceInstanceName = resourceInstance.getName();
988 return resourceInstanceName;
991 private void validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperationInfo operation) {
992 if (origMd5 == null) {
993 if (operation.isCreateOrLink() && ArrayUtils.isNotEmpty(payload)) {
994 log.debug("Missing md5 header during artifact create");
995 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
998 if (ArrayUtils.isNotEmpty(payload)) {
999 log.debug("Cannot have payload while md5 header is missing");
1000 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
1003 String encodeBase64Str = GeneralUtility.calculateMD5Base64EncodedByString(originData);
1004 if (!encodeBase64Str.equals(origMd5)) {
1005 log.debug("The calculated md5 is different then the received one");
1006 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1011 private Either<ArtifactDefinition, ResponseFormat> validateInput(final String componentId, final ArtifactDefinition artifactInfo,
1012 final ArtifactOperationInfo operation, final String artifactId, final User user,
1013 String interfaceName, String operationName,
1014 final ComponentTypeEnum componentType, final Component parentComponent) {
1015 final ArtifactDefinition existingArtifactInfo = findArtifact(parentComponent, componentType, componentId, operation, artifactId);
1016 final boolean isCreateOrLinkOperation = ArtifactOperationEnum.isCreateOrLink(operation.getArtifactOperationEnum());
1017 if (!isCreateOrLinkOperation && existingArtifactInfo == null) {
1018 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1020 final Component component;
1021 if (parentComponent.getUniqueId().equals(componentId)) {
1022 component = parentComponent;
1024 final ComponentInstance componentInstance = findComponentInstance(componentId, parentComponent);
1025 component = findComponent(componentInstance.getComponentUid());
1026 component.setComponentType(componentType);
1028 if (!isCreateOrLinkOperation) {
1029 ignoreUnupdateableFieldsInUpdate(operation, artifactInfo, existingArtifactInfo);
1031 if (isInformationalArtifact(artifactInfo)) {
1032 validateInformationalArtifact(artifactInfo, component);
1034 Either<Boolean, ResponseFormat> validateAndSetArtifactname = validateAndSetArtifactName(artifactInfo);
1035 if (validateAndSetArtifactname.isRight()) {
1036 return Either.right(validateAndSetArtifactname.right().value());
1038 if (!validateArtifactNameUniqueness(componentId, parentComponent, artifactInfo, componentType)) {
1039 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST));
1041 if (operationName != null && interfaceName != null) {
1042 operationName = operationName.toLowerCase();
1043 interfaceName = interfaceName.toLowerCase();
1045 Either<ActionStatus, ResponseFormat> logicalNameStatus = handleArtifactLabel(componentId, parentComponent, operation, artifactInfo,
1046 operationName, componentType);
1047 if (logicalNameStatus.isRight()) {
1048 return Either.right(logicalNameStatus.right().value());
1050 // This is a patch to block possibility of updating service api fields
1052 // through other artifacts flow
1053 final ArtifactGroupTypeEnum artifactGroupType =
1054 operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL;
1055 if (operation.isNotCreateOrLink()) {
1056 checkAndSetUnUpdatableFields(user, artifactInfo, existingArtifactInfo, artifactGroupType);
1058 checkCreateFields(user, artifactInfo, artifactGroupType);
1060 composeArtifactId(componentId, artifactId, artifactInfo, interfaceName, operationName);
1061 if (existingArtifactInfo != null) {
1062 artifactInfo.setMandatory(existingArtifactInfo.getMandatory());
1063 if (operation.isNotCreateOrLink()) {
1064 validateArtifactTypeNotChanged(artifactInfo, existingArtifactInfo);
1067 // artifactGroupType is not allowed to be updated
1068 if (operation.isNotCreateOrLink()) {
1069 Either<ArtifactDefinition, ResponseFormat> validateGroupType = validateOrSetArtifactGroupType(artifactInfo, existingArtifactInfo);
1070 if (validateGroupType.isRight()) {
1071 return Either.right(validateGroupType.right().value());
1074 setArtifactTimeout(artifactInfo, existingArtifactInfo);
1075 if (isHeatArtifact(artifactInfo)) {
1076 validateHeatArtifact(parentComponent, componentId, artifactInfo);
1078 if (isDeploymentArtifact(artifactInfo)) {
1079 if (componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1080 final String artifactName = artifactInfo.getArtifactName();
1081 final String existingArtifactName = (existingArtifactInfo == null) ? null : existingArtifactInfo.getArtifactName();
1082 if (operation.isCreateOrLink() || ((artifactName != null) && !artifactName.equalsIgnoreCase(existingArtifactName))) {
1083 validateSingleDeploymentArtifactName(artifactName, parentComponent);
1086 validateDeploymentArtifact(artifactInfo, component);
1088 Either<Boolean, ResponseFormat> descriptionResult = validateAndCleanDescription(artifactInfo);
1089 if (descriptionResult.isRight()) {
1090 return Either.right(descriptionResult.right().value());
1092 validateArtifactType(artifactInfo, component.getComponentType());
1093 artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase());
1094 if (existingArtifactInfo != null && existingArtifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.SERVICE_API) {
1095 // Change of type is not allowed and should be ignored
1096 artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER);
1097 Either<Boolean, ResponseFormat> validateUrl = validateAndServiceApiUrl(artifactInfo);
1098 if (validateUrl.isRight()) {
1099 return Either.right(validateUrl.right().value());
1101 Either<Boolean, ResponseFormat> validateUpdate = validateFirstUpdateHasPayload(artifactInfo, existingArtifactInfo);
1102 if (validateUpdate.isRight()) {
1103 log.debug("serviceApi first update cnnot be without payload.");
1104 return Either.right(validateUpdate.right().value());
1107 if (artifactInfo.getApiUrl() != null) {
1108 artifactInfo.setApiUrl(null);
1109 log.error("Artifact URL cannot be set through this API - ignoring");
1111 if (Boolean.TRUE.equals(artifactInfo.getServiceApi())) {
1112 artifactInfo.setServiceApi(false);
1113 log.error("Artifact service API flag cannot be changed - ignoring");
1116 return Either.left(artifactInfo);
1119 private Component findComponent(final String componentId) {
1120 Either<? extends Component, StorageOperationStatus> component = toscaOperationFacade.getToscaFullElement(componentId);
1121 if (component.isRight()) {
1122 log.debug("Component '{}' not found ", componentId);
1123 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentId);
1125 return component.left().value();
1128 private void ignoreUnupdateableFieldsInUpdate(final ArtifactOperationInfo operation, final ArtifactDefinition artifactInfo,
1129 final ArtifactDefinition currentArtifactInfo) {
1130 if (operation.isUpdate()) {
1131 artifactInfo.setArtifactType(currentArtifactInfo.getArtifactType());
1132 artifactInfo.setArtifactGroupType(currentArtifactInfo.getArtifactGroupType());
1133 artifactInfo.setArtifactLabel(currentArtifactInfo.getArtifactLabel());
1137 private ArtifactDefinition findArtifact(final Component parentComponent, final ComponentTypeEnum componentType, final String parentId,
1138 final ArtifactOperationInfo operation, final String artifactId) {
1139 ArtifactDefinition foundArtifact = null;
1140 if (StringUtils.isNotEmpty(artifactId)) {
1141 foundArtifact = findArtifact(parentComponent, componentType, parentId, artifactId);
1143 if (foundArtifact != null && operation.isCreateOrLink()) {
1144 log.debug("Artifact {} already exist", artifactId);
1145 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, foundArtifact.getArtifactLabel());
1147 if (foundArtifact == null && operation.isNotCreateOrLink()) {
1148 log.debug("The artifact {} was not found on parent component or instance {}. ", artifactId, parentId);
1149 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, "");
1151 return foundArtifact;
1154 private ArtifactDefinition findArtifact(Component parentComponent, ComponentTypeEnum componentType, String parentId, String artifactId) {
1155 ArtifactDefinition foundArtifact;
1156 if (parentComponent.getUniqueId().equals(parentId)) {
1157 foundArtifact = artifactsResolver.findArtifactOnComponent(parentComponent, componentType, artifactId);
1159 ComponentInstance instance = findComponentInstance(parentId, parentComponent);
1160 foundArtifact = artifactsResolver.findArtifactOnComponentInstance(instance, artifactId);
1162 return foundArtifact;
1165 private void validateInformationalArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1166 final ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
1167 if (groupType != ArtifactGroupTypeEnum.INFORMATIONAL) {
1170 final ComponentTypeEnum parentComponentType = component.getComponentType();
1171 final String artifactType = artifactInfo.getArtifactType();
1172 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1173 if (artifactConfiguration == null) {
1174 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1176 validateArtifactType(parentComponentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1177 if (component.getComponentType() == ComponentTypeEnum.RESOURCE || component.getComponentType() == ComponentTypeEnum.RESOURCE_INSTANCE) {
1178 final ResourceTypeEnum resourceType = ((Resource) component).getResourceType();
1179 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1181 validateArtifactExtension(artifactConfiguration, artifactInfo);
1184 private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) {
1185 if (componentType == ComponentTypeEnum.RESOURCE) {
1186 return NodeTypeEnum.Resource;
1187 } else if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1188 return NodeTypeEnum.ResourceInstance;
1190 return NodeTypeEnum.Service;
1194 // This method is here for backward compatibility - when other parts of the code are cleaned can change to use the internal version
1195 public Either<ArtifactDefinition, ResponseFormat> handleDelete(String parentId, String artifactId, User user, Component parent,
1196 boolean shouldLock, boolean inTransaction) {
1197 ResponseFormat responseFormat;
1198 boolean operationSucceeded = false;
1200 lockComponent(ComponentTypeEnum.RESOURCE, artifactId, AuditingActionEnum.ARTIFACT_DELETE, user, parent);
1203 ArtifactDefinition artifactDefinition = handleDeleteInternal(parentId, artifactId, ComponentTypeEnum.RESOURCE, parent);
1204 operationSucceeded = true;
1205 return Either.left(artifactDefinition);
1206 } catch (ComponentException ce) {
1207 responseFormat = componentsUtils.getResponseFormat(ce);
1208 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1209 ComponentTypeEnum.RESOURCE, null);
1210 return Either.right(responseFormat);
1211 } catch (StorageException se) {
1212 responseFormat = componentsUtils.getResponseFormat(se);
1213 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1214 ComponentTypeEnum.RESOURCE, null);
1215 return Either.right(responseFormat);
1217 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
1221 private ArtifactDefinition handleDeleteInternal(String parentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1222 NodeTypeEnum parentType = convertParentType(componentType);
1223 log.debug("Going to find the artifact {} on the component {}", artifactId, parent.getUniqueId());
1224 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> getArtifactRes = findArtifact(artifactId, parent, parentId,
1226 if (getArtifactRes.isRight()) {
1227 log.debug("Failed to find the artifact {} belonging to {} on the component {}", artifactId, parentId, parent.getUniqueId());
1228 throw new ByActionStatusComponentException(getArtifactRes.right().value(), artifactId);
1230 ArtifactDefinition foundArtifact = getArtifactRes.left().value().getLeft();
1231 ComponentInstance foundInstance = getArtifactRes.left().value().getRight();
1232 String esId = foundArtifact.getEsId();
1233 Either<Boolean, StorageOperationStatus> needClone = ifTrue(StringUtils.isNotEmpty(esId),
1234 () -> forEach(artifactToscaOperation.isCloneNeeded(parent.getUniqueId(), foundArtifact, parentType), b -> log
1235 .debug("handleDelete: clone is needed for deleting {} held by {} in component {} {}? {}", foundArtifact.getArtifactName(), parentType,
1236 parent.getUniqueId(), parent.getName(), b)));
1237 boolean needToClone = false;
1238 // TODO: This should not be done, but in order to keep this refactoring small, we stop here.
1240 // Remove this block once the above refactoring is merged.
1241 if (needClone.isLeft()) {
1242 needToClone = needClone.left().value();
1244 throw new StorageException(needClone.right().value(), foundArtifact.getArtifactDisplayName());
1246 boolean isNeedToDeleteArtifactFromDB =
1247 componentType == ComponentTypeEnum.RESOURCE_INSTANCE && isArtifactOnlyResourceInstanceArtifact(foundArtifact, parent, parentId);
1248 boolean isDuplicated = false;
1249 ArtifactDataDefinition updatedArtifact = deleteOrUpdateArtifactOnGraph(parent, parentId, artifactId, parentType, foundArtifact, needToClone);
1250 isDuplicated = updatedArtifact.getDuplicated();
1251 if (!needToClone && !isDuplicated && isNeedToDeleteArtifactFromDB) {
1252 log.debug("Going to delete the artifact {} from the database. ", artifactId);
1253 CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(esId);
1254 if (cassandraStatus != CassandraOperationStatus.OK) {
1255 log.debug("Failed to delete the artifact {} from the database. ", artifactId);
1256 throw new StorageException(convertToStorageOperationStatus(cassandraStatus), foundArtifact.getArtifactDisplayName());
1259 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1260 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(artifactId, foundArtifact, foundInstance.getGroupInstances());
1261 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
1262 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
1263 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
1264 if (status.isRight()) {
1265 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1266 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1269 StorageOperationStatus status = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
1270 if (status != StorageOperationStatus.OK) {
1271 log.debug("Failed to generate new customization UUID for the component instance {}. ", parentId);
1272 throw new StorageException(status, foundArtifact.getArtifactDisplayName());
1275 List<GroupDataDefinition> updatedGroups = getUpdatedGroups(artifactId, foundArtifact, parent.getGroups());
1276 if (CollectionUtils.isNotEmpty(updatedGroups)) {
1277 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, updatedGroups);
1278 if (status.isRight()) {
1279 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1280 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1284 return foundArtifact;
1287 private boolean isArtifactOnlyResourceInstanceArtifact(ArtifactDefinition foundArtifact, Component parent, String instanceId) {
1288 Optional<ComponentInstance> componentInstanceOpt = parent.getComponentInstanceById(instanceId);
1289 if (!componentInstanceOpt.isPresent()) {
1290 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "", "", parent.getName());
1292 ComponentInstance foundInstance = componentInstanceOpt.get();
1293 String componentUid = foundInstance.getComponentUid();
1294 Either<Component, StorageOperationStatus> getContainerRes = toscaOperationFacade.getToscaElement(componentUid);
1295 if (getContainerRes.isRight()) {
1296 log.debug("Failed to fetch the container component {}. ", componentUid);
1297 throw new StorageException(getContainerRes.right().value());
1299 Component origComponent = getContainerRes.left().value();
1300 Map<String, ArtifactDefinition> deploymentArtifacts = origComponent.getDeploymentArtifacts();
1301 if (MapUtils.isNotEmpty(deploymentArtifacts)) {
1302 Optional<String> op = deploymentArtifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1303 if (op.isPresent()) {
1307 Map<String, ArtifactDefinition> artifacts = origComponent.getArtifacts();
1308 if (MapUtils.isNotEmpty(artifacts)) {
1309 Optional<String> op = artifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1310 if (op.isPresent()) {
1317 private List<GroupDataDefinition> getUpdatedGroups(String artifactId, ArtifactDefinition foundArtifact, List<GroupDefinition> groups) {
1318 List<GroupDataDefinition> updatedGroups = new ArrayList<>();
1319 boolean isUpdated = false;
1320 if (groups != null) {
1321 for (GroupDefinition group : groups) {
1323 if (CollectionUtils.isNotEmpty(group.getArtifacts()) && group.getArtifacts().contains(artifactId)) {
1324 group.getArtifacts().remove(artifactId);
1327 if (CollectionUtils.isNotEmpty(group.getArtifactsUuid()) && group.getArtifactsUuid().contains(foundArtifact.getArtifactUUID())) {
1328 group.getArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1332 updatedGroups.add(group);
1336 return updatedGroups;
1339 private List<GroupInstance> getUpdatedGroupInstances(String artifactId, ArtifactDefinition foundArtifact, List<GroupInstance> groupInstances) {
1340 if (CollectionUtils.isEmpty(groupInstances)) {
1341 return new ArrayList<>();
1343 // TODO: A defensive copy should be created here for groupInstances. Modifying
1345 // arguments (aka output arguments) is overall a bad practice as explained in
1347 // Clean Code by Robert Martin.
1349 // A better approach would be to use Lenses.
1350 return groupInstances.stream().filter(gi -> {
1351 boolean groupInstanceArtifactRemoved = gi.getGroupInstanceArtifacts() != null && gi.getGroupInstanceArtifacts().remove(artifactId);
1352 boolean groupInstanceArtifactUUIDRemoved =
1353 gi.getGroupInstanceArtifactsUuid() != null && gi.getGroupInstanceArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1354 return groupInstanceArtifactRemoved || groupInstanceArtifactUUIDRemoved;
1355 }).collect(Collectors.toList());
1358 private ArtifactDataDefinition deleteOrUpdateArtifactOnGraph(Component component, String parentId, String artifactId, NodeTypeEnum parentType,
1359 ArtifactDefinition foundArtifact, Boolean cloneIsNeeded) {
1360 Either<ArtifactDataDefinition, StorageOperationStatus> result;
1361 boolean isMandatory = foundArtifact.getMandatory() || foundArtifact.getServiceApi();
1362 String componentId = component.getUniqueId();
1363 String instanceId = componentId.equals(parentId) ? null : parentId;
1365 log.debug("Going to update mandatory artifact {} from the component {}", artifactId, parentId);
1366 resetMandatoryArtifactFields(foundArtifact);
1367 result = artifactToscaOperation.updateArtifactOnGraph(component, foundArtifact, parentType, artifactId, instanceId, true, true);
1368 } else if (cloneIsNeeded) {
1369 log.debug("Going to clone artifacts and to delete the artifact {} from the component {}", artifactId, parentId);
1370 result = artifactToscaOperation.deleteArtifactWithCloningOnGraph(componentId, foundArtifact, parentType, instanceId, false);
1372 log.debug("Going to delete the artifact {} from the component {}", artifactId, parentId);
1373 result = artifactToscaOperation.removeArtifactOnGraph(foundArtifact, componentId, instanceId, parentType, false);
1375 if (result.isRight()) {
1376 throw new StorageException(result.right().value(), foundArtifact.getArtifactDisplayName());
1378 return result.left().value();
1381 private Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> findArtifact(String artifactId,
1382 Component fetchedContainerComponent,
1384 ComponentTypeEnum componentType) {
1385 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> result = null;
1386 Map<String, ArtifactDefinition> artifacts = new HashMap<>();
1387 ComponentInstance foundInstance = null;
1388 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && StringUtils.isNotEmpty(parentId)) {
1389 Optional<ComponentInstance> componentInstanceOpt = fetchedContainerComponent.getComponentInstances().stream()
1390 .filter(i -> i.getUniqueId().equals(parentId)).findFirst();
1391 if (!componentInstanceOpt.isPresent()) {
1392 result = Either.right(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER);
1394 foundInstance = componentInstanceOpt.get();
1395 fetchArtifactsFromInstance(artifactId, artifacts, foundInstance);
1398 fetchArtifactsFromComponent(artifactId, fetchedContainerComponent, artifacts);
1400 if (result == null) {
1401 if (artifacts.containsKey(artifactId)) {
1402 result = Either.left(new ImmutablePair<>(artifacts.get(artifactId), foundInstance));
1404 result = Either.right(ActionStatus.ARTIFACT_NOT_FOUND);
1410 private void fetchArtifactsFromComponent(String artifactId, Component component, Map<String, ArtifactDefinition> artifacts) {
1411 Map<String, ArtifactDefinition> currArtifacts;
1412 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
1413 currArtifacts = component.getDeploymentArtifacts().values().stream()
1414 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, i -> i));
1415 if (MapUtils.isNotEmpty(currArtifacts)) {
1416 artifacts.putAll(currArtifacts);
1419 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1420 currArtifacts = component.getArtifacts().values().stream()
1421 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1422 if (MapUtils.isNotEmpty(currArtifacts)) {
1423 artifacts.putAll(currArtifacts);
1426 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1427 currArtifacts = component.getToscaArtifacts().values().stream()
1428 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1429 if (MapUtils.isNotEmpty(currArtifacts)) {
1430 artifacts.putAll(currArtifacts);
1435 private void fetchArtifactsFromInstance(String artifactId, Map<String, ArtifactDefinition> artifacts, ComponentInstance instance) {
1436 Map<String, ArtifactDefinition> currArtifacts;
1437 if (MapUtils.isNotEmpty(instance.getDeploymentArtifacts())) {
1438 currArtifacts = instance.getDeploymentArtifacts().values().stream()
1439 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1440 if (MapUtils.isNotEmpty(currArtifacts)) {
1441 artifacts.putAll(currArtifacts);
1444 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(instance.getArtifacts())) {
1445 currArtifacts = instance.getArtifacts().values().stream()
1446 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1447 if (MapUtils.isNotEmpty(currArtifacts)) {
1448 artifacts.putAll(currArtifacts);
1453 private StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) {
1454 StorageOperationStatus result;
1455 switch (cassandraStatus) {
1457 result = StorageOperationStatus.OK;
1460 result = StorageOperationStatus.NOT_FOUND;
1462 case CLUSTER_NOT_CONNECTED:
1463 case KEYSPACE_NOT_CONNECTED:
1464 result = StorageOperationStatus.CONNECTION_FAILURE;
1467 result = StorageOperationStatus.GENERAL_ERROR;
1473 private void resetMandatoryArtifactFields(ArtifactDefinition fetchedArtifact) {
1474 if (fetchedArtifact != null) {
1475 log.debug("Going to reset mandatory artifact {} fields. ", fetchedArtifact.getUniqueId());
1476 fetchedArtifact.setEsId(null);
1477 fetchedArtifact.setArtifactName(null);
1478 fetchedArtifact.setDescription(null);
1479 fetchedArtifact.setApiUrl(null);
1480 fetchedArtifact.setArtifactChecksum(null);
1481 nodeTemplateOperation.setDefaultArtifactTimeout(fetchedArtifact.getArtifactGroupType(), fetchedArtifact);
1482 fetchedArtifact.setArtifactUUID(null);
1483 long time = System.currentTimeMillis();
1484 fetchedArtifact.setPayloadUpdateDate(time);
1485 fetchedArtifact.setHeatParameters(null);
1486 fetchedArtifact.setHeatParamsUpdateDate(null);
1490 private StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId, ComponentTypeEnum componentType) {
1491 StorageOperationStatus error = StorageOperationStatus.OK;
1492 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1493 log.debug("Need to re-generate customization UUID for instance {}", instanceId);
1494 error = toscaOperationFacade.generateCustomizationUUIDOnInstance(componentId, instanceId);
1499 private ArtifactDefinition handleDownload(String componentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1500 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation
1501 .getArtifactById(componentId, artifactId, componentType, parent.getUniqueId());
1502 if (artifactById.isRight()) {
1503 throw new StorageException(artifactById.right().value());
1505 ArtifactDefinition artifactDefinition = artifactById.left().value();
1506 if (artifactDefinition == null) {
1507 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1509 return artifactDefinition;
1512 private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String componentId, Component parentComponent, ArtifactOperationInfo operation,
1513 ArtifactDefinition artifactInfo, String operationName,
1514 ComponentTypeEnum componentType) {
1515 String artifactLabel = artifactInfo.getArtifactLabel();
1516 if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) {
1517 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
1518 log.debug("missing artifact logical name for component {}", componentId);
1519 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1521 if (operation.isCreateOrLink() && !artifactInfo.getMandatory()) {
1522 if (operationName != null) {
1523 if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) {
1524 log.debug("artifact label cannot be set {}", artifactLabel);
1525 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED));
1527 artifactLabel = operationName;
1530 String displayName = artifactInfo.getArtifactDisplayName();
1531 if (displayName == null || displayName.isEmpty()) {
1532 displayName = artifactLabel;
1534 displayName = ValidationUtils.cleanArtifactDisplayName(displayName);
1535 artifactInfo.setArtifactDisplayName(displayName);
1536 if (!ValidationUtils.validateArtifactLabel(artifactLabel)) {
1537 log.debug("Invalid format form Artifact label : {}", artifactLabel);
1538 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_ARTIFACT_LABEL_NAME, VALID_ARTIFACT_LABEL_NAME));
1540 artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel);
1541 if (artifactLabel.isEmpty()) {
1542 log.debug("missing normalized artifact logical name for component {}", componentId);
1543 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1545 if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) {
1546 log.debug("Invalid lenght form Artifact label : {}", artifactLabel);
1547 return Either.right(componentsUtils
1548 .getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH)));
1550 if (!validateLabelUniqueness(componentId, parentComponent, artifactLabel, componentType)) {
1551 log.debug("Non unique Artifact label : {}", artifactLabel);
1552 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel));
1555 artifactInfo.setArtifactLabel(artifactLabel);
1556 return Either.left(ActionStatus.OK);
1559 private boolean validateLabelUniqueness(String componentId, Component parentComponent, String artifactLabel, ComponentTypeEnum componentType) {
1560 boolean isUnique = true;
1561 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts;
1562 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1563 artifacts = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1565 artifacts = artifactToscaOperation.getArtifacts(componentId);
1567 if (artifacts.isLeft()) {
1568 for (String label : artifacts.left().value().keySet()) {
1569 if (label.equals(artifactLabel)) {
1575 if (componentType == ComponentTypeEnum.RESOURCE && isUnique) {
1576 isUnique = isUniqueLabelInResourceInterfaces(componentId, artifactLabel);
1581 boolean validateArtifactNameUniqueness(String componentId, Component parentComponent, ArtifactDefinition artifactInfo,
1582 ComponentTypeEnum componentType) {
1583 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = getArtifacts(componentType, parentComponent, componentId,
1584 artifactInfo.getArtifactGroupType());
1585 String artifactName = artifactInfo.getArtifactName();
1586 if (artifacts.isLeft() && Objects.nonNull(artifacts.left().value())) {
1587 if (artifacts.left().value().values().stream().anyMatch(ad -> artifactName.equals(ad.getArtifactName())
1588 //check whether it is the same artifact we hold (by label)
1589 && !artifactInfo.getArtifactLabel().equals(ad.getArtifactLabel()))) {
1593 if (ComponentTypeEnum.RESOURCE == componentType) {
1594 return isUniqueArtifactNameInResourceInterfaces(componentId, artifactName, artifactInfo.getArtifactLabel());
1599 private boolean isUniqueArtifactNameInResourceInterfaces(String componentId, String artifactName, String artifactLabel) {
1600 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1601 .getAllInterfacesOfResource(componentId, true, true);
1602 if (allInterfacesOfResource.isLeft()) {
1603 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1604 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1605 .noneMatch(add -> artifactName.equals(add.getArtifactName()) && !artifactLabel.equals(add.getArtifactLabel()));
1610 private boolean isUniqueLabelInResourceInterfaces(String componentId, String artifactLabel) {
1611 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1612 .getAllInterfacesOfResource(componentId, true, true);
1613 if (allInterfacesOfResource.isLeft()) {
1614 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1615 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1616 .noneMatch(add -> artifactLabel.equals(add.getArtifactLabel()));
1621 private Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(ComponentTypeEnum componentType, Component parentComponent,
1623 ArtifactGroupTypeEnum artifactGroupType) {
1624 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse;
1625 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1626 artifactsResponse = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1628 artifactsResponse = artifactToscaOperation.getArtifacts(componentId);
1630 if (artifactsResponse.isRight() && artifactsResponse.right().value() == StorageOperationStatus.NOT_FOUND) {
1631 log.debug("failed to retrieve artifacts for {} ", componentId);
1632 return Either.right(artifactsResponse.right().value());
1634 return Either.left(artifactsResponse.left().value().entrySet().stream().filter(x -> artifactGroupType == x.getValue().getArtifactGroupType())
1635 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
1638 // ***************************************************************
1639 private Either<ArtifactDefinition, Operation> createArtifact(Component parent, String parentId, ArtifactDefinition artifactInfo,
1640 byte[] decodedPayload, ComponentTypeEnum componentTypeEnum,
1641 AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) {
1642 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
1643 if (artifactData == null) {
1644 BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact");
1645 log.debug("Failed to create artifact object for ES.");
1646 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1648 ComponentInstance foundInstance = findComponentInstance(parentId, parent);
1649 String instanceId = null;
1650 if (foundInstance != null) {
1651 if (foundInstance.isArtifactExists(artifactInfo.getArtifactGroupType(), artifactInfo.getArtifactLabel())) {
1652 log.debug("Failed to create artifact, already exists");
1653 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, artifactInfo.getArtifactLabel());
1655 instanceId = foundInstance.getUniqueId();
1657 // set on graph object id of artifact in ES!
1658 artifactInfo.setEsId(artifactData.getId());
1659 Either<ArtifactDefinition, Operation> operationResult;
1660 if (interfaceType != null && operationName != null) {
1661 // lifecycle artifact
1662 Operation operation = convertToOperation(artifactInfo, operationName);
1663 Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation
1664 .updateInterfaceOperation(parentId, interfaceType, operationName, operation);
1665 if (result.isRight()) {
1666 throw new StorageException(result.right().value());
1668 operationResult = Either.right(result.left().value());
1670 // information/deployment/api artifacts
1671 NodeTypeEnum nodeType = convertParentType(componentTypeEnum);
1672 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
1673 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
1674 if (result.isRight()) {
1675 throw new StorageException(result.right().value());
1677 ArtifactDefinition artifactDefinition = result.left().value();
1678 artifactData.setId(artifactDefinition.getEsId());
1679 operationResult = Either.left(artifactDefinition);
1680 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum) != StorageOperationStatus.OK) {
1681 throw new StorageException(generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum));
1684 saveArtifactInCassandra(artifactData, parent, artifactInfo, "", "", auditingActionEnum, componentTypeEnum);
1685 return operationResult;
1688 private ComponentInstance findComponentInstance(String componentInstanceId, Component containerComponent) {
1689 ComponentInstance foundInstance = null;
1690 if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
1691 foundInstance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst()
1694 return foundInstance;
1697 private void validateDeploymentArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1698 final ComponentTypeEnum componentType = component.getComponentType();
1699 if (componentType != ComponentTypeEnum.RESOURCE && componentType != ComponentTypeEnum.SERVICE
1700 && componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1701 log.debug("Invalid component type '{}' for artifact. " + "Expected Resource, Component or Resource Instance", componentType.getValue());
1702 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, componentType.getValue(),
1703 "Service, Resource or ResourceInstance", componentType.getValue());
1705 final String artifactType = artifactInfo.getArtifactType();
1706 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1707 if (artifactConfiguration == null) {
1708 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1710 validateArtifactType(componentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1711 if (componentType == ComponentTypeEnum.RESOURCE || componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1712 final Resource resource = (Resource) component;
1713 final ResourceTypeEnum resourceType = resource.getResourceType();
1714 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1716 validateArtifactExtension(artifactConfiguration, artifactInfo);
1719 private void validateHeatArtifact(final Component parentComponent, final String componentId, final ArtifactDefinition artifactDefinition) {
1720 final String artifactType = artifactDefinition.getArtifactType();
1721 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1722 if (artifactTypeEnum == null) {
1725 switch (artifactTypeEnum) {
1729 validateHeatTimeoutValue(artifactDefinition);
1732 validateHeatEnvDeploymentArtifact(parentComponent, componentId, artifactDefinition);
1739 private void setArtifactTimeout(final ArtifactDefinition newArtifactInfo, final ArtifactDefinition existingArtifactInfo) {
1740 final String artifactType = newArtifactInfo.getArtifactType();
1741 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1742 if (artifactTypeEnum == null) {
1743 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1746 switch (artifactTypeEnum) {
1750 if (newArtifactInfo.getTimeout() == null) {
1751 if (existingArtifactInfo == null) {
1752 newArtifactInfo.setTimeout(NodeTemplateOperation.getDefaultHeatTimeout());
1754 newArtifactInfo.setTimeout(existingArtifactInfo.getTimeout());
1759 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1765 void validateDeploymentArtifactTypeIsLegalForParent(ArtifactDefinition artifactInfo, ArtifactTypeEnum artifactType,
1766 Map<String, ArtifactTypeConfig> resourceDeploymentArtifacts) {
1767 if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) {
1768 log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType());
1769 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
1773 Optional<ArtifactConfiguration> loadArtifactTypeConfig(final String artifactType) {
1774 if (artifactType == null) {
1775 return Optional.empty();
1777 final List<ArtifactConfiguration> artifactConfigurationList = ConfigurationManager.getConfigurationManager().getConfiguration()
1779 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
1780 return Optional.empty();
1782 return artifactConfigurationList.stream().filter(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType))
1786 private Either<Boolean, ResponseFormat> extractHeatParameters(ArtifactDefinition artifactInfo) {
1787 // extract heat parameters
1788 if (artifactInfo.getPayloadData() != null) {
1789 String heatDecodedPayload = new String(Base64.decodeBase64(artifactInfo.getPayloadData()));
1790 Either<List<HeatParameterDefinition>, ResultStatusEnum> heatParameters = ImportUtils
1791 .getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo.getArtifactType());
1792 if (heatParameters.isRight() && (heatParameters.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND)) {
1793 log.info("failed to parse heat parameters ");
1794 ResponseFormat responseFormat = componentsUtils
1795 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactType());
1796 return Either.right(responseFormat);
1797 } else if (heatParameters.isLeft() && heatParameters.left().value() != null) {
1798 artifactInfo.setListHeatParameters(heatParameters.left().value());
1801 return Either.left(true);
1805 void validateArtifactExtension(final ArtifactConfiguration artifactConfiguration, final ArtifactDefinition artifactDefinition) {
1806 final List<String> acceptedTypes = artifactConfiguration.getAcceptedTypes();
1808 * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted.
1810 if (CollectionUtils.isEmpty(acceptedTypes)) {
1813 final String artifactName = artifactDefinition.getArtifactName();
1814 final String fileExtension = FilenameUtils.getExtension(artifactName);
1815 if (fileExtension == null || !acceptedTypes.contains(fileExtension.toLowerCase())) {
1816 final String artifactType = artifactDefinition.getArtifactType();
1817 log.debug("File extension \"{}\" is not allowed for artifact type \"{}\"", fileExtension, artifactType);
1818 throw new ByActionStatusComponentException(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, artifactType);
1823 void validateHeatEnvDeploymentArtifact(final Component parentComponent, final String parentId, final ArtifactDefinition artifactInfo) {
1824 final Wrapper<ArtifactDefinition> heatMDWrapper = new Wrapper<>();
1825 final Wrapper<byte[]> payloadWrapper = new Wrapper<>();
1826 validateYaml(artifactInfo);
1827 validateHeatExist(parentComponent.getUniqueId(), parentId, heatMDWrapper, artifactInfo, parentComponent.getComponentType());
1828 if (!heatMDWrapper.isEmpty()) {
1829 fillArtifactPayload(payloadWrapper, heatMDWrapper.getInnerElement());
1831 if (!heatMDWrapper.isEmpty()) {
1832 validateEnvVsHeat(artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement());
1836 public void fillArtifactPayload(Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactDefinition) {
1837 if (ArrayUtils.isEmpty(artifactDefinition.getPayloadData())) {
1838 Either<DAOArtifactData, CassandraOperationStatus> eitherArtifactData = artifactCassandraDao.getArtifact(artifactDefinition.getEsId());
1839 if (eitherArtifactData.isLeft()) {
1840 byte[] data = eitherArtifactData.left().value().getDataAsArray();
1841 payloadWrapper.setInnerElement(Base64.encodeBase64(data));
1843 log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName());
1844 throw new StorageException(DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()));
1847 payloadWrapper.setInnerElement(artifactDefinition.getPayloadData());
1851 private void validateEnvVsHeat(ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) {
1852 String envPayload = new String(Base64.decodeBase64(envArtifact.getPayloadData()));
1853 Map<String, Object> heatEnvToscaJson = (Map<String, Object>) new Yaml().load(envPayload);
1854 String heatDecodedPayload = new String(Base64.decodeBase64(heatPayloadData));
1855 Map<String, Object> heatToscaJson = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
1856 Either<Map<String, Object>, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils
1857 .findFirstToscaMapElement(heatEnvToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1858 if (eitherHeatEnvProperties.isRight()) {
1859 log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName());
1860 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat Env");
1862 Either<Map<String, Object>, ResultStatusEnum> eitherHeatProperties = ImportUtils
1863 .findFirstToscaMapElement(heatToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1864 if (eitherHeatProperties.isRight()) {
1865 log.debug("Invalid heat format for file:{}", heatArtifact.getArtifactName());
1866 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat");
1868 Set<String> heatPropertiesKeys = eitherHeatProperties.left().value().keySet();
1869 Set<String> heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet();
1870 heatEnvPropertiesKeys.removeAll(heatPropertiesKeys);
1871 if (!heatEnvPropertiesKeys.isEmpty()) {
1872 log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(),
1873 heatArtifact.getArtifactName());
1874 throw new ByActionStatusComponentException(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(),
1875 heatArtifact.getArtifactName());
1879 private void validateYaml(ArtifactDefinition artifactInfo) {
1880 YamlToObjectConverter yamlConverter = new YamlToObjectConverter();
1881 boolean isYamlValid = yamlConverter.isValidYamlEncoded64(artifactInfo.getPayloadData());
1883 log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName());
1884 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType());
1888 private void validateSingleDeploymentArtifactName(final String artifactName, final Component parentComponent) {
1889 boolean artifactNameFound = false;
1890 final Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, null).iterator();
1891 while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) {
1892 artifactNameFound = artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName());
1894 if (artifactNameFound) {
1895 final ComponentTypeEnum componentType = parentComponent.getComponentType();
1896 log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName);
1897 throw new ByActionStatusComponentException(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, componentType.getValue(),
1898 parentComponent.getName(), artifactName);
1902 private void validateHeatExist(String componentId, String parentRiId, Wrapper<ArtifactDefinition> heatArtifactMDWrapper,
1903 ArtifactDefinition heatEnvArtifact, ComponentTypeEnum componentType) {
1904 final Either<ArtifactDefinition, StorageOperationStatus> res = artifactToscaOperation
1905 .getHeatArtifactByHeatEnvId(parentRiId, heatEnvArtifact, componentId, componentType);
1906 if (res.isRight()) {
1907 throw new ByActionStatusComponentException(ActionStatus.MISSING_HEAT);
1909 heatArtifactMDWrapper.setInnerElement(res.left().value());
1913 void validateHeatTimeoutValue(final ArtifactDefinition artifactInfo) {
1914 log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel());
1915 // timeout > 0 for HEAT artifacts
1916 if (artifactInfo.getTimeout() == null || artifactInfo.getTimeout() < 1) {
1917 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
1919 // US649856 - Allow several HEAT files on Resource
1920 log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel());
1924 void validateResourceType(final ResourceTypeEnum resourceType, final ArtifactDefinition artifactInfo, final List<String> typeList) {
1925 if (CollectionUtils.isEmpty(typeList) || typeList.contains(resourceType.getValue())) {
1928 final String listToString = typeList.stream().collect(Collectors.joining(", "));
1929 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, artifactInfo.getArtifactGroupType().getType(),
1930 listToString, resourceType.getValue());
1934 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters(ArtifactDefinition artifactInfo, String artifactType) {
1935 if (artifactInfo.getHeatParameters() != null) {
1936 for (HeatParameterDefinition heatParam : artifactInfo.getListHeatParameters()) {
1937 String parameterType = heatParam.getType();
1938 HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType);
1939 String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType();
1940 if (heatParameterType == null) {
1941 ResponseFormat responseFormat = componentsUtils
1942 .getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam.getType());
1943 return Either.right(responseFormat);
1945 StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam);
1946 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
1947 log.debug("Heat parameter {} is invalid. Status is {}", heatParam.getName(), validateAndUpdateProperty);
1948 ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE;
1949 ResponseFormat responseFormat = componentsUtils
1950 .getResponseFormat(status, artifactTypeStr, heatParam.getType(), heatParam.getName());
1951 return Either.right(responseFormat);
1955 return Either.left(artifactInfo);
1958 public List<ArtifactDefinition> getDeploymentArtifacts(final Component component, final String ciId) {
1959 final ComponentTypeEnum componentType = component.getComponentType();
1960 if (component.getDeploymentArtifacts() == null) {
1961 return Collections.emptyList();
1963 final List<ArtifactDefinition> deploymentArtifacts = new ArrayList<>();
1964 if (ComponentTypeEnum.RESOURCE == componentType && ciId != null) {
1965 final Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(component, ciId, null, null, null);
1966 if (getRI.isRight()) {
1967 return Collections.emptyList();
1969 final ComponentInstance ri = getRI.left().value();
1970 if (ri.getDeploymentArtifacts() != null) {
1971 deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values());
1974 deploymentArtifacts.addAll(component.getDeploymentArtifacts().values());
1976 return deploymentArtifacts;
1979 private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) {
1980 // on create if null add informational to current
1981 if (artifactInfo.getArtifactGroupType() == null) {
1982 artifactInfo.setArtifactGroupType(type);
1984 if (artifactInfo.getUniqueId() != null) {
1985 log.error("artifact uniqid cannot be set ignoring");
1987 artifactInfo.setUniqueId(null);
1988 if (artifactInfo.getArtifactRef() != null) {
1989 log.error("artifact ref cannot be set ignoring");
1991 artifactInfo.setArtifactRef(null);
1992 if (artifactInfo.getArtifactRepository() != null) {
1993 log.error("artifact repository cannot be set ignoring");
1995 artifactInfo.setArtifactRepository(null);
1996 if (artifactInfo.getUserIdCreator() != null) {
1997 log.error("creator uuid cannot be set ignoring");
1999 artifactInfo.setArtifactCreator(user.getUserId());
2000 if (artifactInfo.getUserIdLastUpdater() != null) {
2001 log.error("userId of last updater cannot be set ignoring");
2003 artifactInfo.setUserIdLastUpdater(user.getUserId());
2004 if (artifactInfo.getCreatorFullName() != null) {
2005 log.error("creator Full name cannot be set ignoring");
2007 String fullName = user.getFirstName() + " " + user.getLastName();
2008 artifactInfo.setUpdaterFullName(fullName);
2009 if (artifactInfo.getUpdaterFullName() != null) {
2010 log.error("updater Full name cannot be set ignoring");
2012 artifactInfo.setUpdaterFullName(fullName);
2013 if (artifactInfo.getCreationDate() != null) {
2014 log.error("Creation Date cannot be set ignoring");
2016 long time = System.currentTimeMillis();
2017 artifactInfo.setCreationDate(time);
2018 if (artifactInfo.getLastUpdateDate() != null) {
2019 log.error("Last Update Date cannot be set ignoring");
2021 artifactInfo.setLastUpdateDate(time);
2022 if (artifactInfo.getEsId() != null) {
2023 log.error("es id cannot be set ignoring");
2025 artifactInfo.setEsId(null);
2028 private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName,
2029 String operationName) {
2030 String id = artifactId;
2031 if (artifactId == null || artifactId.isEmpty()) {
2032 String uniqueId = null;
2033 if (interfaceName != null && operationName != null) {
2034 uniqueId = UniqueIdBuilder
2035 .buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo.getArtifactLabel());
2037 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel());
2039 artifactInfo.setUniqueId(uniqueId);
2040 artifactInfo.setEsId(uniqueId);
2043 artifactInfo.setUniqueId(artifactId);
2044 artifactInfo.setEsId(artifactId);
2049 private Either<Boolean, ResponseFormat> validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2050 if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) {
2051 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD));
2053 return Either.left(true);
2057 Either<Boolean, ResponseFormat> validateAndSetArtifactName(ArtifactDefinition artifactInfo) {
2058 if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) {
2059 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2061 String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName());
2062 if (normalizeFileName == null || normalizeFileName.isEmpty()) {
2063 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2065 artifactInfo.setArtifactName(normalizeFileName);
2066 if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) {
2067 return Either.right(
2068 componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH)));
2070 return Either.left(true);
2073 private void validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2074 if (StringUtils.isEmpty(artifactInfo.getArtifactType())) {
2075 log.info("artifact type is missing operation ignored");
2076 throw new ByActionStatusComponentException(ActionStatus.MISSING_ARTIFACT_TYPE);
2078 if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) {
2079 log.info("artifact type cannot be changed operation ignored");
2080 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2084 private Either<ArtifactDefinition, ResponseFormat> validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo,
2085 ArtifactDefinition currentArtifact) {
2086 if (null != artifactInfo && null != currentArtifact) {
2087 if (artifactInfo.getArtifactGroupType() == null) {
2088 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2089 } else if (!currentArtifact.getArtifactGroupType().getType().equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) {
2090 log.info("artifact group type cannot be changed. operation failed");
2091 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2094 return Either.left(artifactInfo);
2097 private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact,
2098 ArtifactGroupTypeEnum type) {
2099 // on update if null add informational to current
2100 if (currentArtifact.getArtifactGroupType() == null && type != null) {
2101 currentArtifact.setArtifactGroupType(type);
2103 if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) {
2104 log.error("artifact uniqid cannot be set ignoring");
2106 artifactInfo.setUniqueId(currentArtifact.getUniqueId());
2107 if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef().equals(artifactInfo.getArtifactRef())) {
2108 log.error("artifact ref cannot be set ignoring");
2110 artifactInfo.setArtifactRef(currentArtifact.getArtifactRef());
2111 if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository().equals(artifactInfo.getArtifactRepository())) {
2112 log.error("artifact repository cannot be set ignoring");
2114 artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository());
2115 if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator().equals(artifactInfo.getUserIdCreator())) {
2116 log.error("creator uuid cannot be set ignoring");
2118 artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator());
2119 if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator().equals(artifactInfo.getArtifactCreator())) {
2120 log.error("artifact creator cannot be set ignoring");
2122 artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator());
2123 if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater().equals(artifactInfo.getUserIdLastUpdater())) {
2124 log.error("userId of last updater cannot be set ignoring");
2126 artifactInfo.setUserIdLastUpdater(user.getUserId());
2127 if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName().equals(artifactInfo.getCreatorFullName())) {
2128 log.error("creator Full name cannot be set ignoring");
2130 artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName());
2131 if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName().equals(artifactInfo.getUpdaterFullName())) {
2132 log.error("updater Full name cannot be set ignoring");
2134 String fullName = user.getFirstName() + " " + user.getLastName();
2135 artifactInfo.setUpdaterFullName(fullName);
2136 if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate().equals(artifactInfo.getCreationDate())) {
2137 log.error("Creation Date cannot be set ignoring");
2139 artifactInfo.setCreationDate(currentArtifact.getCreationDate());
2140 if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate().equals(artifactInfo.getLastUpdateDate())) {
2141 log.error("Last Update Date cannot be set ignoring");
2143 long time = System.currentTimeMillis();
2144 artifactInfo.setLastUpdateDate(time);
2145 if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) {
2146 log.error("es id cannot be set ignoring");
2148 artifactInfo.setEsId(currentArtifact.getUniqueId());
2149 if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName()
2150 .equals(artifactInfo.getArtifactDisplayName())) {
2151 log.error(" Artifact Display Name cannot be set ignoring");
2153 artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName());
2154 if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi().equals(artifactInfo.getServiceApi())) {
2155 log.debug("serviceApi cannot be set. ignoring.");
2157 artifactInfo.setServiceApi(currentArtifact.getServiceApi());
2158 if (artifactInfo.getArtifactGroupType() != null && currentArtifact.getArtifactGroupType() != artifactInfo.getArtifactGroupType()) {
2159 log.debug("artifact group cannot be set. ignoring.");
2161 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2162 artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion());
2163 if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID().isEmpty() && !currentArtifact.getArtifactUUID()
2164 .equals(artifactInfo.getArtifactUUID())) {
2165 log.debug("artifact UUID cannot be set. ignoring.");
2167 artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID());
2168 if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo.getHeatParameters().isEmpty()
2169 && !currentArtifact.getHeatParameters().isEmpty()) {
2170 checkAndSetUnupdatableHeatParams(artifactInfo.getListHeatParameters(), currentArtifact.getListHeatParameters());
2174 private void checkAndSetUnupdatableHeatParams(List<HeatParameterDefinition> heatParameters, List<HeatParameterDefinition> currentParameters) {
2175 Map<String, HeatParameterDefinition> currentParametersMap = getMapOfParameters(currentParameters);
2176 for (HeatParameterDefinition parameter : heatParameters) {
2177 HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId());
2178 if (currentParam != null) {
2179 if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) {
2180 log.debug("heat parameter name cannot be updated ({}). ignoring.", parameter.getName());
2181 parameter.setName(currentParam.getName());
2183 if (parameter.getDefaultValue() != null && !parameter.getDefaultValue().equalsIgnoreCase(currentParam.getDefaultValue())) {
2184 log.debug("heat parameter defaultValue cannot be updated ({}). ignoring.", parameter.getDefaultValue());
2185 parameter.setDefaultValue(currentParam.getDefaultValue());
2187 if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) {
2188 log.debug("heat parameter type cannot be updated ({}). ignoring.", parameter.getType());
2189 parameter.setType(currentParam.getType());
2191 if (parameter.getDescription() != null && !parameter.getDescription().equalsIgnoreCase(currentParam.getDescription())) {
2192 log.debug("heat parameter description cannot be updated ({}). ignoring.", parameter.getDescription());
2193 parameter.setDescription(currentParam.getDescription());
2195 // check and set current value
2196 if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) {
2197 log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue());
2198 parameter.setCurrentValue(currentParam.getDefaultValue());
2204 private Map<String, HeatParameterDefinition> getMapOfParameters(List<HeatParameterDefinition> currentParameters) {
2205 Map<String, HeatParameterDefinition> currentParamsMap = new HashMap<>();
2206 for (HeatParameterDefinition param : currentParameters) {
2207 currentParamsMap.put(param.getUniqueId(), param);
2209 return currentParamsMap;
2212 private Either<Boolean, ResponseFormat> validateAndServiceApiUrl(ArtifactDefinition artifactInfo) {
2213 if (!ValidationUtils.validateStringNotEmpty(artifactInfo.getApiUrl())) {
2214 log.debug("Artifact url cannot be empty.");
2215 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL));
2217 artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase());
2218 if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) {
2219 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL));
2221 if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) {
2223 .right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH)));
2225 return Either.left(true);
2228 private Either<Boolean, ResponseFormat> validateAndCleanDescription(ArtifactDefinition artifactInfo) {
2229 if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) {
2230 log.debug("Artifact description cannot be empty.");
2231 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION));
2233 String description = artifactInfo.getDescription();
2234 description = ValidationUtils.removeNoneUtf8Chars(description);
2235 description = ValidationUtils.normaliseWhitespace(description);
2236 description = ValidationUtils.stripOctets(description);
2237 description = ValidationUtils.removeHtmlTagsOnly(description);
2238 if (!ValidationUtils.validateIsEnglish(description)) {
2239 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2241 if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) {
2242 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION,
2243 String.valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)));
2245 artifactInfo.setDescription(description);
2246 return Either.left(true);
2249 private <T> Either<ArtifactDefinition, T> updateArtifactFlow(Component parent, String parentId, String artifactId,
2250 ArtifactDefinition artifactInfo, byte[] decodedPayload,
2251 ComponentTypeEnum componentType, AuditingActionEnum auditingAction) {
2252 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
2253 if (artifactData == null) {
2254 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2255 log.debug("Failed to create artifact object for ES.");
2256 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
2258 log.debug("Entry on graph is updated. Update artifact in ES");
2259 // Changing previous and current artifactId for auditing
2260 String currArtifactId = artifactInfo.getUniqueId();
2261 NodeTypeEnum parentType = convertParentType(componentType);
2262 if (decodedPayload == null) {
2263 if (!artifactInfo.getMandatory() || artifactInfo.getEsId() != null) {
2264 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactInfo.getEsId());
2265 if (artifactFromCassandra.isRight()) {
2266 throw new StorageException(artifactFromCassandra.right().value());
2268 // clone data to new artifact
2269 artifactData.setData(artifactFromCassandra.left().value().getData());
2270 artifactData.setId(artifactFromCassandra.left().value().getId());
2272 } else if (artifactInfo.getEsId() == null) {
2273 artifactInfo.setEsId(artifactInfo.getUniqueId());
2274 artifactData.setId(artifactInfo.getUniqueId());
2276 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
2277 .updateArtifactOnResource(artifactInfo, parent, artifactId, parentType, parentId, true);
2278 if (result.isRight()) {
2279 throw new StorageException(result.right().value());
2281 ArtifactDefinition artifactDefinition = result.left().value();
2282 updateGeneratedIdInHeatEnv(parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType);
2283 StorageOperationStatus storageOperationStatus = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
2284 if (storageOperationStatus != StorageOperationStatus.OK) {
2285 throw new StorageException(storageOperationStatus);
2287 if (artifactData.getData() != null) {
2288 if (!artifactDefinition.getDuplicated() || artifactData.getId() == null) {
2289 artifactData.setId(artifactDefinition.getEsId());
2291 saveArtifactInCassandra(artifactData, parent, artifactInfo, currArtifactId, artifactId, auditingAction, componentType);
2293 return Either.left(artifactDefinition);
2296 private String updateGeneratedIdInHeatEnv(Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo,
2297 ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2298 if (NodeTypeEnum.Resource == parentType) {
2299 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parent, parentId, artifactId, artifactInfo, artifactDefinition,
2302 return artifactDefinition.getUniqueId();
2305 private String updateGeneratedIdInHeatEnv(Map<String, ArtifactDefinition> deploymentArtifacts, Component parentComponent, String parentId,
2306 String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2307 NodeTypeEnum parentType, boolean isInstanceArtifact) {
2308 String artifactUniqueId;
2309 artifactUniqueId = artifactDefinition.getUniqueId();
2310 String artifactType = artifactInfo.getArtifactType();
2311 if ((ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType)
2312 || ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType)) && !artifactUniqueId.equals(artifactId)) {
2313 // need to update the generated id in heat env
2314 Optional<Entry<String, ArtifactDefinition>> findFirst = deploymentArtifacts.entrySet().stream()
2315 .filter(a -> artifactId.equals(a.getValue().getGeneratedFromId())).findFirst();
2316 if (findFirst.isPresent()) {
2317 ArtifactDefinition artifactEnvInfo = findFirst.get().getValue();
2318 artifactEnvInfo.setIsFromCsar(artifactDefinition.getIsFromCsar());
2319 artifactEnvInfo.setArtifactChecksum(null);
2320 if (isInstanceArtifact) {
2321 artifactToscaOperation
2322 .updateHeatEnvArtifactOnInstance(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2324 artifactToscaOperation
2325 .updateHeatEnvArtifact(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2329 return artifactUniqueId;
2332 private String updateGeneratedIdInHeatEnvOnInstance(ComponentInstance parent, Component parentComponent, String artifactId,
2333 ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2334 NodeTypeEnum parentType) {
2335 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parentComponent, parent.getUniqueId(), artifactId, artifactInfo,
2336 artifactDefinition, parentType, true);
2340 private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) {
2341 log.trace("Starting payload handling");
2342 byte[] payload = artifactInfo.getPayloadData();
2343 byte[] decodedPayload = null;
2344 if (payload != null && payload.length != 0) {
2345 // the generated artifacts were already decoded by the handler
2346 decodedPayload = artifactInfo.getGenerated() ? payload : Base64.decodeBase64(payload);
2347 if (decodedPayload.length == 0) {
2348 log.debug("Failed to decode the payload.");
2349 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
2350 return Either.right(responseFormat);
2352 String checkSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(decodedPayload);
2353 artifactInfo.setArtifactChecksum(checkSum);
2354 log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum);
2355 // Specific payload validations of different types
2356 Either<Boolean, ResponseFormat> result = Either.left(true);
2357 if (isDeploymentArtifact(artifactInfo)) {
2358 log.trace("Starting deployment artifacts payload validation");
2359 String artifactType = artifactInfo.getArtifactType();
2360 String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName());
2361 PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension);
2362 final Optional<ResponseFormat> pmDictionaryError = validateIfPmDictionary(artifactType, decodedPayload);
2363 if (pmDictionaryError.isPresent()) {
2364 return Either.right(pmDictionaryError.get());
2366 Either<Boolean, ActionStatus> isPayloadValid = payloadType.isValid(decodedPayload);
2367 if (isPayloadValid.isRight()) {
2368 ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType);
2369 return Either.right(responseFormat);
2371 if (payloadType.isHeatRelated()) {
2372 log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType);
2373 result = extractHeatParameters(artifactInfo);
2376 if (result.isRight()) {
2377 return Either.right(result.right().value());
2379 } // null/empty payload is normal if called from metadata update ONLY.
2381 // The validation of whether this is metadata/payload update case is
2383 // currently done separately
2385 if (!isArtifactMetadataUpdate) {
2386 log.debug("In artifact: {} Payload is missing.", artifactInfo.getArtifactName());
2387 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
2388 return Either.right(responseFormat);
2391 log.trace("Ended payload handling");
2392 return Either.left(decodedPayload);
2395 private Optional<ResponseFormat> validateIfPmDictionary(String artifactType, byte[] decodedPayload) {
2396 return new PMDictionaryValidator().validateIfPmDictionary(artifactType, decodedPayload).map(this::preparePmDictionaryResponse);
2399 private ResponseFormat preparePmDictionaryResponse(String errorMessage) {
2400 return componentsUtils.getResponseFormat(ActionStatus.INVALID_PM_DICTIONARY_FILE, errorMessage);
2403 public Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface(String resourceId, String userUserId, String artifactId,
2404 boolean inTransaction) {
2405 return toscaOperationFacade.getToscaElement(resourceId, JsonParseFlagEnum.ParseMetadata).right().map(componentsUtils.toResponseFormat())
2406 .left().bind(parentComponent -> {
2407 User user = new User(userUserId);
2408 return handleDelete(resourceId, artifactId, user, parentComponent, false, inTransaction);
2412 private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) {
2413 Operation op = new Operation();
2414 long time = System.currentTimeMillis();
2415 op.setCreationDate(time);
2416 String artifactName = artifactInfo.getArtifactName();
2417 artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName));
2418 op.setImplementation(artifactInfo);
2419 op.setLastUpdateDate(time);
2423 private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) {
2424 String newArtifactName = operationName + "_" + artifactName;
2425 log.trace("converting artifact name {} to {}", artifactName, newArtifactName);
2426 return newArtifactName;
2430 public byte[] downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion,
2431 String artifactName) {
2432 // General validation
2433 if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) {
2434 log.debug(NULL_PARAMETER);
2435 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2437 // Normalizing artifact name
2438 artifactName = ValidationUtils.normalizeFileName(artifactName);
2439 // Resource validation
2440 Resource resource = validateResourceNameAndVersion(resourceName, resourceVersion);
2441 String resourceId = resource.getUniqueId();
2442 // Service validation
2443 Service validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion);
2444 Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts();
2445 if (artifacts == null || artifacts.isEmpty()) {
2446 log.debug("Deployment artifacts of resource {} are not found", resourceId);
2447 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2449 ArtifactDefinition deploymentArtifact = null;
2450 for (ArtifactDefinition artifactDefinition : artifacts.values()) {
2451 if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName().equals(artifactName)) {
2452 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2453 deploymentArtifact = artifactDefinition;
2457 if (deploymentArtifact == null) {
2458 log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId);
2459 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2461 // Downloading the artifact
2462 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deploymentArtifact);
2463 log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId());
2464 return downloadArtifactEither.getRight();
2468 public byte[] downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) {
2469 // General validation
2470 if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) {
2471 log.debug(NULL_PARAMETER);
2472 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2474 // Normalizing artifact name
2475 artifactName = ValidationUtils.normalizeFileName(artifactName);
2476 // Service validation
2477 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2478 // ResourceInstance validation
2479 ComponentInstance resourceInstance = validateResourceInstance(service, resourceInstanceName);
2480 Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
2481 final String finalArtifactName = artifactName;
2482 Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName);
2483 ArtifactDefinition deployableArtifact =
2484 artifacts == null ? null : artifacts.values().stream().filter(filterArtifactByName).findFirst().orElse(null);
2485 if (deployableArtifact == null) {
2486 log.debug("Deployment artifact with name {} not found", artifactName);
2487 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
2489 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2490 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deployableArtifact);
2491 log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId());
2492 return downloadArtifactEither.getRight();
2495 private ComponentInstance validateResourceInstance(Service service, String resourceInstanceName) {
2496 List<ComponentInstance> riList = service.getComponentInstances();
2497 for (ComponentInstance ri : riList) {
2498 if (ri.getNormalizedName().equals(resourceInstanceName)) {
2502 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName);
2505 private ComponentInstance validateResourceInstanceById(Component component, String resourceInstanceId) {
2506 List<ComponentInstance> riList = component.getComponentInstances();
2507 for (ComponentInstance ri : riList) {
2508 if (ri.getUniqueId().equals(resourceInstanceId)) {
2512 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceInstanceId);
2515 private Service validateServiceNameAndVersion(String serviceName, String serviceVersion) {
2516 Either<List<Service>, StorageOperationStatus> serviceListBySystemName = toscaOperationFacade
2517 .getBySystemName(ComponentTypeEnum.SERVICE, serviceName);
2518 if (serviceListBySystemName.isRight()) {
2519 log.debug("Couldn't fetch any service with name {}", serviceName);
2520 throw new ByActionStatusComponentException(
2521 componentsUtils.convertFromStorageResponse(serviceListBySystemName.right().value(), ComponentTypeEnum.SERVICE), serviceName);
2523 List<Service> serviceList = serviceListBySystemName.left().value();
2524 if (serviceList == null || serviceList.isEmpty()) {
2525 log.debug("Couldn't fetch any service with name {}", serviceName);
2526 throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceName);
2528 Service foundService = null;
2529 for (Service service : serviceList) {
2530 if (service.getVersion().equals(serviceVersion)) {
2531 log.trace("Found service with version {}", serviceVersion);
2532 foundService = service;
2536 if (foundService == null) {
2537 log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName);
2538 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE.getValue(),
2541 return foundService;
2544 private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2545 Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade
2546 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2547 if (resourceListBySystemName.isRight()) {
2548 log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2549 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()),
2552 return resourceListBySystemName.left().value();
2555 public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2557 log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion,
2559 if (serviceName == null || serviceVersion == null || artifactName == null) {
2560 log.debug(NULL_PARAMETER);
2561 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2563 // Normalizing artifact name
2564 final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2565 // Service validation
2566 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2567 // Looking for deployment or tosca artifacts
2568 String serviceId = service.getUniqueId();
2569 if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2570 log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2571 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2573 Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2574 if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2575 foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2576 // filters artifact by name
2577 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2579 if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2580 foundArtifactOptl = service.getToscaArtifacts().values().stream()
2581 // filters TOSCA artifact by name
2582 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2584 if (!foundArtifactOptl.isPresent()) {
2585 log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2586 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2588 log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2589 // Downloading the artifact
2590 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl.get());
2591 log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2592 return downloadArtifactEither.getRight();
2595 public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2596 log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2597 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2598 if (artifactById.isRight()) {
2599 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2600 log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2601 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2603 ArtifactDefinition artifactDefinition = artifactById.left().value();
2604 if (artifactDefinition == null) {
2605 log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2606 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2608 return downloadArtifact(artifactDefinition);
2611 private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId,
2612 ComponentTypeEnum componentType, String containerComponentType) {
2613 ComponentTypeEnum componentForAudit =
2614 null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
2615 componentForAudit.getNodeType();
2616 Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaFullElement(componentId);
2617 if (componentResult.isRight()) {
2618 ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND
2619 : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
2620 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
2621 log.debug("Service not found, serviceId {}", componentId);
2622 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
2623 throw new ByActionStatusComponentException(status, componentId);
2625 return componentResult.left().value();
2628 private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId,
2629 ArtifactOperationInfo operation) {
2630 if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
2632 validateCanWorkOnComponent(component, userId);
2633 } catch (ComponentException e) {
2634 String uniqueId = component.getUniqueId();
2635 log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId);
2636 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(), component.getComponentType(),
2643 private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId,
2644 ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
2645 if (operation.isNotDownload()) {
2646 String role = user.getRole();
2647 if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
2648 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2649 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
2650 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2651 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
2656 private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId,
2657 ComponentTypeEnum componentType, boolean inTransaction) {
2660 user = validateUserExists(userId);
2661 } catch (ByResponseFormatComponentException e) {
2662 ResponseFormat responseFormat = e.getResponseFormat();
2663 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2665 } catch (ByActionStatusComponentException e) {
2666 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2667 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2673 private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId, ResponseFormat responseFormat,
2674 ComponentTypeEnum componentType, String userId) {
2675 User user = new User();
2676 user.setUserId(userId);
2677 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2680 protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
2681 AuditingActionEnum auditingAction = null;
2682 switch (operation.getArtifactOperationEnum()) {
2684 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
2687 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API
2688 : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
2691 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
2694 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
2699 return auditingAction;
2702 private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
2703 String esArtifactId = artifactDefinition.getEsId();
2704 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2705 if (artifactfromES.isRight()) {
2706 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2707 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2708 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
2709 log.debug("Error when getting artifact from ES, error: {}", actionStatus);
2710 throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
2712 DAOArtifactData DAOArtifactData = artifactfromES.left().value();
2713 byte[] data = DAOArtifactData.getDataAsArray();
2715 log.debug("Artifact data from cassandra is null");
2716 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
2718 String artifactName = artifactDefinition.getArtifactName();
2719 log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
2720 return new ImmutablePair<>(artifactName, data);
2723 public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
2724 return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
2727 private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo, String currArtifactId,
2728 String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
2729 CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
2730 if (resourceUploadStatus == CassandraOperationStatus.OK) {
2731 log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
2732 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
2733 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2734 componentType, null);
2736 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2737 log.info(FAILED_SAVE_ARTIFACT);
2738 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2739 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2740 componentType, null);
2741 throw new StorageException(resourceUploadStatus);
2745 private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
2746 return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
2749 private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
2750 return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
2753 private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
2754 return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
2757 private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
2758 final String artifactType = artifactInfo.getArtifactType();
2759 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
2760 if (artifactTypeEnum == null) {
2761 artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
2764 switch (artifactTypeEnum) {
2775 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap,
2776 String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
2777 User user = userBusinessLogic.getUser(userUserId, inTransaction);
2778 return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
2781 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
2782 ArtifactGroupTypeEnum groupType) {
2783 ArtifactDefinition artifactInfo = new ArtifactDefinition();
2784 String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
2785 String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
2786 String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
2787 artifactInfo.setArtifactDisplayName(artifactName);
2788 artifactInfo.setArtifactLabel(logicalName.toLowerCase());
2789 artifactInfo.setArtifactType(artifactType);
2790 artifactInfo.setDescription(artifactDescription);
2791 artifactInfo.setArtifactGroupType(groupType);
2792 nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
2793 setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
2794 return artifactInfo;
2797 private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
2798 String uniqueId = null;
2799 if (resourceId != null) {
2800 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
2801 artifactInfo.setUniqueId(uniqueId);
2803 artifactInfo.setUserIdCreator(user.getUserId());
2804 String fullName = user.getFullName();
2805 artifactInfo.setUpdaterFullName(fullName);
2806 long time = System.currentTimeMillis();
2807 artifactInfo.setCreatorFullName(fullName);
2808 artifactInfo.setCreationDate(time);
2809 artifactInfo.setLastUpdateDate(time);
2810 artifactInfo.setUserIdLastUpdater(user.getUserId());
2811 artifactInfo.setMandatory(true);
2814 public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType,
2815 ArtifactGroupTypeEnum groupType, String instanceId) {
2816 return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
2819 public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact,
2820 Component component, NodeTypeEnum parentType, String instanceId) {
2821 return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
2824 private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
2825 byte[] payload = payloadStr.getBytes();
2826 DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
2827 return Either.left(artifactData);
2831 * @param artifactDefinition
2834 public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType,
2835 Component component, String resourceInstanceName, User modifier,
2836 String instanceId, boolean shouldLock, boolean inTransaction) {
2837 String payload = generateHeatEnvPayload(artifactDefinition);
2838 String prevUUID = artifactDefinition.getArtifactUUID();
2839 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2840 return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2841 shouldLock, inTransaction).left()
2842 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2845 public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition,
2846 ComponentTypeEnum componentType, Component component,
2847 String resourceInstanceName, User modifier, boolean shouldLock,
2848 boolean inTransaction, String instanceId) {
2849 String payload = generateHeatEnvPayload(artifactDefinition);
2850 String prevUUID = artifactDefinition.getArtifactUUID();
2851 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2852 return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2853 shouldLock, inTransaction).left()
2854 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2858 Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID,
2859 ArtifactDefinition clonedBeforeGenerate,
2860 ArtifactDefinition updatedArtDef) {
2861 if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
2862 List<ComponentInstance> componentInstances = component.getComponentInstances();
2863 if (componentInstances != null) {
2864 Optional<ComponentInstance> findFirst = componentInstances.stream().filter(ci -> ci.getUniqueId().equals(instanceId)).findFirst();
2865 if (findFirst.isPresent()) {
2866 ComponentInstance relevantInst = findFirst.get();
2867 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate,
2868 relevantInst.getGroupInstances());
2869 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
2870 updatedGroupInstances.forEach(gi -> {
2871 gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
2872 gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
2874 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
2875 .updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
2876 if (status.isRight()) {
2877 log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
2878 ResponseFormat responseFormat = componentsUtils
2879 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(status.right().value()),
2880 clonedBeforeGenerate.getArtifactDisplayName());
2881 return Either.right(responseFormat);
2887 return Either.left(updatedArtDef);
2890 private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
2891 List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
2892 StringBuilder sb = new StringBuilder();
2893 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
2894 sb.append("parameters:\n");
2895 if (heatParameters != null) {
2896 heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2897 List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
2898 for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
2899 String heatValue = heatParameterDefinition.getCurrentValue();
2900 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2901 heatValue = heatParameterDefinition.getDefaultValue();
2902 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2903 empltyHeatValues.add(heatParameterDefinition);
2907 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
2911 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatValue))
2915 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ")
2916 .append(new BigDecimal(heatValue).toPlainString()).append("\n");
2918 case COMMA_DELIMITED_LIST:
2920 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatValue).append("\n");
2923 String value = heatValue;
2924 boolean starts = value.startsWith("\"");
2925 boolean ends = value.endsWith("\"");
2926 if (!(starts && ends)) {
2927 starts = value.startsWith("'");
2928 ends = value.endsWith("'");
2929 if (!(starts && ends)) {
2930 value = "\"" + value + "\"";
2933 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value);
2939 if (!empltyHeatValues.isEmpty()) {
2940 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2941 empltyHeatValues.forEach(hv -> {
2942 sb.append(" ").append(hv.getName()).append(":");
2943 HeatParameterType type = HeatParameterType.isValidType(hv.getType());
2944 if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv.getCurrentValue())
2945 || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
2946 sb.append(" \"\"").append("\n");
2948 sb.append(" ").append("\n");
2953 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
2955 return sb.toString().replace("\\\\n", "\n");
2959 * @param artifactDefinition
2963 public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2964 ComponentTypeEnum componentType, Component component,
2965 String resourceInstanceName, User modifier, String instanceId,
2966 boolean shouldLock, boolean inTransaction) {
2967 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2968 artifactDefinition::getHeatParamsUpdateDate, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2971 public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2972 ComponentTypeEnum componentType, Component component,
2973 String resourceInstanceName, User modifier,
2974 String instanceId, boolean shouldLock,
2975 boolean inTransaction) {
2976 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2977 System::currentTimeMillis, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2980 protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition,
2981 ComponentTypeEnum componentType, Component component,
2982 String resourceInstanceName, User modifier, boolean shouldLock,
2983 boolean inTransaction, Supplier<Long> payloadUpdateDateGen,
2984 Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator,
2985 String instanceId) {
2986 log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2987 if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0
2988 || artifactDefinition.getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
2989 log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2990 Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
2991 DAOArtifactData artifactData = null;
2992 if (artifactDataRes.isLeft()) {
2993 artifactData = artifactDataRes.left().value();
2995 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2996 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
2997 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
2998 resourceInstanceName);
2999 return Either.right(artifactDataRes.right().value());
3001 String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
3003 String esArtifactId = artifactDefinition.getEsId();
3004 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
3005 DAOArtifactData DAOArtifactData;
3006 if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
3007 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
3008 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3009 if (artifactfromES.isRight()) {
3010 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3011 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3012 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3013 log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
3014 return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
3016 DAOArtifactData = artifactfromES.left().value();
3017 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3019 oldCheckSum = artifactDefinition.getArtifactChecksum();
3021 Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3024 lockComponent(component, "Update Artifact - lock resource: ");
3025 } catch (ComponentException e) {
3026 handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null,
3027 artifactDefinition.getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3032 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3033 artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3034 updateArifactDefinitionStatus = artifactToscaOperation
3035 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3037 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3038 artifactDefinition.getEsId());
3039 if (updateArifactDefinitionStatus.isRight()) {
3040 ResponseFormat responseFormat = componentsUtils
3041 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3042 artifactDefinition.getArtifactDisplayName());
3043 log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3044 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3045 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3046 resourceInstanceName);
3047 return Either.right(responseFormat);
3050 artifactDefinition.getArtifactChecksum();
3051 artifactDefinition.setArtifactChecksum(newCheckSum);
3052 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3053 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3054 artifactDefinition.getEsId());
3055 updateArifactDefinitionStatus = artifactToscaOperation
3056 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3058 log.trace("Update Payload {}", artifactDefinition.getEsId());
3060 if (updateArifactDefinitionStatus.isLeft()) {
3061 artifactDefinition = updateArifactDefinitionStatus.left().value();
3062 artifactData.setId(artifactDefinition.getUniqueId());
3063 CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3064 if (saveArtifactStatus == CassandraOperationStatus.OK) {
3065 if (!inTransaction) {
3066 janusGraphDao.commit();
3068 log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3069 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3070 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3071 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3072 resourceInstanceName);
3074 if (!inTransaction) {
3075 janusGraphDao.rollback();
3077 log.info("Failed to save artifact {}.", artifactData.getId());
3078 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3079 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3080 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3081 resourceInstanceName);
3082 return Either.right(responseFormat);
3085 ResponseFormat responseFormat = componentsUtils
3086 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3087 artifactDefinition.getArtifactDisplayName());
3088 log.debug("Failed To update artifact {}", artifactData.getId());
3089 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3090 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3091 resourceInstanceName);
3092 return Either.right(responseFormat);
3096 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
3100 return Either.left(artifactDefinition);
3103 public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType,
3104 List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3106 .buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType,
3107 artifactDef.getArtifactLabel(), artifactDef.getArtifactDisplayName(), artifactDef.getDescription(), artifactDef.getPayloadData(),
3108 updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3111 public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType,
3112 ArtifactGroupTypeEnum artifactGroupType, String label, String displayName,
3113 String description, byte[] artifactContent,
3114 List<ArtifactTemplateInfo> updatedRequiredArtifacts,
3115 List<HeatParameterDefinition> heatParameters) {
3116 Map<String, Object> json = new HashMap<>();
3117 if (artifactId != null && !artifactId.isEmpty()) {
3118 json.put(Constants.ARTIFACT_ID, artifactId);
3120 json.put(Constants.ARTIFACT_NAME, artifactName);
3121 json.put(Constants.ARTIFACT_TYPE, artifactType);
3122 json.put(Constants.ARTIFACT_DESCRIPTION, description);
3123 if (artifactContent != null) {
3124 log.debug("payload is encoded. perform decode");
3125 String encodedPayload = Base64.encodeBase64String(artifactContent);
3126 json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3128 json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3129 json.put(Constants.ARTIFACT_LABEL, label);
3130 json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3131 json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3132 : updatedRequiredArtifacts.stream().filter(
3133 e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3134 .map(ArtifactTemplateInfo::getFileName).collect(Collectors.toList()));
3135 json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>() : heatParameters);
3139 public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user,
3140 Map<String, Object> json, ArtifactOperationInfo operation,
3141 ArtifactDefinition artifactInfo) {
3142 String jsonStr = gson.toJson(json);
3143 ArtifactDefinition artifactDefinitionFromJson =
3144 artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3145 String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3146 Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE,
3147 operation, artifactUniqueId, artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3148 return Either.left(uploadArtifactToService.left().value());
3151 private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo,
3152 AuditingActionEnum auditingAction, String artifactId, User user,
3153 ComponentTypeEnum componentType, Component parent, String originData,
3154 String origMd5, ArtifactOperationInfo operation) {
3155 if (origMd5 != null) {
3156 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3157 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3158 validateDeploymentArtifact(artifactInfo, parent);
3159 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3160 } else { // duplicate
3161 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3164 return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3167 private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId,
3168 ArtifactDefinition artifactInfo, User user,
3169 AuditingActionEnum auditingAction, Component parent,
3170 ComponentTypeEnum componentType, String origMd5) {
3171 Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3172 if (getRI.isRight()) {
3173 throw new ByResponseFormatComponentException(getRI.right().value());
3175 ComponentInstance ri = getRI.left().value();
3176 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3177 if (getArtifactRes.isRight()) {
3178 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3180 ArtifactDefinition currArtifact = getArtifactRes.left().value();
3181 if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType()
3182 .equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3183 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3185 List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3186 List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3188 if (origMd5 != null) {
3189 Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction,
3190 parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams,
3191 currArtifact.getArtifactName());
3192 if (uploadParamsValidationResult.isRight()) {
3193 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3195 artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3197 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo,
3198 ArtifactTypeEnum.HEAT_ENV.getType());
3199 if (validateAndConvertHeatParamers.isRight()) {
3200 throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3202 if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3203 // fill reduced heat env parameters List for updating
3204 boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3205 if (updateRequired) {
3206 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3207 currArtifact.setListHeatParameters(currentHeatEnvParams);
3208 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3209 .updateArtifactOnResource(currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3210 if (updateArtifactRes.isRight()) {
3211 log.debug("Failed to update artifact on graph - {}", artifactId);
3212 throw new StorageException(updateArtifactRes.right().value());
3214 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(),
3215 parent.getUniqueId());
3216 if (error != StorageOperationStatus.OK) {
3217 throw new StorageException(error);
3221 updateHeatMetaDataIfNeeded(componentId, user, auditingAction, componentType, parent, ri, artifactInfo);
3222 StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3223 if (error != StorageOperationStatus.OK) {
3224 throw new StorageException(error);
3226 return Either.left(currArtifact);
3229 private void updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType,
3230 Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3231 String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3232 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId,
3233 auditingAction, user);
3234 if (getArtifactRes.isRight()) {
3235 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3237 ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3238 if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3239 validateHeatMetaData(updatedHeatEnvArtifact);
3240 updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3241 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3242 .updateArtifactOnResource(heatArtifactToUpdate, parent, heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId,
3244 if (updateArtifactRes.isRight()) {
3245 log.debug("Failed to update artifact on graph - {}", heatArtifactId);
3246 throw new StorageException(updateArtifactRes.right().value());
3248 ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3249 updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition,
3250 componentType.getNodeType());
3251 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(),
3252 parent.getUniqueId());
3253 if (error != StorageOperationStatus.OK) {
3254 throw new StorageException(error);
3259 private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3260 Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3261 Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3262 Integer updateTimeout = updatedHeatEnv.getTimeout();
3263 if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3264 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3268 private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3269 // currently only timeout metadata can be updated
3270 return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3273 private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3274 // currently only timeout metadata can be updated
3275 origHeat.setTimeout(updatedHeatEnv.getTimeout());
3278 private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams,
3279 List<HeatParameterDefinition> updatedHeatEnvParams) {
3280 boolean isUpdate = false;
3281 List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3282 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3283 String paramName = heatEnvParam.getName();
3284 validateParamName(paramName, currentParamsNames);
3285 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3286 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3287 String updatedParamValue = heatEnvParam.getCurrentValue();
3288 if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3289 currHeatParam.setCurrentValue(updatedParamValue);
3298 private void validateParamName(String paramName, List<String> heatParamsNames) {
3299 if (!heatParamsNames.contains(paramName)) {
3300 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3304 private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo,
3305 AuditingActionEnum auditingAction, Component parent,
3306 ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact,
3307 boolean needToUpdateGroup) {
3308 Either<ArtifactDefinition, Operation> insideEither = null;
3309 String currentHeatId = currHeatArtifact.getUniqueId();
3310 String esArtifactId = currHeatArtifact.getEsId();
3311 Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3312 if (artifactFromES.isRight()) {
3313 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3314 throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3316 DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3317 ArtifactDefinition updatedHeatArt = currHeatArtifact;
3318 List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3319 List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3320 List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3321 if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3322 //TODO: improve complexity - currently N^2
3324 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3325 paramName = heatEnvParam.getName();
3326 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3327 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3328 String updatedParamValue = heatEnvParam.getCurrentValue();
3329 if (updatedParamValue == null) {
3330 updatedParamValue = heatEnvParam.getDefaultValue();
3332 HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3333 if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3334 throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE, ArtifactTypeEnum.HEAT_ENV.getType(),
3335 paramType.getType(), paramName);
3337 currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3338 newHeatEnvParams.add(currHeatParam);
3343 if (!newHeatEnvParams.isEmpty()) {
3344 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3345 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation
3346 .updateArtifactOnResource(currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId,
3348 if (operationStatus.isRight()) {
3349 log.debug("Failed to update artifact on graph - {}", currHeatArtifact.getUniqueId());
3350 throw new StorageException(operationStatus.right().value());
3352 updatedHeatArt = operationStatus.left().value();
3353 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3354 DAOArtifactData.setId(updatedHeatArt.getEsId());
3356 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), auditingAction,
3358 insideEither = Either.left(updatedHeatArt);
3361 Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3362 if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3363 artifactEnvInfo.setArtifactChecksum(null);
3364 updateHeatEnvArtifact = artifactToscaOperation
3365 .updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), componentType.getNodeType(),
3368 //TODO Andrey check if componentId = parent.getUniqeId
3369 updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType.getNodeType());
3371 if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3372 ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo, updateHeatEnvArtifact.left().value(), parent);
3373 if (result != ActionStatus.OK) {
3374 throw new ByActionStatusComponentException(result);
3377 if (updatedHeatEnvParams.isEmpty()) {
3378 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3380 return insideEither;
3383 private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3384 StorageOperationStatus error = StorageOperationStatus.OK;
3385 log.debug("Need to re-generate customization UUID for group instance on component instance {}", ri.getUniqueId());
3386 List<GroupInstance> groupsInstances = ri.getGroupInstances();
3387 List<String> groupInstancesId = null;
3388 if (groupsInstances != null && !groupsInstances.isEmpty()) {
3389 groupInstancesId = groupsInstances.stream()
3390 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(artifactId))
3391 .map(GroupInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
3393 if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3394 toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3399 public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent,
3400 User user, ArtifactDefinition artifactInfo,
3401 String artifactId, ComponentTypeEnum componentType,
3403 List<HeatParameterDefinition> currentHeatEnvParams,
3404 List<HeatParameterDefinition> updatedHeatEnvParams,
3405 String currArtifactName) {
3406 if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3407 ResponseFormat responseFormat = componentsUtils
3408 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName);
3409 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3410 return Either.right(responseFormat);
3412 for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3413 String paramName = uploadedHeatParam.getName();
3414 boolean isExistsInHeat = false;
3415 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3416 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3417 isExistsInHeat = true;
3418 uploadedHeatParam.setType(currHeatParam.getType());
3419 uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3420 uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3421 uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3425 if (!isExistsInHeat) {
3426 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3427 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType,
3429 return Either.right(responseFormat);
3432 return Either.left(updatedHeatEnvParams);
3435 private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId,
3436 AuditingActionEnum auditingAction, User user) {
3437 ResponseFormat responseFormat = null;
3438 List<ComponentInstance> ris = component.getComponentInstances();
3439 for (ComponentInstance ri : ris) {
3440 if (riID.equals(ri.getUniqueId())) {
3441 return Either.left(ri);
3444 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3445 log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3446 handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3447 return Either.right(responseFormat);
3450 private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId,
3451 AuditingActionEnum auditingAction, User user) {
3452 ResponseFormat responseFormat = null;
3453 Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3454 for (ArtifactDefinition artifact : rtifactsMap.values()) {
3455 if (artifactId.equals(artifact.getUniqueId())) {
3456 return Either.left(artifact);
3459 responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3460 handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3462 return Either.right(responseFormat);
3465 public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3466 ArtifactDefinition ret;
3467 if (eitherArtifact.isLeft()) {
3468 ret = eitherArtifact.left().value();
3470 ret = eitherArtifact.right().value().getImplementationArtifact();
3475 public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
3476 ResourceCommonInfo resourceCommonInfo) {
3477 Component component = getComponentByUuid(componentType, componentUuid);
3478 resourceCommonInfo.setResourceName(component.getName());
3479 return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3483 * downloads an artifact of resource instance of component by UUIDs
3485 * @param componentType
3486 * @param componentUuid
3487 * @param resourceInstanceName
3488 * @param artifactUUID
3491 public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
3492 String artifactUUID) {
3493 ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3494 if (resourceInstance != null) {
3495 return downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, resourceInstance.getName());
3497 return downloadArtifact(null, artifactUUID, null);
3502 * uploads an artifact to a component by UUID
3506 * @param componentType
3507 * @param componentUuid
3508 * @param resourceCommonInfo
3512 public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3513 String componentUuid, ResourceCommonInfo resourceCommonInfo,
3514 ArtifactOperationInfo operation) {
3515 Either<ArtifactDefinition, Operation> actionResult;
3516 Component component;
3518 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3519 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3520 String userId = request.getHeader(Constants.USER_ID_HEADER);
3521 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3522 ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3523 componentId = componentMetadataDataDefinition.getUniqueId();
3524 String componentName = componentMetadataDataDefinition.getName();
3525 if (!componentMetadataDataDefinition.getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3526 component = checkoutParentComponent(componentType, componentId, userId);
3527 if (component != null) {
3528 componentId = component.getUniqueId();
3529 componentName = component.getName();
3532 resourceCommonInfo.setResourceName(componentName);
3533 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null,
3535 return actionResult.left().value();
3539 * upload an artifact to a resource instance by UUID
3543 * @param componentType
3544 * @param componentUuid
3545 * @param resourceInstanceName
3549 public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3550 String resourceInstanceName, ArtifactOperationInfo operation) {
3551 Either<ArtifactDefinition, Operation> actionResult;
3552 Component component = null;
3553 String componentInstanceId;
3555 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3556 String userId = request.getHeader(Constants.USER_ID_HEADER);
3557 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3558 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid,
3559 resourceInstanceName);
3560 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3561 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3563 if (component == null) {
3564 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3566 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3568 componentInstanceId = componentRiPair.getRight().getUniqueId();
3569 componentId = componentRiPair.getLeft().getUniqueId();
3570 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3571 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5,
3572 data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3573 return actionResult.left().value();
3577 * updates an artifact on a component by UUID
3581 * @param componentType
3582 * @param componentUuid
3583 * @param artifactUUID
3584 * @param resourceCommonInfo
3585 * @param operation TODO
3588 public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3589 String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3590 ArtifactOperationInfo operation) {
3591 Either<ArtifactDefinition, Operation> actionResult;
3592 Component component;
3595 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3596 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3597 String userId = request.getHeader(Constants.USER_ID_HEADER);
3598 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3599 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3600 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3601 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3602 component = checkoutParentComponent(componentType, componentId, userId);
3603 if (component != null) {
3604 componentId = component.getUniqueId();
3605 componentName = component.getName();
3608 resourceCommonInfo.setResourceName(componentName);
3609 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3610 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null,
3612 if (actionResult.isRight()) {
3613 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult.right().value());
3615 return actionResult.left().value();
3619 * updates an artifact on a resource instance by UUID
3623 * @param componentType
3624 * @param componentUuid
3625 * @param resourceInstanceName
3626 * @param artifactUUID
3627 * @param operation TODO
3630 public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3631 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3632 Either<ArtifactDefinition, Operation> actionResult;
3633 Component component = null;
3634 String componentInstanceId;
3637 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3638 String userId = request.getHeader(Constants.USER_ID_HEADER);
3639 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3640 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3641 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3642 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3644 if (component == null) {
3645 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3647 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3649 componentInstanceId = componentRiPair.getRight().getUniqueId();
3650 componentId = componentRiPair.getLeft().getUniqueId();
3651 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3652 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3653 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo,
3654 origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3655 return actionResult.left().value();
3658 private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid,
3659 ArtifactDefinition artifactInfo) {
3660 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3661 if (componentStorageOperationStatusEither.isRight()) {
3662 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3663 log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
3664 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3666 Component storedComponent = componentStorageOperationStatusEither.left().value();
3667 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3668 .getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
3669 if (!optionalInterface.isPresent()) {
3670 log.debug("Failed to get resource interface for resource Id {}", componentId);
3671 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
3673 //fetch the operation from storage
3674 InterfaceDefinition gotInterface = optionalInterface.get();
3675 Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
3676 Optional<Operation> optionalOperation = operationsMap.values().stream().filter(o -> o.getUniqueId().equals(operationUuid)).findFirst();
3677 if (!optionalOperation.isPresent()) {
3678 log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
3679 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
3680 return Either.right(responseFormat);
3682 Operation operation = optionalOperation.get();
3683 ArtifactDefinition implementationArtifact = operation.getImplementationArtifact();
3684 implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
3685 implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
3686 implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
3687 implementationArtifact.setDescription(artifactInfo.getDescription());
3688 implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
3689 implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
3690 implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
3691 implementationArtifact.setEsId(artifactInfo.getEsId());
3692 operation.setImplementation(implementationArtifact);
3693 gotInterface.setOperationsMap(operationsMap);
3694 Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = interfaceOperation
3695 .updateInterfaces(storedComponent, Collections.singletonList(gotInterface));
3696 if (interfaceDefinitionStorageOperationStatusEither.isRight()) {
3697 StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
3698 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
3699 return Either.right(componentsUtils.getResponseFormat(actionStatus));
3701 return Either.left(artifactInfo);
3705 * updates an artifact on a component by UUID
3709 * @param componentType
3710 * @param componentUuid
3711 * @param artifactUUID
3715 public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(String data, HttpServletRequest request,
3716 ComponentTypeEnum componentType,
3717 String componentUuid, String interfaceUUID,
3718 String operationUUID, String artifactUUID,
3719 ResourceCommonInfo resourceCommonInfo,
3720 ArtifactOperationInfo operation) {
3721 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
3722 Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
3723 String componentId = null;
3724 ArtifactDefinition existingArtifactInfo = null;
3725 String interfaceName = null;
3726 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3727 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3728 String userId = request.getHeader(Constants.USER_ID_HEADER);
3729 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3730 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(as));
3733 if (errorWrapper.isEmpty()) {
3734 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3735 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3736 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3737 Component component = checkoutParentComponent(componentType, componentId, userId);
3738 if (component != null) {
3739 componentId = component.getUniqueId();
3740 componentName = component.getName();
3743 resourceCommonInfo.setResourceName(componentName);
3745 if (errorWrapper.isEmpty()) {
3746 Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
3747 if (interfaceNameEither.isRight()) {
3748 errorWrapper.setInnerElement(interfaceNameEither.right().value());
3750 interfaceName = interfaceNameEither.left().value();
3752 if (errorWrapper.isEmpty()) {
3753 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
3754 if (toscaComponentEither.isRight()) {
3755 StorageOperationStatus status = toscaComponentEither.right().value();
3756 log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
3757 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
3759 if (errorWrapper.isEmpty()) {
3760 NodeTypeEnum parentType = convertParentType(componentType);
3761 final List<ArtifactDefinition> existingDeploymentArtifacts = getDeploymentArtifacts(toscaComponentEither.left().value(), null);
3762 for (ArtifactDefinition artifactDefinition : existingDeploymentArtifacts) {
3763 if (artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())) {
3764 existingArtifactInfo = artifactDefinition;
3768 if (existingArtifactInfo != null) {
3769 return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
3774 if (errorWrapper.isEmpty()) {
3775 updateArtifactResult = handleArtifactRequestAndFlatten(componentId, userId, componentType, operation, artifactUUID, artifactInfo, origMd5,
3776 data, interfaceName, operationUUID);
3778 updateArtifactResult = Either.right(errorWrapper.getInnerElement());
3780 return updateArtifactResult;
3783 private Either<ArtifactDefinition, ResponseFormat> handleArtifactRequestAndFlatten(String componentId, String userId,
3784 ComponentTypeEnum componentType,
3785 ArtifactOperationInfo operation, String artifactId,
3786 ArtifactDefinition artifactInfo, String origMd5,
3787 String originData, String interfaceName,
3788 String operationName) {
3790 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
3791 operationName, null, null).right().map(op -> {
3792 log.debug("Unexpected value returned while calling handleArtifactRequest: {}", op);
3793 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3795 } catch (ComponentException e) {
3796 return Either.right(e.getResponseFormat());
3800 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid) {
3801 return fetchLatestComponentMetadataOrThrow(componentType, componentUuid, componentUuid);
3804 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid,
3805 String resourceInstanceName) {
3806 return fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3807 throw new ByActionStatusComponentException(as, resourceInstanceName);
3811 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadata(ComponentTypeEnum componentType, String componentUuid) {
3812 return toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true).right().map(sos -> {
3813 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, sos);
3814 return componentsUtils.convertFromStorageResponse(sos, componentType);
3818 private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
3819 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3820 if (componentStorageOperationStatusEither.isRight()) {
3821 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3822 log.debug("Failed to fetch component information by component id, error {}", errorStatus);
3823 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3825 Component storedComponent = componentStorageOperationStatusEither.left().value();
3826 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3827 .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
3828 if (!optionalInterface.isPresent()) {
3829 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
3831 return Either.left(optionalInterface.get().getType());
3835 * deletes an artifact on a component by UUID
3838 * @param componentType
3839 * @param componentUuid
3840 * @param artifactUUID
3841 * @param resourceCommonInfo
3842 * @param operation TODO
3845 public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3846 String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3847 ArtifactOperationInfo operation) {
3848 Either<ArtifactDefinition, Operation> actionResult;
3849 Component component;
3852 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3853 String userId = request.getHeader(Constants.USER_ID_HEADER);
3854 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3855 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3856 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3857 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3858 component = checkoutParentComponent(componentType, componentId, userId);
3859 if (component != null) {
3860 componentId = component.getUniqueId();
3861 componentName = component.getName();
3864 resourceCommonInfo.setResourceName(componentName);
3865 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3866 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
3867 return actionResult.left().value();
3871 * deletes an artifact from a resource instance by UUID
3874 * @param componentType
3875 * @param componentUuid
3876 * @param resourceInstanceName
3877 * @param artifactUUID
3878 * @param operation TODO
3881 public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3882 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3883 Either<ArtifactDefinition, Operation> actionResult;
3884 Component component = null;
3885 String componentInstanceId;
3888 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3889 String userId = request.getHeader(Constants.USER_ID_HEADER);
3890 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3891 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3892 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3893 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3895 if (component == null) {
3896 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3898 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3900 componentInstanceId = componentRiPair.getRight().getUniqueId();
3901 componentId = componentRiPair.getLeft().getUniqueId();
3902 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3903 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5,
3904 null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3905 return actionResult.left().value();
3908 private String findArtifactId(ComponentInstance instance, String artifactUUID) {
3909 String artifactId = null;
3910 ArtifactDefinition foundArtifact = null;
3911 if (instance.getDeploymentArtifacts() != null) {
3912 foundArtifact = instance.getDeploymentArtifacts().values().stream()
3913 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3915 if (foundArtifact == null && instance.getArtifacts() != null) {
3916 foundArtifact = instance.getArtifacts().values().stream()
3917 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3919 if (foundArtifact == null) {
3920 log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
3921 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
3923 artifactId = foundArtifact.getUniqueId();
3928 @SuppressWarnings("unchecked")
3929 public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact, String envType,
3930 String parentId, NodeTypeEnum parentType, String parentName, User user, Component component,
3931 Map<String, String> existingEnvVersions) {
3932 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
3933 .getDeploymentResourceInstanceArtifacts();
3934 if (deploymentResourceArtifacts == null) {
3935 log.debug("no deployment artifacts are configured for generated artifacts");
3936 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3938 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
3939 if (placeHolderData == null) {
3940 log.debug("no env type {} are configured for generated artifacts", envType);
3941 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3943 String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
3944 ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user.getUserId(),
3945 ArtifactGroupTypeEnum.DEPLOYMENT, true);
3946 ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
3947 artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
3948 artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
3949 artifactHeatEnv.setTimeout(0);
3950 artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
3951 buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
3952 // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
3953 handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
3954 ArtifactDefinition heatEnvPlaceholder;
3955 // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
3956 if (parentType != NodeTypeEnum.ResourceInstance) {
3957 String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
3958 artifactHeatEnv.setArtifactChecksum(checkSum);
3959 Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component,
3960 parentType, parentId);
3961 if (addHeatEnvArtifact.isRight()) {
3962 log.debug("failed to create heat env artifact on resource instance");
3963 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(
3964 componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact.right().value(), false), "", null));
3966 heatEnvPlaceholder = createArtifactPlaceHolder;
3968 heatEnvPlaceholder = artifactHeatEnv;
3969 artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
3970 setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
3972 ComponentTypeEnum componentType = component.getComponentType();
3973 if (parentType == NodeTypeEnum.ResourceInstance) {
3974 componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
3976 createdArtifacts.add(heatEnvPlaceholder);
3977 componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
3978 new ResourceCommonInfo(parentName, componentType.getValue()), ResourceVersionInfo.newBuilder().build(),
3979 ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(), null, heatEnvPlaceholder, null);
3980 return heatEnvPlaceholder;
3983 private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
3984 if (artifact.getListHeatParameters() == null) {
3987 List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
3988 for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
3989 HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
3990 heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
3991 heatEnvParameter.setCurrentValue(null);
3992 heatEnvParameters.add(heatEnvParameter);
3994 artifactDefinition.setListHeatParameters(heatEnvParameters);
3997 private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
3998 String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
3999 String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
4000 String name = heatArtifact.getArtifactName();
4003 name = heatArtifact.getArtifactLabel();
4004 fileName = name + "." + envExtension;
4006 fileName = name.replaceAll("." + heatExtension, "." + envExtension);
4008 heatEnvArtifact.setArtifactName(fileName);
4011 private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
4012 if (null != existingEnvVersions) {
4013 String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
4014 if (null != prevVersion) {
4015 heatEnvArtifact.setArtifactVersion(prevVersion);
4020 public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user,
4021 List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4022 ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4023 ComponentTypeEnum componentType = component.getComponentType();
4024 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4025 Either<ArtifactDefinition, Operation> result;
4027 for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4028 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4029 uploadedArtifacts.add(result.left().value());
4031 } catch (ComponentException e) {
4032 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component.getName(), e.getResponseFormat());
4033 if (operation.isCreateOrLink()) {
4034 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4038 return uploadedArtifacts;
4041 public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Component component, User user, ArtifactOperationInfo operation,
4042 boolean shouldLock, boolean inTransaction, ComponentTypeEnum componentType,
4043 ArtifactDefinition artifactDefinition) {
4044 AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4045 String componentId = component.getUniqueId();
4046 String artifactId = artifactDefinition.getUniqueId();
4047 Either<ArtifactDefinition, Operation> result;
4048 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4049 //artifact validation
4050 artifactDefinition = validateArtifact(componentId, componentType, operation, artifactId, artifactDefinition, auditingAction, user, component,
4051 shouldLock, inTransaction);
4052 switch (operation.getArtifactOperationEnum()) {
4054 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType,
4055 component, null, null);
4056 result = createArtifact(component, componentId, artifactDefinition, validPayload, componentType, auditingAction, null, null);
4059 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component,
4061 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4062 auditingAction, user, component, true);
4065 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4068 if (artifactGenerationRequired(component, artifactDefinition)) {
4069 result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4071 result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4075 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4078 throw new UnsupportedOperationException(
4079 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4084 public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component,
4085 User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4086 ArtifactOperationInfo operation, boolean shouldLock,
4087 boolean inTransaction) {
4088 List<ArtifactDefinition> handleArtifactsResult;
4089 ComponentTypeEnum componentType = component.getComponentType();
4090 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4091 Either<ArtifactDefinition, Operation> actionResult;
4095 for (ArtifactDefinition artifact : artifactsToHandle) {
4096 originData = ArtifactUtils.buildJsonStringForCsarVfcArtifact(artifact);
4097 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4098 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact.getUniqueId(),
4099 artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4100 uploadedArtifacts.add(actionResult.left().value());
4102 handleArtifactsResult = uploadedArtifacts;
4103 } catch (ComponentException e) {
4104 if (operation.isCreateOrLink()) {
4105 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4109 return handleArtifactsResult;
4112 private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName) {
4113 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4114 Option<Component> oComponent = Option.of(getComponentByUuid(componentType, componentUuid));
4115 return oComponent.toTry(componentNotFound(componentType, componentUuid)).flatMap(
4116 component -> findFirstMatching(component, ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4117 .toTry(componentInstanceNotFound(componentType, resourceInstanceName, component))).get();
4120 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName) {
4121 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4122 ComponentInstance componentInstance = findFirstMatching(component,
4123 ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4124 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4125 return new ImmutablePair<>(component, componentInstance);
4128 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid,
4129 String resourceInstanceName) {
4130 Component component = getLatestComponentByUuid(componentType, componentUuid);
4131 ComponentInstance componentInstance = findFirstMatching(component, ci -> ci.getNormalizedName().equals(resourceInstanceName))
4132 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4133 return new ImmutablePair<>(component, componentInstance);
4136 private Supplier<Throwable> componentNotFound(ComponentTypeEnum componentType, String componentUuid) {
4138 log.debug(FAILED_FETCH_COMPONENT, componentType.getValue(), componentUuid);
4139 return new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentUuid);
4143 private Supplier<Throwable> componentInstanceNotFound(ComponentTypeEnum componentType, String resourceInstanceName, Component component) {
4145 log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4146 return new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4147 RESOURCE_INSTANCE, componentType.getValue(), component.getName());
4151 private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4152 ImmutablePair<String, byte[]> downloadArtifact;
4153 List<ArtifactDefinition> artifactsList = null;
4154 ArtifactDefinition deploymentArtifact;
4155 if (artifacts != null && !artifacts.isEmpty()) {
4156 artifactsList = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID))
4157 .collect(Collectors.toList());
4159 if (artifactsList == null || artifactsList.isEmpty()) {
4160 log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4161 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4163 deploymentArtifact = artifactsList.get(0);
4164 downloadArtifact = downloadArtifact(deploymentArtifact);
4165 log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4166 return downloadArtifact.getRight();
4169 private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4170 Component component;
4171 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4172 if (getComponentRes.isRight()) {
4173 StorageOperationStatus status = getComponentRes.right().value();
4174 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4175 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4177 component = getComponentRes.left().value();
4182 private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4183 Component component;
4184 Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4185 if (getComponentRes.isRight()) {
4186 StorageOperationStatus status = getComponentRes.right().value();
4187 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4188 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4190 List<Component> value = getComponentRes.left().value();
4191 if (value.isEmpty()) {
4192 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4193 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4194 throw new ByActionStatusComponentException(status);
4196 component = value.get(0);
4202 private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4203 ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4204 StorageOperationStatus storageStatus;
4205 ArtifactDefinition latestArtifact;
4206 List<ArtifactDefinition> artifacts;
4207 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4208 if (getArtifactsRes.isRight()) {
4209 storageStatus = getArtifactsRes.right().value();
4210 log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4211 if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4212 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4214 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4216 artifacts = getArtifactsRes.left().value().values().stream()
4217 .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList());
4218 if (artifacts == null || artifacts.isEmpty()) {
4219 log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4220 parentId, actionStatus);
4221 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4223 latestArtifact = artifacts.stream().max((a1, a2) -> {
4224 int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4225 if (compareRes == 0) {
4226 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(),
4227 a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate());
4231 if (latestArtifact == null) {
4232 log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4233 parentId, actionStatus);
4234 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4236 return latestArtifact.getUniqueId();
4239 private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4240 Component component = null;
4241 User modifier = userBusinessLogic.getUser(userId, false);
4242 LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout",
4243 LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4244 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
4245 .changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4246 if (checkoutRes.isRight()) {
4247 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId,
4248 checkoutRes.right().value().getStatus());
4249 throw new ByResponseFormatComponentException(checkoutRes.right().value());
4251 return checkoutRes.left().value();
4255 void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4256 this.nodeTemplateOperation = nodeTemplateOperation;
4259 public List<ArtifactConfiguration> getConfiguration() {
4260 return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
4263 public enum ArtifactOperationEnum {
4264 CREATE, UPDATE, DELETE, DOWNLOAD, LINK;
4266 public static boolean isCreateOrLink(ArtifactOperationEnum operation) {
4267 return operation == CREATE || operation == LINK;