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 (StringUtils.isEmpty(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 final Either<Service, StorageOperationStatus> serviceBySystemNameAndVersion
2517 = toscaOperationFacade.getBySystemNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
2518 if (serviceBySystemNameAndVersion.isRight()) {
2519 log.debug("Couldn't fetch any service with name {}", serviceName);
2520 throw new ByActionStatusComponentException(
2521 componentsUtils.convertFromStorageResponse(serviceBySystemNameAndVersion.right().value(), ComponentTypeEnum.SERVICE), serviceName);
2523 return serviceBySystemNameAndVersion.left().value();
2526 private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2527 Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade
2528 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2529 if (resourceListBySystemName.isRight()) {
2530 log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2531 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()),
2534 return resourceListBySystemName.left().value();
2537 public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2539 log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion,
2541 if (serviceName == null || serviceVersion == null || artifactName == null) {
2542 log.debug(NULL_PARAMETER);
2543 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2545 // Normalizing artifact name
2546 final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2547 // Service validation
2548 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2549 // Looking for deployment or tosca artifacts
2550 String serviceId = service.getUniqueId();
2551 if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2552 log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2553 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2555 Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2556 if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2557 foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2558 // filters artifact by name
2559 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2561 if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2562 foundArtifactOptl = service.getToscaArtifacts().values().stream()
2563 // filters TOSCA artifact by name
2564 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2566 if (!foundArtifactOptl.isPresent()) {
2567 log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2568 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2570 log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2571 // Downloading the artifact
2572 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl.get());
2573 log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2574 return downloadArtifactEither.getRight();
2577 public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2578 log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2579 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2580 if (artifactById.isRight()) {
2581 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2582 log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2583 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2585 ArtifactDefinition artifactDefinition = artifactById.left().value();
2586 if (artifactDefinition == null) {
2587 log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2588 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2590 return downloadArtifact(artifactDefinition);
2593 private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId,
2594 ComponentTypeEnum componentType, String containerComponentType) {
2595 ComponentTypeEnum componentForAudit =
2596 null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
2597 componentForAudit.getNodeType();
2598 Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaFullElement(componentId);
2599 if (componentResult.isRight()) {
2600 ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND
2601 : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
2602 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
2603 log.debug("Service not found, serviceId {}", componentId);
2604 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
2605 throw new ByActionStatusComponentException(status, componentId);
2607 return componentResult.left().value();
2610 private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId,
2611 ArtifactOperationInfo operation) {
2612 if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
2614 validateCanWorkOnComponent(component, userId);
2615 } catch (ComponentException e) {
2616 String uniqueId = component.getUniqueId();
2617 log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId);
2618 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(), component.getComponentType(),
2625 private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId,
2626 ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
2627 if (operation.isNotDownload()) {
2628 String role = user.getRole();
2629 if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
2630 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2631 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
2632 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2633 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
2638 private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId,
2639 ComponentTypeEnum componentType, boolean inTransaction) {
2642 user = validateUserExists(userId);
2643 } catch (ByResponseFormatComponentException e) {
2644 ResponseFormat responseFormat = e.getResponseFormat();
2645 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2647 } catch (ByActionStatusComponentException e) {
2648 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2649 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2655 private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId, ResponseFormat responseFormat,
2656 ComponentTypeEnum componentType, String userId) {
2657 User user = new User();
2658 user.setUserId(userId);
2659 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2662 protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
2663 AuditingActionEnum auditingAction = null;
2664 switch (operation.getArtifactOperationEnum()) {
2666 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
2669 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API
2670 : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
2673 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
2676 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
2681 return auditingAction;
2684 private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
2685 String esArtifactId = artifactDefinition.getEsId();
2686 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2687 if (artifactfromES.isRight()) {
2688 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2689 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2690 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
2691 log.debug("Error when getting artifact from ES, error: {}", actionStatus);
2692 throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
2694 DAOArtifactData DAOArtifactData = artifactfromES.left().value();
2695 byte[] data = DAOArtifactData.getDataAsArray();
2697 log.debug("Artifact data from cassandra is null");
2698 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
2700 String artifactName = artifactDefinition.getArtifactName();
2701 log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
2702 return new ImmutablePair<>(artifactName, data);
2705 public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
2706 return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
2709 private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo, String currArtifactId,
2710 String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
2711 CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
2712 if (resourceUploadStatus == CassandraOperationStatus.OK) {
2713 log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
2714 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
2715 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2716 componentType, null);
2718 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2719 log.info(FAILED_SAVE_ARTIFACT);
2720 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2721 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2722 componentType, null);
2723 throw new StorageException(resourceUploadStatus);
2727 private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
2728 return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
2731 private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
2732 return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
2735 private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
2736 return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
2739 private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
2740 final String artifactType = artifactInfo.getArtifactType();
2741 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
2742 if (artifactTypeEnum == null) {
2743 artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
2746 switch (artifactTypeEnum) {
2757 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap,
2758 String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
2759 User user = userBusinessLogic.getUser(userUserId, inTransaction);
2760 return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
2763 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
2764 ArtifactGroupTypeEnum groupType) {
2765 ArtifactDefinition artifactInfo = new ArtifactDefinition();
2766 String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
2767 String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
2768 String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
2769 artifactInfo.setArtifactDisplayName(artifactName);
2770 artifactInfo.setArtifactLabel(logicalName.toLowerCase());
2771 artifactInfo.setArtifactType(artifactType);
2772 artifactInfo.setDescription(artifactDescription);
2773 artifactInfo.setArtifactGroupType(groupType);
2774 nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
2775 setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
2776 return artifactInfo;
2779 private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
2780 String uniqueId = null;
2781 if (resourceId != null) {
2782 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
2783 artifactInfo.setUniqueId(uniqueId);
2785 artifactInfo.setUserIdCreator(user.getUserId());
2786 String fullName = user.getFullName();
2787 artifactInfo.setUpdaterFullName(fullName);
2788 long time = System.currentTimeMillis();
2789 artifactInfo.setCreatorFullName(fullName);
2790 artifactInfo.setCreationDate(time);
2791 artifactInfo.setLastUpdateDate(time);
2792 artifactInfo.setUserIdLastUpdater(user.getUserId());
2793 artifactInfo.setMandatory(true);
2796 public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType,
2797 ArtifactGroupTypeEnum groupType, String instanceId) {
2798 return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
2801 public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact,
2802 Component component, NodeTypeEnum parentType, String instanceId) {
2803 return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
2806 private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
2807 byte[] payload = payloadStr.getBytes();
2808 DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
2809 return Either.left(artifactData);
2813 * @param artifactDefinition
2816 public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType,
2817 Component component, String resourceInstanceName, User modifier,
2818 String instanceId, boolean shouldLock, boolean inTransaction) {
2819 String payload = generateHeatEnvPayload(artifactDefinition);
2820 String prevUUID = artifactDefinition.getArtifactUUID();
2821 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2822 return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2823 shouldLock, inTransaction).left()
2824 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2827 public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition,
2828 ComponentTypeEnum componentType, Component component,
2829 String resourceInstanceName, User modifier, boolean shouldLock,
2830 boolean inTransaction, String instanceId) {
2831 String payload = generateHeatEnvPayload(artifactDefinition);
2832 String prevUUID = artifactDefinition.getArtifactUUID();
2833 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2834 return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2835 shouldLock, inTransaction).left()
2836 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2840 Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID,
2841 ArtifactDefinition clonedBeforeGenerate,
2842 ArtifactDefinition updatedArtDef) {
2843 if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
2844 List<ComponentInstance> componentInstances = component.getComponentInstances();
2845 if (componentInstances != null) {
2846 Optional<ComponentInstance> findFirst = componentInstances.stream().filter(ci -> ci.getUniqueId().equals(instanceId)).findFirst();
2847 if (findFirst.isPresent()) {
2848 ComponentInstance relevantInst = findFirst.get();
2849 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate,
2850 relevantInst.getGroupInstances());
2851 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
2852 updatedGroupInstances.forEach(gi -> {
2853 gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
2854 gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
2856 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
2857 .updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
2858 if (status.isRight()) {
2859 log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
2860 ResponseFormat responseFormat = componentsUtils
2861 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(status.right().value()),
2862 clonedBeforeGenerate.getArtifactDisplayName());
2863 return Either.right(responseFormat);
2869 return Either.left(updatedArtDef);
2872 private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
2873 List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
2874 StringBuilder sb = new StringBuilder();
2875 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
2876 sb.append("parameters:\n");
2877 if (heatParameters != null) {
2878 heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2879 List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
2880 for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
2881 String heatValue = heatParameterDefinition.getCurrentValue();
2882 if (StringUtils.isEmpty(heatValue)) {
2883 heatValue = heatParameterDefinition.getDefaultValue();
2884 if (StringUtils.isEmpty(heatValue)) {
2885 empltyHeatValues.add(heatParameterDefinition);
2889 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
2893 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatValue))
2897 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ")
2898 .append(new BigDecimal(heatValue).toPlainString()).append("\n");
2900 case COMMA_DELIMITED_LIST:
2902 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatValue).append("\n");
2905 String value = heatValue;
2906 boolean starts = value.startsWith("\"");
2907 boolean ends = value.endsWith("\"");
2908 if (!(starts && ends)) {
2909 starts = value.startsWith("'");
2910 ends = value.endsWith("'");
2911 if (!(starts && ends)) {
2912 value = "\"" + value + "\"";
2915 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value);
2921 if (!empltyHeatValues.isEmpty()) {
2922 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2923 empltyHeatValues.forEach(hv -> {
2924 sb.append(" ").append(hv.getName()).append(":");
2925 HeatParameterType type = HeatParameterType.isValidType(hv.getType());
2926 if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv.getCurrentValue())
2927 || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
2928 sb.append(" \"\"").append("\n");
2930 sb.append(" ").append("\n");
2935 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
2937 return sb.toString().replace("\\\\n", "\n");
2941 * @param artifactDefinition
2945 public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2946 ComponentTypeEnum componentType, Component component,
2947 String resourceInstanceName, User modifier, String instanceId,
2948 boolean shouldLock, boolean inTransaction) {
2949 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2950 artifactDefinition::getHeatParamsUpdateDate, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2953 public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2954 ComponentTypeEnum componentType, Component component,
2955 String resourceInstanceName, User modifier,
2956 String instanceId, boolean shouldLock,
2957 boolean inTransaction) {
2958 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2959 System::currentTimeMillis, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2962 protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition,
2963 ComponentTypeEnum componentType, Component component,
2964 String resourceInstanceName, User modifier, boolean shouldLock,
2965 boolean inTransaction, Supplier<Long> payloadUpdateDateGen,
2966 Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator,
2967 String instanceId) {
2968 log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2969 if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0
2970 || artifactDefinition.getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
2971 log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2972 Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
2973 DAOArtifactData artifactData = null;
2974 if (artifactDataRes.isLeft()) {
2975 artifactData = artifactDataRes.left().value();
2977 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2978 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
2979 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
2980 resourceInstanceName);
2981 return Either.right(artifactDataRes.right().value());
2983 String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
2985 String esArtifactId = artifactDefinition.getEsId();
2986 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
2987 DAOArtifactData DAOArtifactData;
2988 if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
2989 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
2990 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2991 if (artifactfromES.isRight()) {
2992 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2993 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2994 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
2995 log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
2996 return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
2998 DAOArtifactData = artifactfromES.left().value();
2999 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3001 oldCheckSum = artifactDefinition.getArtifactChecksum();
3003 Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3006 lockComponent(component, "Update Artifact - lock resource: ");
3007 } catch (ComponentException e) {
3008 handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null,
3009 artifactDefinition.getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3014 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3015 artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3016 updateArifactDefinitionStatus = artifactToscaOperation
3017 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3019 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3020 artifactDefinition.getEsId());
3021 if (updateArifactDefinitionStatus.isRight()) {
3022 ResponseFormat responseFormat = componentsUtils
3023 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3024 artifactDefinition.getArtifactDisplayName());
3025 log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3026 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3027 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3028 resourceInstanceName);
3029 return Either.right(responseFormat);
3032 artifactDefinition.getArtifactChecksum();
3033 artifactDefinition.setArtifactChecksum(newCheckSum);
3034 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3035 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3036 artifactDefinition.getEsId());
3037 updateArifactDefinitionStatus = artifactToscaOperation
3038 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3040 log.trace("Update Payload {}", artifactDefinition.getEsId());
3042 if (updateArifactDefinitionStatus.isLeft()) {
3043 artifactDefinition = updateArifactDefinitionStatus.left().value();
3044 artifactData.setId(artifactDefinition.getUniqueId());
3045 CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3046 if (saveArtifactStatus == CassandraOperationStatus.OK) {
3047 if (!inTransaction) {
3048 janusGraphDao.commit();
3050 log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3051 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3052 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3053 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3054 resourceInstanceName);
3056 if (!inTransaction) {
3057 janusGraphDao.rollback();
3059 log.info("Failed to save artifact {}.", artifactData.getId());
3060 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3061 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3062 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3063 resourceInstanceName);
3064 return Either.right(responseFormat);
3067 ResponseFormat responseFormat = componentsUtils
3068 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3069 artifactDefinition.getArtifactDisplayName());
3070 log.debug("Failed To update artifact {}", artifactData.getId());
3071 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3072 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3073 resourceInstanceName);
3074 return Either.right(responseFormat);
3078 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
3082 return Either.left(artifactDefinition);
3085 public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType,
3086 List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3088 .buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType,
3089 artifactDef.getArtifactLabel(), artifactDef.getArtifactDisplayName(), artifactDef.getDescription(), artifactDef.getPayloadData(),
3090 updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3093 public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType,
3094 ArtifactGroupTypeEnum artifactGroupType, String label, String displayName,
3095 String description, byte[] artifactContent,
3096 List<ArtifactTemplateInfo> updatedRequiredArtifacts,
3097 List<HeatParameterDefinition> heatParameters) {
3098 Map<String, Object> json = new HashMap<>();
3099 if (artifactId != null && !artifactId.isEmpty()) {
3100 json.put(Constants.ARTIFACT_ID, artifactId);
3102 json.put(Constants.ARTIFACT_NAME, artifactName);
3103 json.put(Constants.ARTIFACT_TYPE, artifactType);
3104 json.put(Constants.ARTIFACT_DESCRIPTION, description);
3105 if (artifactContent != null) {
3106 log.debug("payload is encoded. perform decode");
3107 String encodedPayload = Base64.encodeBase64String(artifactContent);
3108 json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3110 json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3111 json.put(Constants.ARTIFACT_LABEL, label);
3112 json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3113 json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3114 : updatedRequiredArtifacts.stream().filter(
3115 e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3116 .map(ArtifactTemplateInfo::getFileName).collect(Collectors.toList()));
3117 json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>() : heatParameters);
3121 public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user,
3122 Map<String, Object> json, ArtifactOperationInfo operation,
3123 ArtifactDefinition artifactInfo) {
3124 String jsonStr = gson.toJson(json);
3125 ArtifactDefinition artifactDefinitionFromJson =
3126 artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3127 String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3128 Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE,
3129 operation, artifactUniqueId, artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3130 return Either.left(uploadArtifactToService.left().value());
3133 private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo,
3134 AuditingActionEnum auditingAction, String artifactId, User user,
3135 ComponentTypeEnum componentType, Component parent, String originData,
3136 String origMd5, ArtifactOperationInfo operation) {
3137 if (origMd5 != null) {
3138 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3139 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3140 validateDeploymentArtifact(artifactInfo, parent);
3141 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3142 } else { // duplicate
3143 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3146 return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3149 private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId,
3150 ArtifactDefinition artifactInfo, User user,
3151 AuditingActionEnum auditingAction, Component parent,
3152 ComponentTypeEnum componentType, String origMd5) {
3153 Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3154 if (getRI.isRight()) {
3155 throw new ByResponseFormatComponentException(getRI.right().value());
3157 ComponentInstance ri = getRI.left().value();
3158 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3159 if (getArtifactRes.isRight()) {
3160 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3162 ArtifactDefinition currArtifact = getArtifactRes.left().value();
3163 if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType()
3164 .equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3165 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3167 List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3168 List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3170 if (origMd5 != null) {
3171 Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction,
3172 parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams,
3173 currArtifact.getArtifactName());
3174 if (uploadParamsValidationResult.isRight()) {
3175 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3177 artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3179 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo,
3180 ArtifactTypeEnum.HEAT_ENV.getType());
3181 if (validateAndConvertHeatParamers.isRight()) {
3182 throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3184 if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3185 // fill reduced heat env parameters List for updating
3186 boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3187 if (updateRequired) {
3188 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3189 currArtifact.setListHeatParameters(currentHeatEnvParams);
3190 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3191 .updateArtifactOnResource(currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3192 if (updateArtifactRes.isRight()) {
3193 log.debug("Failed to update artifact on graph - {}", artifactId);
3194 throw new StorageException(updateArtifactRes.right().value());
3196 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(),
3197 parent.getUniqueId());
3198 if (error != StorageOperationStatus.OK) {
3199 throw new StorageException(error);
3203 updateHeatMetaDataIfNeeded(componentId, user, auditingAction, componentType, parent, ri, artifactInfo);
3204 StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3205 if (error != StorageOperationStatus.OK) {
3206 throw new StorageException(error);
3208 return Either.left(currArtifact);
3211 private void updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType,
3212 Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3213 String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3214 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId,
3215 auditingAction, user);
3216 if (getArtifactRes.isRight()) {
3217 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3219 ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3220 if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3221 validateHeatMetaData(updatedHeatEnvArtifact);
3222 updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3223 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3224 .updateArtifactOnResource(heatArtifactToUpdate, parent, heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId,
3226 if (updateArtifactRes.isRight()) {
3227 log.debug("Failed to update artifact on graph - {}", heatArtifactId);
3228 throw new StorageException(updateArtifactRes.right().value());
3230 ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3231 updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition,
3232 componentType.getNodeType());
3233 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(),
3234 parent.getUniqueId());
3235 if (error != StorageOperationStatus.OK) {
3236 throw new StorageException(error);
3241 private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3242 Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3243 Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3244 Integer updateTimeout = updatedHeatEnv.getTimeout();
3245 if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3246 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3250 private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3251 // currently only timeout metadata can be updated
3252 return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3255 private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3256 // currently only timeout metadata can be updated
3257 origHeat.setTimeout(updatedHeatEnv.getTimeout());
3260 private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams,
3261 List<HeatParameterDefinition> updatedHeatEnvParams) {
3262 boolean isUpdate = false;
3263 List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3264 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3265 String paramName = heatEnvParam.getName();
3266 validateParamName(paramName, currentParamsNames);
3267 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3268 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3269 String updatedParamValue = heatEnvParam.getCurrentValue();
3270 if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3271 currHeatParam.setCurrentValue(updatedParamValue);
3280 private void validateParamName(String paramName, List<String> heatParamsNames) {
3281 if (!heatParamsNames.contains(paramName)) {
3282 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3286 private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo,
3287 AuditingActionEnum auditingAction, Component parent,
3288 ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact,
3289 boolean needToUpdateGroup) {
3290 Either<ArtifactDefinition, Operation> insideEither = null;
3291 String currentHeatId = currHeatArtifact.getUniqueId();
3292 String esArtifactId = currHeatArtifact.getEsId();
3293 Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3294 if (artifactFromES.isRight()) {
3295 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3296 throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3298 DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3299 ArtifactDefinition updatedHeatArt = currHeatArtifact;
3300 List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3301 List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3302 List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3303 if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3304 //TODO: improve complexity - currently N^2
3306 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3307 paramName = heatEnvParam.getName();
3308 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3309 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3310 String updatedParamValue = heatEnvParam.getCurrentValue();
3311 if (updatedParamValue == null) {
3312 updatedParamValue = heatEnvParam.getDefaultValue();
3314 HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3315 if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3316 throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE, ArtifactTypeEnum.HEAT_ENV.getType(),
3317 paramType.getType(), paramName);
3319 currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3320 newHeatEnvParams.add(currHeatParam);
3325 if (!newHeatEnvParams.isEmpty()) {
3326 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3327 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation
3328 .updateArtifactOnResource(currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId,
3330 if (operationStatus.isRight()) {
3331 log.debug("Failed to update artifact on graph - {}", currHeatArtifact.getUniqueId());
3332 throw new StorageException(operationStatus.right().value());
3334 updatedHeatArt = operationStatus.left().value();
3335 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3336 DAOArtifactData.setId(updatedHeatArt.getEsId());
3338 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), auditingAction,
3340 insideEither = Either.left(updatedHeatArt);
3343 Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3344 if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3345 artifactEnvInfo.setArtifactChecksum(null);
3346 updateHeatEnvArtifact = artifactToscaOperation
3347 .updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), componentType.getNodeType(),
3350 //TODO Andrey check if componentId = parent.getUniqeId
3351 updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType.getNodeType());
3353 if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3354 ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo, updateHeatEnvArtifact.left().value(), parent);
3355 if (result != ActionStatus.OK) {
3356 throw new ByActionStatusComponentException(result);
3359 if (updatedHeatEnvParams.isEmpty()) {
3360 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3362 return insideEither;
3365 private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3366 StorageOperationStatus error = StorageOperationStatus.OK;
3367 log.debug("Need to re-generate customization UUID for group instance on component instance {}", ri.getUniqueId());
3368 List<GroupInstance> groupsInstances = ri.getGroupInstances();
3369 List<String> groupInstancesId = null;
3370 if (groupsInstances != null && !groupsInstances.isEmpty()) {
3371 groupInstancesId = groupsInstances.stream()
3372 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(artifactId))
3373 .map(GroupInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
3375 if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3376 toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3381 public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent,
3382 User user, ArtifactDefinition artifactInfo,
3383 String artifactId, ComponentTypeEnum componentType,
3385 List<HeatParameterDefinition> currentHeatEnvParams,
3386 List<HeatParameterDefinition> updatedHeatEnvParams,
3387 String currArtifactName) {
3388 if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3389 ResponseFormat responseFormat = componentsUtils
3390 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName);
3391 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3392 return Either.right(responseFormat);
3394 for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3395 String paramName = uploadedHeatParam.getName();
3396 boolean isExistsInHeat = false;
3397 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3398 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3399 isExistsInHeat = true;
3400 uploadedHeatParam.setType(currHeatParam.getType());
3401 uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3402 uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3403 uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3407 if (!isExistsInHeat) {
3408 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3409 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType,
3411 return Either.right(responseFormat);
3414 return Either.left(updatedHeatEnvParams);
3417 private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId,
3418 AuditingActionEnum auditingAction, User user) {
3419 ResponseFormat responseFormat = null;
3420 List<ComponentInstance> ris = component.getComponentInstances();
3421 for (ComponentInstance ri : ris) {
3422 if (riID.equals(ri.getUniqueId())) {
3423 return Either.left(ri);
3426 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3427 log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3428 handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3429 return Either.right(responseFormat);
3432 private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId,
3433 AuditingActionEnum auditingAction, User user) {
3434 ResponseFormat responseFormat = null;
3435 Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3436 for (ArtifactDefinition artifact : rtifactsMap.values()) {
3437 if (artifactId.equals(artifact.getUniqueId())) {
3438 return Either.left(artifact);
3441 responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3442 handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3444 return Either.right(responseFormat);
3447 public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3448 ArtifactDefinition ret;
3449 if (eitherArtifact.isLeft()) {
3450 ret = eitherArtifact.left().value();
3452 ret = eitherArtifact.right().value().getImplementationArtifact();
3457 public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
3458 ResourceCommonInfo resourceCommonInfo) {
3459 Component component = getComponentByUuid(componentType, componentUuid);
3460 resourceCommonInfo.setResourceName(component.getName());
3461 return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3465 * downloads an artifact of resource instance of component by UUIDs
3467 * @param componentType
3468 * @param componentUuid
3469 * @param resourceInstanceName
3470 * @param artifactUUID
3473 public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
3474 String artifactUUID) {
3475 ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3476 if (resourceInstance != null) {
3477 return downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, resourceInstance.getName());
3479 return downloadArtifact(null, artifactUUID, null);
3484 * uploads an artifact to a component by UUID
3488 * @param componentType
3489 * @param componentUuid
3490 * @param resourceCommonInfo
3494 public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3495 String componentUuid, ResourceCommonInfo resourceCommonInfo,
3496 ArtifactOperationInfo operation) {
3497 Either<ArtifactDefinition, Operation> actionResult;
3498 Component component;
3500 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3501 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3502 String userId = request.getHeader(Constants.USER_ID_HEADER);
3503 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3504 ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3505 componentId = componentMetadataDataDefinition.getUniqueId();
3506 String componentName = componentMetadataDataDefinition.getName();
3507 if (!componentMetadataDataDefinition.getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3508 component = checkoutParentComponent(componentType, componentId, userId);
3509 if (component != null) {
3510 componentId = component.getUniqueId();
3511 componentName = component.getName();
3514 resourceCommonInfo.setResourceName(componentName);
3515 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null,
3517 return actionResult.left().value();
3521 * upload an artifact to a resource instance by UUID
3525 * @param componentType
3526 * @param componentUuid
3527 * @param resourceInstanceName
3531 public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3532 String resourceInstanceName, ArtifactOperationInfo operation) {
3533 Either<ArtifactDefinition, Operation> actionResult;
3534 Component component = null;
3535 String componentInstanceId;
3537 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3538 String userId = request.getHeader(Constants.USER_ID_HEADER);
3539 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3540 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid,
3541 resourceInstanceName);
3542 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3543 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3545 if (component == null) {
3546 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3548 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3550 componentInstanceId = componentRiPair.getRight().getUniqueId();
3551 componentId = componentRiPair.getLeft().getUniqueId();
3552 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3553 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5,
3554 data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3555 return actionResult.left().value();
3559 * updates an artifact on a component by UUID
3563 * @param componentType
3564 * @param componentUuid
3565 * @param artifactUUID
3566 * @param resourceCommonInfo
3567 * @param operation TODO
3570 public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3571 String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3572 ArtifactOperationInfo operation) {
3573 Either<ArtifactDefinition, Operation> actionResult;
3574 Component component;
3577 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3578 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3579 String userId = request.getHeader(Constants.USER_ID_HEADER);
3580 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3581 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3582 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3583 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3584 component = checkoutParentComponent(componentType, componentId, userId);
3585 if (component != null) {
3586 componentId = component.getUniqueId();
3587 componentName = component.getName();
3590 resourceCommonInfo.setResourceName(componentName);
3591 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3592 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null,
3594 if (actionResult.isRight()) {
3595 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult.right().value());
3597 return actionResult.left().value();
3601 * updates an artifact on a resource instance by UUID
3605 * @param componentType
3606 * @param componentUuid
3607 * @param resourceInstanceName
3608 * @param artifactUUID
3609 * @param operation TODO
3612 public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3613 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3614 Either<ArtifactDefinition, Operation> actionResult;
3615 Component component = null;
3616 String componentInstanceId;
3619 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3620 String userId = request.getHeader(Constants.USER_ID_HEADER);
3621 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3622 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3623 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3624 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3626 if (component == null) {
3627 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3629 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3631 componentInstanceId = componentRiPair.getRight().getUniqueId();
3632 componentId = componentRiPair.getLeft().getUniqueId();
3633 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3634 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3635 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo,
3636 origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3637 return actionResult.left().value();
3640 private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid,
3641 ArtifactDefinition artifactInfo) {
3642 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3643 if (componentStorageOperationStatusEither.isRight()) {
3644 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3645 log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
3646 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3648 Component storedComponent = componentStorageOperationStatusEither.left().value();
3649 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3650 .getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
3651 if (!optionalInterface.isPresent()) {
3652 log.debug("Failed to get resource interface for resource Id {}", componentId);
3653 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
3655 //fetch the operation from storage
3656 InterfaceDefinition gotInterface = optionalInterface.get();
3657 Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
3658 Optional<Operation> optionalOperation = operationsMap.values().stream().filter(o -> o.getUniqueId().equals(operationUuid)).findFirst();
3659 if (!optionalOperation.isPresent()) {
3660 log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
3661 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
3662 return Either.right(responseFormat);
3664 Operation operation = optionalOperation.get();
3665 ArtifactDefinition implementationArtifact = operation.getImplementationArtifact();
3666 implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
3667 implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
3668 implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
3669 implementationArtifact.setDescription(artifactInfo.getDescription());
3670 implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
3671 implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
3672 implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
3673 implementationArtifact.setEsId(artifactInfo.getEsId());
3674 operation.setImplementation(implementationArtifact);
3675 gotInterface.setOperationsMap(operationsMap);
3676 Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = interfaceOperation
3677 .updateInterfaces(storedComponent, Collections.singletonList(gotInterface));
3678 if (interfaceDefinitionStorageOperationStatusEither.isRight()) {
3679 StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
3680 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
3681 return Either.right(componentsUtils.getResponseFormat(actionStatus));
3683 return Either.left(artifactInfo);
3687 * updates an artifact on a component by UUID
3691 * @param componentType
3692 * @param componentUuid
3693 * @param artifactUUID
3697 public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(String data, HttpServletRequest request,
3698 ComponentTypeEnum componentType,
3699 String componentUuid, String interfaceUUID,
3700 String operationUUID, String artifactUUID,
3701 ResourceCommonInfo resourceCommonInfo,
3702 ArtifactOperationInfo operation) {
3703 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
3704 Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
3705 String componentId = null;
3706 ArtifactDefinition existingArtifactInfo = null;
3707 String interfaceName = null;
3708 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3709 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3710 String userId = request.getHeader(Constants.USER_ID_HEADER);
3711 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3712 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(as));
3715 if (errorWrapper.isEmpty()) {
3716 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3717 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3718 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3719 Component component = checkoutParentComponent(componentType, componentId, userId);
3720 if (component != null) {
3721 componentId = component.getUniqueId();
3722 componentName = component.getName();
3725 resourceCommonInfo.setResourceName(componentName);
3727 if (errorWrapper.isEmpty()) {
3728 Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
3729 if (interfaceNameEither.isRight()) {
3730 errorWrapper.setInnerElement(interfaceNameEither.right().value());
3732 interfaceName = interfaceNameEither.left().value();
3734 if (errorWrapper.isEmpty()) {
3735 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
3736 if (toscaComponentEither.isRight()) {
3737 StorageOperationStatus status = toscaComponentEither.right().value();
3738 log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
3739 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
3741 if (errorWrapper.isEmpty()) {
3742 NodeTypeEnum parentType = convertParentType(componentType);
3743 final List<ArtifactDefinition> existingDeploymentArtifacts = getDeploymentArtifacts(toscaComponentEither.left().value(), null);
3744 for (ArtifactDefinition artifactDefinition : existingDeploymentArtifacts) {
3745 if (artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())) {
3746 existingArtifactInfo = artifactDefinition;
3750 if (existingArtifactInfo != null) {
3751 return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
3756 if (errorWrapper.isEmpty()) {
3757 updateArtifactResult = handleArtifactRequestAndFlatten(componentId, userId, componentType, operation, artifactUUID, artifactInfo, origMd5,
3758 data, interfaceName, operationUUID);
3760 updateArtifactResult = Either.right(errorWrapper.getInnerElement());
3762 return updateArtifactResult;
3765 private Either<ArtifactDefinition, ResponseFormat> handleArtifactRequestAndFlatten(String componentId, String userId,
3766 ComponentTypeEnum componentType,
3767 ArtifactOperationInfo operation, String artifactId,
3768 ArtifactDefinition artifactInfo, String origMd5,
3769 String originData, String interfaceName,
3770 String operationName) {
3772 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
3773 operationName, null, null).right().map(op -> {
3774 log.debug("Unexpected value returned while calling handleArtifactRequest: {}", op);
3775 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3777 } catch (ComponentException e) {
3778 return Either.right(e.getResponseFormat());
3782 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid) {
3783 return fetchLatestComponentMetadataOrThrow(componentType, componentUuid, componentUuid);
3786 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid,
3787 String resourceInstanceName) {
3788 return fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3789 throw new ByActionStatusComponentException(as, resourceInstanceName);
3793 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadata(ComponentTypeEnum componentType, String componentUuid) {
3794 return toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true).right().map(sos -> {
3795 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, sos);
3796 return componentsUtils.convertFromStorageResponse(sos, componentType);
3800 private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
3801 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3802 if (componentStorageOperationStatusEither.isRight()) {
3803 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3804 log.debug("Failed to fetch component information by component id, error {}", errorStatus);
3805 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3807 Component storedComponent = componentStorageOperationStatusEither.left().value();
3808 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3809 .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
3810 if (!optionalInterface.isPresent()) {
3811 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
3813 return Either.left(optionalInterface.get().getType());
3817 * deletes an artifact on a component by UUID
3820 * @param componentType
3821 * @param componentUuid
3822 * @param artifactUUID
3823 * @param resourceCommonInfo
3824 * @param operation TODO
3827 public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3828 String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3829 ArtifactOperationInfo operation) {
3830 Either<ArtifactDefinition, Operation> actionResult;
3831 Component component;
3834 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3835 String userId = request.getHeader(Constants.USER_ID_HEADER);
3836 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3837 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3838 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3839 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3840 component = checkoutParentComponent(componentType, componentId, userId);
3841 if (component != null) {
3842 componentId = component.getUniqueId();
3843 componentName = component.getName();
3846 resourceCommonInfo.setResourceName(componentName);
3847 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3848 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
3849 return actionResult.left().value();
3853 * deletes an artifact from a resource instance by UUID
3856 * @param componentType
3857 * @param componentUuid
3858 * @param resourceInstanceName
3859 * @param artifactUUID
3860 * @param operation TODO
3863 public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3864 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3865 Either<ArtifactDefinition, Operation> actionResult;
3866 Component component = null;
3867 String componentInstanceId;
3870 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3871 String userId = request.getHeader(Constants.USER_ID_HEADER);
3872 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3873 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3874 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3875 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3877 if (component == null) {
3878 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3880 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3882 componentInstanceId = componentRiPair.getRight().getUniqueId();
3883 componentId = componentRiPair.getLeft().getUniqueId();
3884 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3885 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5,
3886 null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3887 return actionResult.left().value();
3890 private String findArtifactId(ComponentInstance instance, String artifactUUID) {
3891 String artifactId = null;
3892 ArtifactDefinition foundArtifact = null;
3893 if (instance.getDeploymentArtifacts() != null) {
3894 foundArtifact = instance.getDeploymentArtifacts().values().stream()
3895 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3897 if (foundArtifact == null && instance.getArtifacts() != null) {
3898 foundArtifact = instance.getArtifacts().values().stream()
3899 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3901 if (foundArtifact == null) {
3902 log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
3903 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
3905 artifactId = foundArtifact.getUniqueId();
3910 @SuppressWarnings("unchecked")
3911 public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact, String envType,
3912 String parentId, NodeTypeEnum parentType, String parentName, User user, Component component,
3913 Map<String, String> existingEnvVersions) {
3914 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
3915 .getDeploymentResourceInstanceArtifacts();
3916 if (deploymentResourceArtifacts == null) {
3917 log.debug("no deployment artifacts are configured for generated artifacts");
3918 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3920 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
3921 if (placeHolderData == null) {
3922 log.debug("no env type {} are configured for generated artifacts", envType);
3923 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3925 String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
3926 ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user.getUserId(),
3927 ArtifactGroupTypeEnum.DEPLOYMENT, true);
3928 ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
3929 artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
3930 artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
3931 artifactHeatEnv.setTimeout(0);
3932 artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
3933 buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
3934 // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
3935 handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
3936 ArtifactDefinition heatEnvPlaceholder;
3937 // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
3938 if (parentType != NodeTypeEnum.ResourceInstance) {
3939 String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
3940 artifactHeatEnv.setArtifactChecksum(checkSum);
3941 Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component,
3942 parentType, parentId);
3943 if (addHeatEnvArtifact.isRight()) {
3944 log.debug("failed to create heat env artifact on resource instance");
3945 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(
3946 componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact.right().value(), false), "", null));
3948 heatEnvPlaceholder = createArtifactPlaceHolder;
3950 heatEnvPlaceholder = artifactHeatEnv;
3951 artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
3952 setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
3954 ComponentTypeEnum componentType = component.getComponentType();
3955 if (parentType == NodeTypeEnum.ResourceInstance) {
3956 componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
3958 createdArtifacts.add(heatEnvPlaceholder);
3959 componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
3960 new ResourceCommonInfo(parentName, componentType.getValue()), ResourceVersionInfo.newBuilder().build(),
3961 ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(), null, heatEnvPlaceholder, null);
3962 return heatEnvPlaceholder;
3965 private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
3966 if (artifact.getListHeatParameters() == null) {
3969 List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
3970 for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
3971 HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
3972 heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
3973 heatEnvParameter.setCurrentValue(null);
3974 heatEnvParameters.add(heatEnvParameter);
3976 artifactDefinition.setListHeatParameters(heatEnvParameters);
3979 private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
3980 String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
3981 String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
3982 String name = heatArtifact.getArtifactName();
3985 name = heatArtifact.getArtifactLabel();
3986 fileName = name + "." + envExtension;
3988 fileName = name.replaceAll("." + heatExtension, "." + envExtension);
3990 heatEnvArtifact.setArtifactName(fileName);
3993 private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
3994 if (null != existingEnvVersions) {
3995 String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
3996 if (null != prevVersion) {
3997 heatEnvArtifact.setArtifactVersion(prevVersion);
4002 public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user,
4003 List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4004 ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4005 ComponentTypeEnum componentType = component.getComponentType();
4006 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4007 Either<ArtifactDefinition, Operation> result;
4009 for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4010 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4011 uploadedArtifacts.add(result.left().value());
4013 } catch (ComponentException e) {
4014 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component.getName(), e.getResponseFormat());
4015 if (operation.isCreateOrLink()) {
4016 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4020 return uploadedArtifacts;
4023 public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Component component, User user, ArtifactOperationInfo operation,
4024 boolean shouldLock, boolean inTransaction, ComponentTypeEnum componentType,
4025 ArtifactDefinition artifactDefinition) {
4026 AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4027 String componentId = component.getUniqueId();
4028 String artifactId = artifactDefinition.getUniqueId();
4029 Either<ArtifactDefinition, Operation> result;
4030 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4031 //artifact validation
4032 artifactDefinition = validateArtifact(componentId, componentType, operation, artifactId, artifactDefinition, auditingAction, user, component,
4033 shouldLock, inTransaction);
4034 switch (operation.getArtifactOperationEnum()) {
4036 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType,
4037 component, null, null);
4038 result = createArtifact(component, componentId, artifactDefinition, validPayload, componentType, auditingAction, null, null);
4041 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component,
4043 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4044 auditingAction, user, component, true);
4047 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4050 if (artifactGenerationRequired(component, artifactDefinition)) {
4051 result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4053 result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4057 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4060 throw new UnsupportedOperationException(
4061 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4066 public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component,
4067 User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4068 ArtifactOperationInfo operation, boolean shouldLock,
4069 boolean inTransaction) {
4070 List<ArtifactDefinition> handleArtifactsResult;
4071 ComponentTypeEnum componentType = component.getComponentType();
4072 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4073 Either<ArtifactDefinition, Operation> actionResult;
4077 for (ArtifactDefinition artifact : artifactsToHandle) {
4078 originData = ArtifactUtils.buildJsonStringForCsarVfcArtifact(artifact);
4079 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4080 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact.getUniqueId(),
4081 artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4082 uploadedArtifacts.add(actionResult.left().value());
4084 handleArtifactsResult = uploadedArtifacts;
4085 } catch (ComponentException e) {
4086 if (operation.isCreateOrLink()) {
4087 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4091 return handleArtifactsResult;
4094 private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName) {
4095 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4096 Option<Component> oComponent = Option.of(getComponentByUuid(componentType, componentUuid));
4097 return oComponent.toTry(componentNotFound(componentType, componentUuid)).flatMap(
4098 component -> findFirstMatching(component, ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4099 .toTry(componentInstanceNotFound(componentType, resourceInstanceName, component))).get();
4102 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName) {
4103 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4104 ComponentInstance componentInstance = findFirstMatching(component,
4105 ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4106 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4107 return new ImmutablePair<>(component, componentInstance);
4110 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid,
4111 String resourceInstanceName) {
4112 Component component = getLatestComponentByUuid(componentType, componentUuid);
4113 ComponentInstance componentInstance = findFirstMatching(component, ci -> ci.getNormalizedName().equals(resourceInstanceName))
4114 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4115 return new ImmutablePair<>(component, componentInstance);
4118 private Supplier<Throwable> componentNotFound(ComponentTypeEnum componentType, String componentUuid) {
4120 log.debug(FAILED_FETCH_COMPONENT, componentType.getValue(), componentUuid);
4121 return new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentUuid);
4125 private Supplier<Throwable> componentInstanceNotFound(ComponentTypeEnum componentType, String resourceInstanceName, Component component) {
4127 log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4128 return new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4129 RESOURCE_INSTANCE, componentType.getValue(), component.getName());
4133 private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4134 ImmutablePair<String, byte[]> downloadArtifact;
4135 List<ArtifactDefinition> artifactsList = null;
4136 ArtifactDefinition deploymentArtifact;
4137 if (artifacts != null && !artifacts.isEmpty()) {
4138 artifactsList = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID))
4139 .collect(Collectors.toList());
4141 if (artifactsList == null || artifactsList.isEmpty()) {
4142 log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4143 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4145 deploymentArtifact = artifactsList.get(0);
4146 downloadArtifact = downloadArtifact(deploymentArtifact);
4147 log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4148 return downloadArtifact.getRight();
4151 private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4152 Component component;
4153 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4154 if (getComponentRes.isRight()) {
4155 StorageOperationStatus status = getComponentRes.right().value();
4156 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4157 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4159 component = getComponentRes.left().value();
4164 private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4165 Component component;
4166 Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4167 if (getComponentRes.isRight()) {
4168 StorageOperationStatus status = getComponentRes.right().value();
4169 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4170 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4172 List<Component> value = getComponentRes.left().value();
4173 if (value.isEmpty()) {
4174 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4175 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4176 throw new ByActionStatusComponentException(status);
4178 component = value.get(0);
4184 private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4185 ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4186 StorageOperationStatus storageStatus;
4187 ArtifactDefinition latestArtifact;
4188 List<ArtifactDefinition> artifacts;
4189 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4190 if (getArtifactsRes.isRight()) {
4191 storageStatus = getArtifactsRes.right().value();
4192 log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4193 if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4194 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4196 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4198 artifacts = getArtifactsRes.left().value().values().stream()
4199 .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList());
4200 if (artifacts == null || artifacts.isEmpty()) {
4201 log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4202 parentId, actionStatus);
4203 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4205 latestArtifact = artifacts.stream().max((a1, a2) -> {
4206 int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4207 if (compareRes == 0) {
4208 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(),
4209 a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate());
4213 if (latestArtifact == null) {
4214 log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4215 parentId, actionStatus);
4216 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4218 return latestArtifact.getUniqueId();
4221 private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4222 Component component = null;
4223 User modifier = userBusinessLogic.getUser(userId, false);
4224 LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout",
4225 LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4226 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
4227 .changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4228 if (checkoutRes.isRight()) {
4229 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId,
4230 checkoutRes.right().value().getStatus());
4231 throw new ByResponseFormatComponentException(checkoutRes.right().value());
4233 return checkoutRes.left().value();
4237 void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4238 this.nodeTemplateOperation = nodeTemplateOperation;
4241 public List<ArtifactConfiguration> getConfiguration() {
4242 return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
4245 public enum ArtifactOperationEnum {
4246 CREATE, UPDATE, DELETE, DOWNLOAD, LINK;
4248 public static boolean isCreateOrLink(ArtifactOperationEnum operation) {
4249 return operation == CREATE || operation == LINK;