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, checkIfSkipImports(parent.getModel())).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 boolean checkIfSkipImports(final String model) {
391 return null != model && !model.equalsIgnoreCase("ETSI SOL001 v2.5.1")
392 && !model.equalsIgnoreCase("AUTOMATION COMPOSITION");
395 private Either<ArtifactDefinition, Operation> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
396 String artifactId, ArtifactDefinition artifactInfo, String origMd5, String originData,
397 String interfaceName, String operationName, AuditingActionEnum auditingAction, User user,
398 Component parent, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
399 if (interfaceName != null && operationName != null) {
400 interfaceName = interfaceName.toLowerCase();
401 operationName = operationName.toLowerCase();
404 lockComponent(componentType, artifactId, auditingAction, user, parent);
406 Either<ArtifactDefinition, Operation> result;
407 boolean operationSucceeded = false;
409 switch (operation.getArtifactOperationEnum()) {
411 if (artifactGenerationRequired(parent, artifactInfo)) {
412 result = Either.left(generateNotSavedArtifact(parent, artifactInfo));
414 result = Either.left(handleDownload(componentId, artifactId, componentType, parent));
418 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, parent));
421 result = handleUpdate(componentId, componentType, operation, artifactId, artifactInfo, null, origMd5, originData, interfaceName,
422 operationName, auditingAction, user, parent, needUpdateGroup);
425 result = handleCreate(componentId, artifactInfo, operation, auditingAction, user, componentType, parent, origMd5, originData,
426 interfaceName, operationName);
429 result = Either.left(handleLink(componentId, artifactInfo, componentType, parent));
432 throw new UnsupportedOperationException(
433 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
435 operationSucceeded = true;
438 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
442 private void lockComponent(ComponentTypeEnum componentType, String artifactId, AuditingActionEnum auditingAction, User user, Component parent) {
444 lockComponent(parent, ARTIFACT_ACTION_LOCK);
445 } catch (ComponentException e) {
446 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, null, null, artifactId, e.getResponseFormat(), componentType, null);
452 public Either<ArtifactDefinition, Operation> handleUpdate(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
453 String artifactId, ArtifactDefinition artifactInfo, byte[] decodedPayload,
454 String origMd5, String originData, String interfaceName, String operationName,
455 AuditingActionEnum auditingAction, User user, Component parent,
456 boolean needUpdateGroup) {
457 Either<ArtifactDefinition, Operation> result;
458 validateArtifactType(artifactInfo);
459 final String artifactType = artifactInfo.getArtifactType();
460 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && (ArtifactTypeEnum.HEAT.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_VOL
461 .getType().equals(artifactType) || ArtifactTypeEnum.HEAT_NET.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_ENV.getType()
462 .equals(artifactType))) {
463 result = handleUpdateHeatEnvAndHeatMeta(componentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, originData,
465 if (needUpdateGroup) {
466 ActionStatus error = updateGroupInstance(artifactInfo, result.left().value(), parent, componentId);
467 if (error != ActionStatus.OK) {
468 throw new ByActionStatusComponentException(error);
471 } else if (componentType == ComponentTypeEnum.RESOURCE && ArtifactTypeEnum.HEAT_ENV.getType().equals(artifactType)) {
472 result = handleUpdateHeatWithHeatEnvParams(componentId, artifactInfo, auditingAction, componentType, parent, originData, origMd5,
473 operation, needUpdateGroup);
475 if (decodedPayload == null) {
476 decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5,
477 originData, interfaceName, operationName);
479 result = updateArtifactFlow(parent, componentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
480 if (needUpdateGroup && result.isLeft()) {
481 ArtifactDefinition updatedArtifact = result.left().value();
482 updateGroupForHeat(artifactInfo, updatedArtifact, parent);
488 private void validateArtifactType(final ArtifactDefinition artifactInfo) {
489 if (!isArtifactSupported(artifactInfo.getArtifactType())) {
490 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
494 private void validateArtifactType(final ArtifactDefinition artifactInfo, final ComponentTypeEnum componentType) {
495 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactInfo.getArtifactType()).orElse(null);
496 if (artifactConfiguration == null) {
497 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
498 log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName());
499 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE);
500 throw new ByResponseFormatComponentException(responseFormat);
502 final ArtifactGroupTypeEnum artifactGroupType = artifactInfo.getArtifactGroupType();
504 validateArtifactType(componentType, artifactGroupType, artifactConfiguration);
505 } catch (final ComponentException e) {
506 log.debug("Artifact is invalid", e);
507 BeEcompErrorManager.getInstance()
508 .logBeInvalidTypeError("Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(),
509 "Artifact " + artifactInfo.getArtifactName());
510 log.debug("Not supported artifact type = {}", artifactInfo.getArtifactType());
511 final ResponseFormat responseFormat = componentsUtils
512 .getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
513 throw new ByResponseFormatComponentException(responseFormat);
517 private void validateArtifactType(final ComponentTypeEnum componentType, final ArtifactGroupTypeEnum groupType,
518 final ArtifactConfiguration artifactConfiguration) {
519 final boolean supportComponentType =
520 CollectionUtils.isNotEmpty(artifactConfiguration.getComponentTypes()) && artifactConfiguration.getComponentTypes().stream()
521 .anyMatch(componentType1 -> componentType1.getValue().equalsIgnoreCase(componentType.getValue()));
522 if (!supportComponentType) {
523 log.debug("Artifact Type '{}' not supported for Component Type '{}'", artifactConfiguration.getType(), componentType.getValue());
524 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
526 final boolean supportResourceType = artifactConfiguration.hasSupport(groupType);
527 if (!supportResourceType) {
528 log.debug("Artifact Type '{}' not supported for Component Type '{}' and Category '{}'", artifactConfiguration.getType(),
529 componentType.getValue(), groupType.getType());
530 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
534 private boolean isArtifactSupported(final String artifactType) {
535 final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
536 final List<ArtifactConfiguration> artifactConfigurationList = configuration.getArtifacts();
537 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
540 return artifactConfigurationList.stream().anyMatch(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType));
544 public ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent) {
545 List<GroupDefinition> groups = parent.getGroups();
546 if (groups != null && !groups.isEmpty()) {
547 List<GroupDataDefinition> groupToUpdate = groups.stream()
548 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfo.getUniqueId())).collect(Collectors.toList());
549 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
550 groupToUpdate.forEach(g -> {
551 g.getArtifacts().remove(artifactInfo.getUniqueId());
552 g.getArtifactsUuid().remove(artifactInfo.getArtifactUUID());
553 g.getArtifacts().add(artAfterUpdate.getUniqueId());
554 g.getArtifactsUuid().add(artAfterUpdate.getArtifactUUID());
555 if (!artifactInfo.getArtifactUUID().equals(artAfterUpdate.getArtifactUUID())) {
556 g.setGroupUUID(UniqueIdBuilder.generateUUID());
559 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
560 if (status.isRight()) {
561 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
562 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status.right().value()));
566 return ActionStatus.OK;
570 ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfoHeat, ArtifactDefinition artHeatAfterUpdate, ArtifactDefinition artifactInfoHeatE,
571 ArtifactDefinition artHEAfterUpdate, Component parent) {
572 List<GroupDefinition> groups = parent.getGroups();
573 if (groups != null && !groups.isEmpty()) {
574 List<GroupDataDefinition> groupToUpdate = groups.stream()
575 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfoHeat.getUniqueId())).collect(Collectors.toList());
576 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
577 groupToUpdate.forEach(g -> {
578 g.getArtifacts().remove(artifactInfoHeat.getUniqueId());
579 g.getArtifactsUuid().remove(artifactInfoHeat.getArtifactUUID());
580 g.getArtifacts().remove(artifactInfoHeatE.getUniqueId());
581 g.getArtifacts().add(artHeatAfterUpdate.getUniqueId());
582 g.getArtifactsUuid().add(artHeatAfterUpdate.getArtifactUUID());
583 g.getArtifacts().add(artHEAfterUpdate.getUniqueId());
585 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
586 if (status.isRight()) {
587 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
588 return componentsUtils.convertFromStorageResponse(status.right().value());
592 return ActionStatus.OK;
595 private ActionStatus updateGroupInstance(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent, String parentId) {
596 List<GroupInstance> updatedGroupInstances = new ArrayList<>();
597 List<GroupInstance> groupInstances = null;
598 Optional<ComponentInstance> componentInstOp = parent.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(parentId))
600 if (componentInstOp.isPresent()) {
601 groupInstances = componentInstOp.get().getGroupInstances();
603 if (CollectionUtils.isNotEmpty(groupInstances)) {
604 boolean isUpdated = false;
605 for (GroupInstance groupInstance : groupInstances) {
607 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifacts()) && groupInstance.getGroupInstanceArtifacts()
608 .contains(artifactInfo.getUniqueId())) {
609 groupInstance.getGroupInstanceArtifacts().remove(artifactInfo.getUniqueId());
610 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getUniqueId());
613 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifactsUuid()) && groupInstance.getGroupInstanceArtifactsUuid()
614 .contains(artifactInfo.getArtifactUUID())) {
615 groupInstance.getGroupInstanceArtifactsUuid().remove(artifactInfo.getArtifactUUID());
616 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getArtifactUUID());
620 updatedGroupInstances.add(groupInstance);
624 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
625 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
626 if (status.isRight()) {
627 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
628 return componentsUtils.convertFromStorageResponse(status.right().value());
630 return ActionStatus.OK;
633 ArtifactDefinition generateNotSavedArtifact(Component parent, ArtifactDefinition artifactDefinition) {
634 if (artifactDefinition.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA) {
635 Either<byte[], ComponentException> decodedPayload = decodeToscaArtifactPayload(parent, false, false,
636 artifactDefinition.getArtifactType());
637 // TODO: This should not be done, but in order to keep this refactoring relatively small, we stop here
638 if (decodedPayload.isRight()) {
639 throw decodedPayload.right().value();
641 artifactDefinition.setPayload(decodedPayload.left().value());
642 return artifactDefinition;
645 String heatArtifactId = artifactDefinition.getGeneratedFromId();
646 Either<ArtifactDefinition, StorageOperationStatus> heatRes = artifactToscaOperation.getArtifactById(parent.getUniqueId(), heatArtifactId);
647 if (heatRes.isRight()) {
648 log.debug("Failed to fetch heat artifact by generated id {} for heat env {}", heatArtifactId, artifactDefinition.getUniqueId());
649 throw new StorageException(heatRes.right().value());
651 String generatedPayload = generateHeatEnvPayload(heatRes.left().value());
652 artifactDefinition.setPayloadData(generatedPayload);
653 return artifactDefinition;
657 private Either<ArtifactDefinition, Operation> handleUpdateHeatWithHeatEnvParams(String componentId, ArtifactDefinition artifactInfo,
658 AuditingActionEnum auditingAction,
659 ComponentTypeEnum componentType, Component parent,
660 String originData, String origMd5,
661 ArtifactOperationInfo operation, boolean needToUpdateGroup) {
662 Either<ArtifactDefinition, StorageOperationStatus> artifactHeatRes = artifactToscaOperation
663 .getArtifactById(componentId, artifactInfo.getGeneratedFromId());
664 ArtifactDefinition currHeatArtifact = artifactHeatRes.left().value();
665 if (origMd5 != null) {
666 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
667 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
668 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
669 } else { // duplicate
670 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
673 return updateHeatParams(componentId, artifactInfo, auditingAction, parent, componentType, currHeatArtifact, needToUpdateGroup);
676 private void handleLockingAndCommit(Component parent, boolean shouldLock, boolean inTransaction, boolean actionSucceeded) {
677 if (actionSucceeded) {
679 if (!inTransaction) {
680 janusGraphDao.commit();
684 if (!inTransaction) {
685 janusGraphDao.rollback();
689 graphLockOperation.unlockComponent(parent.getUniqueId(), parent.getComponentType().getNodeType());
693 public ImmutablePair<String, byte[]> handleDownloadToscaModelRequest(Component component, ArtifactDefinition csarArtifact) {
694 if (artifactGenerationRequired(component, csarArtifact)) {
695 Either<byte[], ResponseFormat> generated = csarUtils.createCsar(component, false, false);
696 if (generated.isRight()) {
697 log.debug("Failed to export tosca csar for component {} error {}", component.getUniqueId(), generated.right().value());
698 throw new ByResponseFormatComponentException(generated.right().value());
700 return new ImmutablePair<>(csarArtifact.getArtifactName(), generated.left().value());
702 return downloadArtifact(csarArtifact);
705 public ImmutablePair<String, byte[]> handleDownloadRequestById(String componentId, String artifactId, String userId,
706 ComponentTypeEnum componentType, String parentId, String containerComponentType) {
707 // perform all validation in common flow
708 Either<ArtifactDefinition, Operation> result = handleArtifactRequest(componentId, userId, componentType,
709 new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DOWNLOAD), artifactId, null, null, null, null, null, parentId,
710 containerComponentType);
711 ArtifactDefinition artifactDefinition;
712 if (result.isLeft()) {
713 artifactDefinition = result.left().value();
715 artifactDefinition = result.right().value().getImplementationArtifact();
717 // for tosca artifacts and heat env on VF level generated on download without saving
718 if (artifactDefinition.getPayloadData() != null) {
719 return (new ImmutablePair<>(artifactDefinition.getArtifactName(), artifactDefinition.getPayloadData()));
721 return downloadArtifact(artifactDefinition);
724 public Map<String, ArtifactDefinition> handleGetArtifactsByType(String containerComponentType, String parentId, ComponentTypeEnum componentType,
725 String componentId, String artifactGroupType, String userId) {
728 // detect auditing type
729 Map<String, ArtifactDefinition> resMap = null;
734 if (userId == null) {
735 log.debug("handleGetArtifactsByType - no HTTP_CSP_HEADER , component id {}", componentId);
736 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
740 // check user existence
745 validateUserExists(userId);
748 // 5. check service/resource existence
750 // 6. check service/resource check out
752 // 7. user is owner of checkout state
753 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
754 ComponentParametersView componentFilter = new ComponentParametersView();
755 componentFilter.disableAll();
756 componentFilter.setIgnoreArtifacts(false);
757 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
758 componentFilter.setIgnoreComponentInstances(false);
760 Component component = validateComponentExistsByFilter(realComponentId, ComponentTypeEnum.findByParamName(containerComponentType),
762 lockComponent(component, ARTIFACT_ACTION_LOCK);
763 boolean failed = false;
765 ArtifactGroupTypeEnum groupType = ArtifactGroupTypeEnum.findType(artifactGroupType);
766 if (groupType == null) {
767 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
768 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
770 if (parentId == null && groupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
771 List<ArtifactDefinition> list = getDeploymentArtifacts(component, componentId);
772 if (list != null && !list.isEmpty()) {
773 resMap = list.stream().collect(Collectors.toMap(ArtifactDataDefinition::getArtifactLabel, Function.identity()));
775 resMap = new HashMap<>();
779 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsMapStatus = getArtifacts(realComponentId,
780 componentType.getNodeType(), groupType, componentId);
781 if (artifactsMapStatus.isRight()) {
782 if (artifactsMapStatus.right().value() != StorageOperationStatus.NOT_FOUND) {
783 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
784 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
786 resMap = new HashMap<>();
789 resMap = artifactsMapStatus.left().value();
793 } catch (ComponentException e) {
800 janusGraphDao.rollback();
803 janusGraphDao.commit();
805 componentType = component.getComponentType();
806 NodeTypeEnum nodeType = componentType.getNodeType();
807 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
811 private ArtifactDefinition getArtifactIfBelongsToComponent(String componentId, ComponentTypeEnum componentType, String artifactId,
812 Component component) {
813 // check artifact existence
814 Either<ArtifactDefinition, StorageOperationStatus> artifactResult = artifactToscaOperation
815 .getArtifactById(componentId, artifactId, componentType, component.getUniqueId());
816 if (artifactResult.isRight()) {
817 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentId);
819 // verify artifact belongs to component
821 switch (componentType) {
824 found = ComponentUtils.checkArtifactInComponent(component, artifactId);
826 case RESOURCE_INSTANCE:
827 found = ComponentUtils.checkArtifactInResourceInstance(component, componentId, artifactId);
833 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentType.name().toLowerCase());
835 return artifactResult.left().value();
838 private Either<ArtifactDefinition, Operation> handleCreate(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
839 AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType,
840 Component parent, String origMd5, String originData, String interfaceType,
841 String operationName) {
842 byte[] decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, null, user, componentType, parent, origMd5,
843 originData, interfaceType, operationName);
844 return createArtifact(parent, componentId, artifactInfo, decodedPayload, componentType, auditingAction, interfaceType, operationName);
847 private ArtifactDefinition handleLink(String componentId, ArtifactDefinition artifactInfo, ComponentTypeEnum componentType, Component parent) {
848 ComponentInstance foundInstance = findComponentInstance(componentId, parent);
849 String instanceId = null;
850 if (foundInstance != null) {
851 instanceId = foundInstance.getUniqueId();
853 NodeTypeEnum nodeType = convertParentType(componentType);
854 Either<ArtifactDefinition, StorageOperationStatus> artifactDefinitionEither = artifactToscaOperation
855 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
856 if (artifactDefinitionEither.isRight()) {
857 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
859 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), componentId, componentType) != StorageOperationStatus.OK) {
860 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
862 return artifactDefinitionEither.left().value();
865 private <T> Either<ArtifactDefinition, T> lockComponentAndUpdateArtifact(String parentId, ArtifactDefinition artifactInfo,
866 AuditingActionEnum auditingAction, String artifactId, User user,
867 ComponentTypeEnum componentType, Component parent, byte[] decodedPayload,
868 boolean shouldLock, boolean inTransaction) {
869 boolean failed = false;
870 boolean writeAudit = true;
872 lockComponent(parent, shouldLock, ARTIFACT_ACTION_LOCK);
874 return updateArtifactFlow(parent, parentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
875 } catch (ComponentException ce) {
877 handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, ce.getResponseFormat(), componentType, null);
881 } catch (StorageException se) {
887 unlockComponent(failed, parent, inTransaction);
892 private byte[] validateInput(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
893 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
894 String origMd5, String originData, String interfaceType, String operationName) {
895 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
896 return getValidPayload(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, interfaceType,
900 private byte[] getValidPayload(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
901 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
902 String interfaceType, String operationName) {
904 Either<ArtifactDefinition, ResponseFormat> validateResult = validateInput(componentId, artifactInfo, operation, artifactId, user,
905 interfaceType, operationName, componentType, parent);
906 if (validateResult.isRight()) {
907 ResponseFormat responseFormat = validateResult.right().value();
908 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
909 throw new ByResponseFormatComponentException(responseFormat);
911 Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
912 if (payloadEither.isRight()) {
913 ResponseFormat responseFormat = payloadEither.right().value();
914 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
915 log.debug("Error during handle payload");
916 throw new ByResponseFormatComponentException(responseFormat);
918 // validate heat parameters. this part must be after the parameters are
920 // extracted in "handlePayload"
921 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters = validateAndConvertHeatParameters(artifactInfo,
922 artifactInfo.getArtifactType());
923 if (validateAndConvertHeatParameters.isRight()) {
924 ResponseFormat responseFormat = validateAndConvertHeatParameters.right().value();
925 handleAuditing(auditingAction, parent, componentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null);
926 log.debug("Error during handle payload");
927 throw new ByResponseFormatComponentException(responseFormat);
929 return payloadEither.left().value();
932 public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
933 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
934 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
935 if (componentsUtils.isExternalApiEvent(auditingActionEnum)) {
940 user.setUserId("UNKNOWN");
942 handleInternalAuditEvent(auditingActionEnum, component, componentId, user, artifactDefinition, prevArtifactUuid, currentArtifactUuid,
943 responseFormat, componentTypeEnum, resourceInstanceName);
946 private void handleInternalAuditEvent(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
947 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
948 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
949 switch (componentTypeEnum) {
951 Resource resource = (Resource) component;
952 if (resource == null) {
953 // In that case, component ID should be instead of name
954 resource = new Resource();
955 resource.setName(componentId);
957 componentsUtils.auditResource(responseFormat, user, resource, resource.getName(), auditingActionEnum,
958 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(), currentArtifactUuid, artifactDefinition);
961 Service service = (Service) component;
962 if (service == null) {
963 // In that case, component ID should be instead of name
964 service = new Service();
965 service.setName(componentId);
968 .auditComponent(responseFormat, user, service, auditingActionEnum, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
969 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
970 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
972 case RESOURCE_INSTANCE:
973 if (resourceInstanceName == null) {
974 resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId);
976 componentsUtils.auditComponent(responseFormat, user, component, auditingActionEnum,
977 new ResourceCommonInfo(resourceInstanceName, ComponentTypeEnum.RESOURCE_INSTANCE.getValue()),
978 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
979 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
986 private String getResourceInstanceNameFromComponent(Component component, String componentId) {
987 ComponentInstance resourceInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findFirst()
989 String resourceInstanceName = null;
990 if (resourceInstance != null) {
991 resourceInstanceName = resourceInstance.getName();
993 return resourceInstanceName;
996 private void validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperationInfo operation) {
997 if (origMd5 == null) {
998 if (operation.isCreateOrLink() && ArrayUtils.isNotEmpty(payload)) {
999 log.debug("Missing md5 header during artifact create");
1000 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1003 if (ArrayUtils.isNotEmpty(payload)) {
1004 log.debug("Cannot have payload while md5 header is missing");
1005 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
1008 String encodeBase64Str = GeneralUtility.calculateMD5Base64EncodedByString(originData);
1009 if (!encodeBase64Str.equals(origMd5)) {
1010 log.debug("The calculated md5 is different then the received one");
1011 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1016 private Either<ArtifactDefinition, ResponseFormat> validateInput(final String componentId, final ArtifactDefinition artifactInfo,
1017 final ArtifactOperationInfo operation, final String artifactId, final User user,
1018 String interfaceName, String operationName,
1019 final ComponentTypeEnum componentType, final Component parentComponent) {
1020 final ArtifactDefinition existingArtifactInfo = findArtifact(parentComponent, componentType, componentId, operation, artifactId);
1021 final boolean isCreateOrLinkOperation = ArtifactOperationEnum.isCreateOrLink(operation.getArtifactOperationEnum());
1022 if (!isCreateOrLinkOperation && existingArtifactInfo == null) {
1023 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1025 final Component component;
1026 if (parentComponent.getUniqueId().equals(componentId)) {
1027 component = parentComponent;
1029 final ComponentInstance componentInstance = findComponentInstance(componentId, parentComponent);
1030 component = findComponent(componentInstance.getComponentUid());
1031 component.setComponentType(componentType);
1033 if (!isCreateOrLinkOperation) {
1034 ignoreUnupdateableFieldsInUpdate(operation, artifactInfo, existingArtifactInfo);
1036 if (isInformationalArtifact(artifactInfo)) {
1037 validateInformationalArtifact(artifactInfo, component);
1039 Either<Boolean, ResponseFormat> validateAndSetArtifactname = validateAndSetArtifactName(artifactInfo);
1040 if (validateAndSetArtifactname.isRight()) {
1041 return Either.right(validateAndSetArtifactname.right().value());
1043 if (!validateArtifactNameUniqueness(componentId, parentComponent, artifactInfo, componentType)) {
1044 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST));
1046 if (operationName != null && interfaceName != null) {
1047 operationName = operationName.toLowerCase();
1048 interfaceName = interfaceName.toLowerCase();
1050 Either<ActionStatus, ResponseFormat> logicalNameStatus = handleArtifactLabel(componentId, parentComponent, operation, artifactInfo,
1051 operationName, componentType);
1052 if (logicalNameStatus.isRight()) {
1053 return Either.right(logicalNameStatus.right().value());
1055 // This is a patch to block possibility of updating service api fields
1057 // through other artifacts flow
1058 final ArtifactGroupTypeEnum artifactGroupType =
1059 operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL;
1060 if (operation.isNotCreateOrLink()) {
1061 checkAndSetUnUpdatableFields(user, artifactInfo, existingArtifactInfo, artifactGroupType);
1063 checkCreateFields(user, artifactInfo, artifactGroupType);
1065 composeArtifactId(componentId, artifactId, artifactInfo, interfaceName, operationName);
1066 if (existingArtifactInfo != null) {
1067 artifactInfo.setMandatory(existingArtifactInfo.getMandatory());
1068 if (operation.isNotCreateOrLink()) {
1069 validateArtifactTypeNotChanged(artifactInfo, existingArtifactInfo);
1072 // artifactGroupType is not allowed to be updated
1073 if (operation.isNotCreateOrLink()) {
1074 Either<ArtifactDefinition, ResponseFormat> validateGroupType = validateOrSetArtifactGroupType(artifactInfo, existingArtifactInfo);
1075 if (validateGroupType.isRight()) {
1076 return Either.right(validateGroupType.right().value());
1079 setArtifactTimeout(artifactInfo, existingArtifactInfo);
1080 if (isHeatArtifact(artifactInfo)) {
1081 validateHeatArtifact(parentComponent, componentId, artifactInfo);
1083 if (isDeploymentArtifact(artifactInfo)) {
1084 if (componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1085 final String artifactName = artifactInfo.getArtifactName();
1086 final String existingArtifactName = (existingArtifactInfo == null) ? null : existingArtifactInfo.getArtifactName();
1087 if (operation.isCreateOrLink() || ((artifactName != null) && !artifactName.equalsIgnoreCase(existingArtifactName))) {
1088 validateSingleDeploymentArtifactName(artifactName, parentComponent);
1091 validateDeploymentArtifact(artifactInfo, component);
1093 Either<Boolean, ResponseFormat> descriptionResult = validateAndCleanDescription(artifactInfo);
1094 if (descriptionResult.isRight()) {
1095 return Either.right(descriptionResult.right().value());
1097 validateArtifactType(artifactInfo, component.getComponentType());
1098 artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase());
1099 if (existingArtifactInfo != null && existingArtifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.SERVICE_API) {
1100 // Change of type is not allowed and should be ignored
1101 artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER);
1102 Either<Boolean, ResponseFormat> validateUrl = validateAndServiceApiUrl(artifactInfo);
1103 if (validateUrl.isRight()) {
1104 return Either.right(validateUrl.right().value());
1106 Either<Boolean, ResponseFormat> validateUpdate = validateFirstUpdateHasPayload(artifactInfo, existingArtifactInfo);
1107 if (validateUpdate.isRight()) {
1108 log.debug("serviceApi first update cnnot be without payload.");
1109 return Either.right(validateUpdate.right().value());
1112 if (artifactInfo.getApiUrl() != null) {
1113 artifactInfo.setApiUrl(null);
1114 log.error("Artifact URL cannot be set through this API - ignoring");
1116 if (Boolean.TRUE.equals(artifactInfo.getServiceApi())) {
1117 artifactInfo.setServiceApi(false);
1118 log.error("Artifact service API flag cannot be changed - ignoring");
1121 return Either.left(artifactInfo);
1124 private Component findComponent(final String componentId) {
1125 Either<? extends Component, StorageOperationStatus> component = toscaOperationFacade.getToscaFullElement(componentId);
1126 if (component.isRight()) {
1127 log.debug("Component '{}' not found ", componentId);
1128 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentId);
1130 return component.left().value();
1133 private void ignoreUnupdateableFieldsInUpdate(final ArtifactOperationInfo operation, final ArtifactDefinition artifactInfo,
1134 final ArtifactDefinition currentArtifactInfo) {
1135 if (operation.isUpdate()) {
1136 artifactInfo.setArtifactType(currentArtifactInfo.getArtifactType());
1137 artifactInfo.setArtifactGroupType(currentArtifactInfo.getArtifactGroupType());
1138 artifactInfo.setArtifactLabel(currentArtifactInfo.getArtifactLabel());
1142 private ArtifactDefinition findArtifact(final Component parentComponent, final ComponentTypeEnum componentType, final String parentId,
1143 final ArtifactOperationInfo operation, final String artifactId) {
1144 ArtifactDefinition foundArtifact = null;
1145 if (StringUtils.isNotEmpty(artifactId)) {
1146 foundArtifact = findArtifact(parentComponent, componentType, parentId, artifactId);
1148 if (foundArtifact != null && operation.isCreateOrLink()) {
1149 log.debug("Artifact {} already exist", artifactId);
1150 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, foundArtifact.getArtifactLabel());
1152 if (foundArtifact == null && operation.isNotCreateOrLink()) {
1153 log.debug("The artifact {} was not found on parent component or instance {}. ", artifactId, parentId);
1154 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, "");
1156 return foundArtifact;
1159 private ArtifactDefinition findArtifact(Component parentComponent, ComponentTypeEnum componentType, String parentId, String artifactId) {
1160 ArtifactDefinition foundArtifact;
1161 if (parentComponent.getUniqueId().equals(parentId)) {
1162 foundArtifact = artifactsResolver.findArtifactOnComponent(parentComponent, componentType, artifactId);
1164 ComponentInstance instance = findComponentInstance(parentId, parentComponent);
1165 foundArtifact = artifactsResolver.findArtifactOnComponentInstance(instance, artifactId);
1167 return foundArtifact;
1170 private void validateInformationalArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1171 final ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
1172 if (groupType != ArtifactGroupTypeEnum.INFORMATIONAL) {
1175 final ComponentTypeEnum parentComponentType = component.getComponentType();
1176 final String artifactType = artifactInfo.getArtifactType();
1177 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1178 if (artifactConfiguration == null) {
1179 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1181 validateArtifactType(parentComponentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1182 if (component.getComponentType() == ComponentTypeEnum.RESOURCE || component.getComponentType() == ComponentTypeEnum.RESOURCE_INSTANCE) {
1183 final ResourceTypeEnum resourceType = ((Resource) component).getResourceType();
1184 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1186 validateArtifactExtension(artifactConfiguration, artifactInfo);
1189 private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) {
1190 if (componentType == ComponentTypeEnum.RESOURCE) {
1191 return NodeTypeEnum.Resource;
1192 } else if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1193 return NodeTypeEnum.ResourceInstance;
1195 return NodeTypeEnum.Service;
1199 // This method is here for backward compatibility - when other parts of the code are cleaned can change to use the internal version
1200 public Either<ArtifactDefinition, ResponseFormat> handleDelete(String parentId, String artifactId, User user, Component parent,
1201 boolean shouldLock, boolean inTransaction) {
1202 ResponseFormat responseFormat;
1203 boolean operationSucceeded = false;
1205 lockComponent(ComponentTypeEnum.RESOURCE, artifactId, AuditingActionEnum.ARTIFACT_DELETE, user, parent);
1208 ArtifactDefinition artifactDefinition = handleDeleteInternal(parentId, artifactId, ComponentTypeEnum.RESOURCE, parent);
1209 operationSucceeded = true;
1210 return Either.left(artifactDefinition);
1211 } catch (ComponentException ce) {
1212 responseFormat = componentsUtils.getResponseFormat(ce);
1213 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1214 ComponentTypeEnum.RESOURCE, null);
1215 return Either.right(responseFormat);
1216 } catch (StorageException se) {
1217 responseFormat = componentsUtils.getResponseFormat(se);
1218 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1219 ComponentTypeEnum.RESOURCE, null);
1220 return Either.right(responseFormat);
1222 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
1226 private ArtifactDefinition handleDeleteInternal(String parentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1227 NodeTypeEnum parentType = convertParentType(componentType);
1228 log.debug("Going to find the artifact {} on the component {}", artifactId, parent.getUniqueId());
1229 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> getArtifactRes = findArtifact(artifactId, parent, parentId,
1231 if (getArtifactRes.isRight()) {
1232 log.debug("Failed to find the artifact {} belonging to {} on the component {}", artifactId, parentId, parent.getUniqueId());
1233 throw new ByActionStatusComponentException(getArtifactRes.right().value(), artifactId);
1235 ArtifactDefinition foundArtifact = getArtifactRes.left().value().getLeft();
1236 ComponentInstance foundInstance = getArtifactRes.left().value().getRight();
1237 String esId = foundArtifact.getEsId();
1238 Either<Boolean, StorageOperationStatus> needClone = ifTrue(StringUtils.isNotEmpty(esId),
1239 () -> forEach(artifactToscaOperation.isCloneNeeded(parent.getUniqueId(), foundArtifact, parentType), b -> log
1240 .debug("handleDelete: clone is needed for deleting {} held by {} in component {} {}? {}", foundArtifact.getArtifactName(), parentType,
1241 parent.getUniqueId(), parent.getName(), b)));
1242 boolean needToClone = false;
1243 // TODO: This should not be done, but in order to keep this refactoring small, we stop here.
1245 // Remove this block once the above refactoring is merged.
1246 if (needClone.isLeft()) {
1247 needToClone = needClone.left().value();
1249 throw new StorageException(needClone.right().value(), foundArtifact.getArtifactDisplayName());
1251 boolean isNeedToDeleteArtifactFromDB =
1252 componentType == ComponentTypeEnum.RESOURCE_INSTANCE && isArtifactOnlyResourceInstanceArtifact(foundArtifact, parent, parentId);
1253 boolean isDuplicated = false;
1254 ArtifactDataDefinition updatedArtifact = deleteOrUpdateArtifactOnGraph(parent, parentId, artifactId, parentType, foundArtifact, needToClone);
1255 isDuplicated = updatedArtifact.getDuplicated();
1256 if (!needToClone && !isDuplicated && isNeedToDeleteArtifactFromDB) {
1257 log.debug("Going to delete the artifact {} from the database. ", artifactId);
1258 CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(esId);
1259 if (cassandraStatus != CassandraOperationStatus.OK) {
1260 log.debug("Failed to delete the artifact {} from the database. ", artifactId);
1261 throw new StorageException(convertToStorageOperationStatus(cassandraStatus), foundArtifact.getArtifactDisplayName());
1264 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1265 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(artifactId, foundArtifact, foundInstance.getGroupInstances());
1266 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
1267 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
1268 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
1269 if (status.isRight()) {
1270 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1271 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1274 StorageOperationStatus status = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
1275 if (status != StorageOperationStatus.OK) {
1276 log.debug("Failed to generate new customization UUID for the component instance {}. ", parentId);
1277 throw new StorageException(status, foundArtifact.getArtifactDisplayName());
1280 List<GroupDataDefinition> updatedGroups = getUpdatedGroups(artifactId, foundArtifact, parent.getGroups());
1281 if (CollectionUtils.isNotEmpty(updatedGroups)) {
1282 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, updatedGroups);
1283 if (status.isRight()) {
1284 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1285 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1289 return foundArtifact;
1292 private boolean isArtifactOnlyResourceInstanceArtifact(ArtifactDefinition foundArtifact, Component parent, String instanceId) {
1293 Optional<ComponentInstance> componentInstanceOpt = parent.getComponentInstanceById(instanceId);
1294 if (!componentInstanceOpt.isPresent()) {
1295 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "", "", parent.getName());
1297 ComponentInstance foundInstance = componentInstanceOpt.get();
1298 String componentUid = foundInstance.getComponentUid();
1299 Either<Component, StorageOperationStatus> getContainerRes = toscaOperationFacade.getToscaElement(componentUid);
1300 if (getContainerRes.isRight()) {
1301 log.debug("Failed to fetch the container component {}. ", componentUid);
1302 throw new StorageException(getContainerRes.right().value());
1304 Component origComponent = getContainerRes.left().value();
1305 Map<String, ArtifactDefinition> deploymentArtifacts = origComponent.getDeploymentArtifacts();
1306 if (MapUtils.isNotEmpty(deploymentArtifacts)) {
1307 Optional<String> op = deploymentArtifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1308 if (op.isPresent()) {
1312 Map<String, ArtifactDefinition> artifacts = origComponent.getArtifacts();
1313 if (MapUtils.isNotEmpty(artifacts)) {
1314 Optional<String> op = artifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1315 if (op.isPresent()) {
1322 private List<GroupDataDefinition> getUpdatedGroups(String artifactId, ArtifactDefinition foundArtifact, List<GroupDefinition> groups) {
1323 List<GroupDataDefinition> updatedGroups = new ArrayList<>();
1324 boolean isUpdated = false;
1325 if (groups != null) {
1326 for (GroupDefinition group : groups) {
1328 if (CollectionUtils.isNotEmpty(group.getArtifacts()) && group.getArtifacts().contains(artifactId)) {
1329 group.getArtifacts().remove(artifactId);
1332 if (CollectionUtils.isNotEmpty(group.getArtifactsUuid()) && group.getArtifactsUuid().contains(foundArtifact.getArtifactUUID())) {
1333 group.getArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1337 updatedGroups.add(group);
1341 return updatedGroups;
1344 private List<GroupInstance> getUpdatedGroupInstances(String artifactId, ArtifactDefinition foundArtifact, List<GroupInstance> groupInstances) {
1345 if (CollectionUtils.isEmpty(groupInstances)) {
1346 return new ArrayList<>();
1348 // TODO: A defensive copy should be created here for groupInstances. Modifying
1350 // arguments (aka output arguments) is overall a bad practice as explained in
1352 // Clean Code by Robert Martin.
1354 // A better approach would be to use Lenses.
1355 return groupInstances.stream().filter(gi -> {
1356 boolean groupInstanceArtifactRemoved = gi.getGroupInstanceArtifacts() != null && gi.getGroupInstanceArtifacts().remove(artifactId);
1357 boolean groupInstanceArtifactUUIDRemoved =
1358 gi.getGroupInstanceArtifactsUuid() != null && gi.getGroupInstanceArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1359 return groupInstanceArtifactRemoved || groupInstanceArtifactUUIDRemoved;
1360 }).collect(Collectors.toList());
1363 private ArtifactDataDefinition deleteOrUpdateArtifactOnGraph(Component component, String parentId, String artifactId, NodeTypeEnum parentType,
1364 ArtifactDefinition foundArtifact, Boolean cloneIsNeeded) {
1365 Either<ArtifactDataDefinition, StorageOperationStatus> result;
1366 boolean isMandatory = foundArtifact.getMandatory() || foundArtifact.getServiceApi();
1367 String componentId = component.getUniqueId();
1368 String instanceId = componentId.equals(parentId) ? null : parentId;
1370 log.debug("Going to update mandatory artifact {} from the component {}", artifactId, parentId);
1371 resetMandatoryArtifactFields(foundArtifact);
1372 result = artifactToscaOperation.updateArtifactOnGraph(component, foundArtifact, parentType, artifactId, instanceId, true, true);
1373 } else if (cloneIsNeeded) {
1374 log.debug("Going to clone artifacts and to delete the artifact {} from the component {}", artifactId, parentId);
1375 result = artifactToscaOperation.deleteArtifactWithCloningOnGraph(componentId, foundArtifact, parentType, instanceId, false);
1377 log.debug("Going to delete the artifact {} from the component {}", artifactId, parentId);
1378 result = artifactToscaOperation.removeArtifactOnGraph(foundArtifact, componentId, instanceId, parentType, false);
1380 if (result.isRight()) {
1381 throw new StorageException(result.right().value(), foundArtifact.getArtifactDisplayName());
1383 return result.left().value();
1386 private Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> findArtifact(String artifactId,
1387 Component fetchedContainerComponent,
1389 ComponentTypeEnum componentType) {
1390 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> result = null;
1391 Map<String, ArtifactDefinition> artifacts = new HashMap<>();
1392 ComponentInstance foundInstance = null;
1393 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && StringUtils.isNotEmpty(parentId)) {
1394 Optional<ComponentInstance> componentInstanceOpt = fetchedContainerComponent.getComponentInstances().stream()
1395 .filter(i -> i.getUniqueId().equals(parentId)).findFirst();
1396 if (!componentInstanceOpt.isPresent()) {
1397 result = Either.right(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER);
1399 foundInstance = componentInstanceOpt.get();
1400 fetchArtifactsFromInstance(artifactId, artifacts, foundInstance);
1403 fetchArtifactsFromComponent(artifactId, fetchedContainerComponent, artifacts);
1405 if (result == null) {
1406 if (artifacts.containsKey(artifactId)) {
1407 result = Either.left(new ImmutablePair<>(artifacts.get(artifactId), foundInstance));
1409 result = Either.right(ActionStatus.ARTIFACT_NOT_FOUND);
1415 private void fetchArtifactsFromComponent(String artifactId, Component component, Map<String, ArtifactDefinition> artifacts) {
1416 Map<String, ArtifactDefinition> currArtifacts;
1417 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
1418 currArtifacts = component.getDeploymentArtifacts().values().stream()
1419 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, i -> i));
1420 if (MapUtils.isNotEmpty(currArtifacts)) {
1421 artifacts.putAll(currArtifacts);
1424 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1425 currArtifacts = component.getArtifacts().values().stream()
1426 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1427 if (MapUtils.isNotEmpty(currArtifacts)) {
1428 artifacts.putAll(currArtifacts);
1431 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1432 currArtifacts = component.getToscaArtifacts().values().stream()
1433 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1434 if (MapUtils.isNotEmpty(currArtifacts)) {
1435 artifacts.putAll(currArtifacts);
1440 private void fetchArtifactsFromInstance(String artifactId, Map<String, ArtifactDefinition> artifacts, ComponentInstance instance) {
1441 Map<String, ArtifactDefinition> currArtifacts;
1442 if (MapUtils.isNotEmpty(instance.getDeploymentArtifacts())) {
1443 currArtifacts = instance.getDeploymentArtifacts().values().stream()
1444 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1445 if (MapUtils.isNotEmpty(currArtifacts)) {
1446 artifacts.putAll(currArtifacts);
1449 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(instance.getArtifacts())) {
1450 currArtifacts = instance.getArtifacts().values().stream()
1451 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1452 if (MapUtils.isNotEmpty(currArtifacts)) {
1453 artifacts.putAll(currArtifacts);
1458 private StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) {
1459 StorageOperationStatus result;
1460 switch (cassandraStatus) {
1462 result = StorageOperationStatus.OK;
1465 result = StorageOperationStatus.NOT_FOUND;
1467 case CLUSTER_NOT_CONNECTED:
1468 case KEYSPACE_NOT_CONNECTED:
1469 result = StorageOperationStatus.CONNECTION_FAILURE;
1472 result = StorageOperationStatus.GENERAL_ERROR;
1478 private void resetMandatoryArtifactFields(ArtifactDefinition fetchedArtifact) {
1479 if (fetchedArtifact != null) {
1480 log.debug("Going to reset mandatory artifact {} fields. ", fetchedArtifact.getUniqueId());
1481 fetchedArtifact.setEsId(null);
1482 fetchedArtifact.setArtifactName(null);
1483 fetchedArtifact.setDescription(null);
1484 fetchedArtifact.setApiUrl(null);
1485 fetchedArtifact.setArtifactChecksum(null);
1486 nodeTemplateOperation.setDefaultArtifactTimeout(fetchedArtifact.getArtifactGroupType(), fetchedArtifact);
1487 fetchedArtifact.setArtifactUUID(null);
1488 long time = System.currentTimeMillis();
1489 fetchedArtifact.setPayloadUpdateDate(time);
1490 fetchedArtifact.setHeatParameters(null);
1491 fetchedArtifact.setHeatParamsUpdateDate(null);
1495 private StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId, ComponentTypeEnum componentType) {
1496 StorageOperationStatus error = StorageOperationStatus.OK;
1497 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1498 log.debug("Need to re-generate customization UUID for instance {}", instanceId);
1499 error = toscaOperationFacade.generateCustomizationUUIDOnInstance(componentId, instanceId);
1504 private ArtifactDefinition handleDownload(String componentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1505 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation
1506 .getArtifactById(componentId, artifactId, componentType, parent.getUniqueId());
1507 if (artifactById.isRight()) {
1508 throw new StorageException(artifactById.right().value());
1510 ArtifactDefinition artifactDefinition = artifactById.left().value();
1511 if (artifactDefinition == null) {
1512 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1514 return artifactDefinition;
1517 private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String componentId, Component parentComponent, ArtifactOperationInfo operation,
1518 ArtifactDefinition artifactInfo, String operationName,
1519 ComponentTypeEnum componentType) {
1520 String artifactLabel = artifactInfo.getArtifactLabel();
1521 if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) {
1522 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
1523 log.debug("missing artifact logical name for component {}", componentId);
1524 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1526 if (operation.isCreateOrLink() && !artifactInfo.getMandatory()) {
1527 if (operationName != null) {
1528 if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) {
1529 log.debug("artifact label cannot be set {}", artifactLabel);
1530 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED));
1532 artifactLabel = operationName;
1535 String displayName = artifactInfo.getArtifactDisplayName();
1536 if (displayName == null || displayName.isEmpty()) {
1537 displayName = artifactLabel;
1539 displayName = ValidationUtils.cleanArtifactDisplayName(displayName);
1540 artifactInfo.setArtifactDisplayName(displayName);
1541 if (!ValidationUtils.validateArtifactLabel(artifactLabel)) {
1542 log.debug("Invalid format form Artifact label : {}", artifactLabel);
1543 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_ARTIFACT_LABEL_NAME, VALID_ARTIFACT_LABEL_NAME));
1545 artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel);
1546 if (artifactLabel.isEmpty()) {
1547 log.debug("missing normalized artifact logical name for component {}", componentId);
1548 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1550 if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) {
1551 log.debug("Invalid lenght form Artifact label : {}", artifactLabel);
1552 return Either.right(componentsUtils
1553 .getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH)));
1555 if (!validateLabelUniqueness(componentId, parentComponent, artifactLabel, componentType)) {
1556 log.debug("Non unique Artifact label : {}", artifactLabel);
1557 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel));
1560 artifactInfo.setArtifactLabel(artifactLabel);
1561 return Either.left(ActionStatus.OK);
1564 private boolean validateLabelUniqueness(String componentId, Component parentComponent, String artifactLabel, ComponentTypeEnum componentType) {
1565 boolean isUnique = true;
1566 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts;
1567 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1568 artifacts = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1570 artifacts = artifactToscaOperation.getArtifacts(componentId);
1572 if (artifacts.isLeft()) {
1573 for (String label : artifacts.left().value().keySet()) {
1574 if (label.equals(artifactLabel)) {
1580 if (componentType == ComponentTypeEnum.RESOURCE && isUnique) {
1581 isUnique = isUniqueLabelInResourceInterfaces(componentId, artifactLabel);
1586 boolean validateArtifactNameUniqueness(String componentId, Component parentComponent, ArtifactDefinition artifactInfo,
1587 ComponentTypeEnum componentType) {
1588 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = getArtifacts(componentType, parentComponent, componentId,
1589 artifactInfo.getArtifactGroupType());
1590 String artifactName = artifactInfo.getArtifactName();
1591 if (artifacts.isLeft() && Objects.nonNull(artifacts.left().value())) {
1592 if (artifacts.left().value().values().stream().anyMatch(ad -> artifactName.equals(ad.getArtifactName())
1593 //check whether it is the same artifact we hold (by label)
1594 && !artifactInfo.getArtifactLabel().equals(ad.getArtifactLabel()))) {
1598 if (ComponentTypeEnum.RESOURCE == componentType) {
1599 return isUniqueArtifactNameInResourceInterfaces(componentId, artifactName, artifactInfo.getArtifactLabel());
1604 private boolean isUniqueArtifactNameInResourceInterfaces(String componentId, String artifactName, String artifactLabel) {
1605 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1606 .getAllInterfacesOfResource(componentId, true, true);
1607 if (allInterfacesOfResource.isLeft()) {
1608 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1609 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1610 .noneMatch(add -> artifactName.equals(add.getArtifactName()) && !artifactLabel.equals(add.getArtifactLabel()));
1615 private boolean isUniqueLabelInResourceInterfaces(String componentId, String artifactLabel) {
1616 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1617 .getAllInterfacesOfResource(componentId, true, true);
1618 if (allInterfacesOfResource.isLeft()) {
1619 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1620 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1621 .noneMatch(add -> artifactLabel.equals(add.getArtifactLabel()));
1626 private Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(ComponentTypeEnum componentType, Component parentComponent,
1628 ArtifactGroupTypeEnum artifactGroupType) {
1629 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse;
1630 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1631 artifactsResponse = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1633 artifactsResponse = artifactToscaOperation.getArtifacts(componentId);
1635 if (artifactsResponse.isRight() && artifactsResponse.right().value() == StorageOperationStatus.NOT_FOUND) {
1636 log.debug("failed to retrieve artifacts for {} ", componentId);
1637 return Either.right(artifactsResponse.right().value());
1639 return Either.left(artifactsResponse.left().value().entrySet().stream().filter(x -> artifactGroupType == x.getValue().getArtifactGroupType())
1640 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
1643 // ***************************************************************
1644 private Either<ArtifactDefinition, Operation> createArtifact(Component parent, String parentId, ArtifactDefinition artifactInfo,
1645 byte[] decodedPayload, ComponentTypeEnum componentTypeEnum,
1646 AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) {
1647 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
1648 if (artifactData == null) {
1649 BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact");
1650 log.debug("Failed to create artifact object for ES.");
1651 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1653 ComponentInstance foundInstance = findComponentInstance(parentId, parent);
1654 String instanceId = null;
1655 if (foundInstance != null) {
1656 if (foundInstance.isArtifactExists(artifactInfo.getArtifactGroupType(), artifactInfo.getArtifactLabel())) {
1657 log.debug("Failed to create artifact, already exists");
1658 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, artifactInfo.getArtifactLabel());
1660 instanceId = foundInstance.getUniqueId();
1662 // set on graph object id of artifact in ES!
1663 artifactInfo.setEsId(artifactData.getId());
1664 Either<ArtifactDefinition, Operation> operationResult;
1665 if (interfaceType != null && operationName != null) {
1666 // lifecycle artifact
1667 Operation operation = convertToOperation(artifactInfo, operationName);
1668 Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation
1669 .updateInterfaceOperation(parentId, interfaceType, operationName, operation);
1670 if (result.isRight()) {
1671 throw new StorageException(result.right().value());
1673 operationResult = Either.right(result.left().value());
1675 // information/deployment/api artifacts
1676 NodeTypeEnum nodeType = convertParentType(componentTypeEnum);
1677 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
1678 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
1679 if (result.isRight()) {
1680 throw new StorageException(result.right().value());
1682 ArtifactDefinition artifactDefinition = result.left().value();
1683 artifactData.setId(artifactDefinition.getEsId());
1684 operationResult = Either.left(artifactDefinition);
1685 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum) != StorageOperationStatus.OK) {
1686 throw new StorageException(generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum));
1689 saveArtifactInCassandra(artifactData, parent, artifactInfo, "", "", auditingActionEnum, componentTypeEnum);
1690 return operationResult;
1693 private ComponentInstance findComponentInstance(String componentInstanceId, Component containerComponent) {
1694 ComponentInstance foundInstance = null;
1695 if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
1696 foundInstance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst()
1699 return foundInstance;
1702 private void validateDeploymentArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1703 final ComponentTypeEnum componentType = component.getComponentType();
1704 if (componentType != ComponentTypeEnum.RESOURCE && componentType != ComponentTypeEnum.SERVICE
1705 && componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1706 log.debug("Invalid component type '{}' for artifact. " + "Expected Resource, Component or Resource Instance", componentType.getValue());
1707 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, componentType.getValue(),
1708 "Service, Resource or ResourceInstance", componentType.getValue());
1710 final String artifactType = artifactInfo.getArtifactType();
1711 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1712 if (artifactConfiguration == null) {
1713 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1715 validateArtifactType(componentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1716 if (componentType == ComponentTypeEnum.RESOURCE || componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1717 final Resource resource = (Resource) component;
1718 final ResourceTypeEnum resourceType = resource.getResourceType();
1719 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1721 validateArtifactExtension(artifactConfiguration, artifactInfo);
1724 private void validateHeatArtifact(final Component parentComponent, final String componentId, final ArtifactDefinition artifactDefinition) {
1725 final String artifactType = artifactDefinition.getArtifactType();
1726 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1727 if (artifactTypeEnum == null) {
1730 switch (artifactTypeEnum) {
1734 validateHeatTimeoutValue(artifactDefinition);
1737 validateHeatEnvDeploymentArtifact(parentComponent, componentId, artifactDefinition);
1744 private void setArtifactTimeout(final ArtifactDefinition newArtifactInfo, final ArtifactDefinition existingArtifactInfo) {
1745 final String artifactType = newArtifactInfo.getArtifactType();
1746 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1747 if (artifactTypeEnum == null) {
1748 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1751 switch (artifactTypeEnum) {
1755 if (newArtifactInfo.getTimeout() == null) {
1756 if (existingArtifactInfo == null) {
1757 newArtifactInfo.setTimeout(NodeTemplateOperation.getDefaultHeatTimeout());
1759 newArtifactInfo.setTimeout(existingArtifactInfo.getTimeout());
1764 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1770 void validateDeploymentArtifactTypeIsLegalForParent(ArtifactDefinition artifactInfo, ArtifactTypeEnum artifactType,
1771 Map<String, ArtifactTypeConfig> resourceDeploymentArtifacts) {
1772 if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) {
1773 log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType());
1774 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
1778 Optional<ArtifactConfiguration> loadArtifactTypeConfig(final String artifactType) {
1779 if (artifactType == null) {
1780 return Optional.empty();
1782 final List<ArtifactConfiguration> artifactConfigurationList = ConfigurationManager.getConfigurationManager().getConfiguration()
1784 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
1785 return Optional.empty();
1787 return artifactConfigurationList.stream().filter(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType))
1791 private Either<Boolean, ResponseFormat> extractHeatParameters(ArtifactDefinition artifactInfo) {
1792 // extract heat parameters
1793 if (artifactInfo.getPayloadData() != null) {
1794 String heatDecodedPayload = new String(Base64.decodeBase64(artifactInfo.getPayloadData()));
1795 Either<List<HeatParameterDefinition>, ResultStatusEnum> heatParameters = ImportUtils
1796 .getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo.getArtifactType());
1797 if (heatParameters.isRight() && (heatParameters.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND)) {
1798 log.info("failed to parse heat parameters ");
1799 ResponseFormat responseFormat = componentsUtils
1800 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactType());
1801 return Either.right(responseFormat);
1802 } else if (heatParameters.isLeft() && heatParameters.left().value() != null) {
1803 artifactInfo.setListHeatParameters(heatParameters.left().value());
1806 return Either.left(true);
1810 void validateArtifactExtension(final ArtifactConfiguration artifactConfiguration, final ArtifactDefinition artifactDefinition) {
1811 final List<String> acceptedTypes = artifactConfiguration.getAcceptedTypes();
1813 * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted.
1815 if (CollectionUtils.isEmpty(acceptedTypes)) {
1818 final String artifactName = artifactDefinition.getArtifactName();
1819 final String fileExtension = FilenameUtils.getExtension(artifactName);
1820 if (fileExtension == null || !acceptedTypes.contains(fileExtension.toLowerCase())) {
1821 final String artifactType = artifactDefinition.getArtifactType();
1822 log.debug("File extension \"{}\" is not allowed for artifact type \"{}\"", fileExtension, artifactType);
1823 throw new ByActionStatusComponentException(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, artifactType);
1828 void validateHeatEnvDeploymentArtifact(final Component parentComponent, final String parentId, final ArtifactDefinition artifactInfo) {
1829 final Wrapper<ArtifactDefinition> heatMDWrapper = new Wrapper<>();
1830 final Wrapper<byte[]> payloadWrapper = new Wrapper<>();
1831 validateYaml(artifactInfo);
1832 validateHeatExist(parentComponent.getUniqueId(), parentId, heatMDWrapper, artifactInfo, parentComponent.getComponentType());
1833 if (!heatMDWrapper.isEmpty()) {
1834 fillArtifactPayload(payloadWrapper, heatMDWrapper.getInnerElement());
1836 if (!heatMDWrapper.isEmpty()) {
1837 validateEnvVsHeat(artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement());
1841 public void fillArtifactPayload(Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactDefinition) {
1842 if (ArrayUtils.isEmpty(artifactDefinition.getPayloadData())) {
1843 Either<DAOArtifactData, CassandraOperationStatus> eitherArtifactData = artifactCassandraDao.getArtifact(artifactDefinition.getEsId());
1844 if (eitherArtifactData.isLeft()) {
1845 byte[] data = eitherArtifactData.left().value().getDataAsArray();
1846 payloadWrapper.setInnerElement(Base64.encodeBase64(data));
1848 log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName());
1849 throw new StorageException(DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()));
1852 payloadWrapper.setInnerElement(artifactDefinition.getPayloadData());
1856 private void validateEnvVsHeat(ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) {
1857 String envPayload = new String(Base64.decodeBase64(envArtifact.getPayloadData()));
1858 Map<String, Object> heatEnvToscaJson = (Map<String, Object>) new Yaml().load(envPayload);
1859 String heatDecodedPayload = new String(Base64.decodeBase64(heatPayloadData));
1860 Map<String, Object> heatToscaJson = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
1861 Either<Map<String, Object>, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils
1862 .findFirstToscaMapElement(heatEnvToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1863 if (eitherHeatEnvProperties.isRight()) {
1864 log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName());
1865 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat Env");
1867 Either<Map<String, Object>, ResultStatusEnum> eitherHeatProperties = ImportUtils
1868 .findFirstToscaMapElement(heatToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1869 if (eitherHeatProperties.isRight()) {
1870 log.debug("Invalid heat format for file:{}", heatArtifact.getArtifactName());
1871 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat");
1873 Set<String> heatPropertiesKeys = eitherHeatProperties.left().value().keySet();
1874 Set<String> heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet();
1875 heatEnvPropertiesKeys.removeAll(heatPropertiesKeys);
1876 if (!heatEnvPropertiesKeys.isEmpty()) {
1877 log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(),
1878 heatArtifact.getArtifactName());
1879 throw new ByActionStatusComponentException(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(),
1880 heatArtifact.getArtifactName());
1884 private void validateYaml(ArtifactDefinition artifactInfo) {
1885 YamlToObjectConverter yamlConverter = new YamlToObjectConverter();
1886 boolean isYamlValid = yamlConverter.isValidYamlEncoded64(artifactInfo.getPayloadData());
1888 log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName());
1889 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType());
1893 private void validateSingleDeploymentArtifactName(final String artifactName, final Component parentComponent) {
1894 boolean artifactNameFound = false;
1895 final Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, null).iterator();
1896 while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) {
1897 artifactNameFound = artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName());
1899 if (artifactNameFound) {
1900 final ComponentTypeEnum componentType = parentComponent.getComponentType();
1901 log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName);
1902 throw new ByActionStatusComponentException(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, componentType.getValue(),
1903 parentComponent.getName(), artifactName);
1907 private void validateHeatExist(String componentId, String parentRiId, Wrapper<ArtifactDefinition> heatArtifactMDWrapper,
1908 ArtifactDefinition heatEnvArtifact, ComponentTypeEnum componentType) {
1909 final Either<ArtifactDefinition, StorageOperationStatus> res = artifactToscaOperation
1910 .getHeatArtifactByHeatEnvId(parentRiId, heatEnvArtifact, componentId, componentType);
1911 if (res.isRight()) {
1912 throw new ByActionStatusComponentException(ActionStatus.MISSING_HEAT);
1914 heatArtifactMDWrapper.setInnerElement(res.left().value());
1918 void validateHeatTimeoutValue(final ArtifactDefinition artifactInfo) {
1919 log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel());
1920 // timeout > 0 for HEAT artifacts
1921 if (artifactInfo.getTimeout() == null || artifactInfo.getTimeout() < 1) {
1922 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
1924 // US649856 - Allow several HEAT files on Resource
1925 log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel());
1929 void validateResourceType(final ResourceTypeEnum resourceType, final ArtifactDefinition artifactInfo, final List<String> typeList) {
1930 if (CollectionUtils.isEmpty(typeList) || typeList.contains(resourceType.getValue())) {
1933 final String listToString = typeList.stream().collect(Collectors.joining(", "));
1934 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, artifactInfo.getArtifactGroupType().getType(),
1935 listToString, resourceType.getValue());
1939 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters(ArtifactDefinition artifactInfo, String artifactType) {
1940 if (artifactInfo.getHeatParameters() != null) {
1941 for (HeatParameterDefinition heatParam : artifactInfo.getListHeatParameters()) {
1942 String parameterType = heatParam.getType();
1943 HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType);
1944 String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType();
1945 if (heatParameterType == null) {
1946 ResponseFormat responseFormat = componentsUtils
1947 .getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam.getType());
1948 return Either.right(responseFormat);
1950 StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam);
1951 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
1952 log.debug("Heat parameter {} is invalid. Status is {}", heatParam.getName(), validateAndUpdateProperty);
1953 ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE;
1954 ResponseFormat responseFormat = componentsUtils
1955 .getResponseFormat(status, artifactTypeStr, heatParam.getType(), heatParam.getName());
1956 return Either.right(responseFormat);
1960 return Either.left(artifactInfo);
1963 public List<ArtifactDefinition> getDeploymentArtifacts(final Component component, final String ciId) {
1964 final ComponentTypeEnum componentType = component.getComponentType();
1965 if (component.getDeploymentArtifacts() == null) {
1966 return Collections.emptyList();
1968 final List<ArtifactDefinition> deploymentArtifacts = new ArrayList<>();
1969 if (ComponentTypeEnum.RESOURCE == componentType && ciId != null) {
1970 final Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(component, ciId, null, null, null);
1971 if (getRI.isRight()) {
1972 return Collections.emptyList();
1974 final ComponentInstance ri = getRI.left().value();
1975 if (ri.getDeploymentArtifacts() != null) {
1976 deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values());
1979 deploymentArtifacts.addAll(component.getDeploymentArtifacts().values());
1981 return deploymentArtifacts;
1984 private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) {
1985 // on create if null add informational to current
1986 if (artifactInfo.getArtifactGroupType() == null) {
1987 artifactInfo.setArtifactGroupType(type);
1989 if (artifactInfo.getUniqueId() != null) {
1990 log.error("artifact uniqid cannot be set ignoring");
1992 artifactInfo.setUniqueId(null);
1993 if (artifactInfo.getArtifactRef() != null) {
1994 log.error("artifact ref cannot be set ignoring");
1996 artifactInfo.setArtifactRef(null);
1997 if (artifactInfo.getArtifactRepository() != null) {
1998 log.error("artifact repository cannot be set ignoring");
2000 artifactInfo.setArtifactRepository(null);
2001 if (artifactInfo.getUserIdCreator() != null) {
2002 log.error("creator uuid cannot be set ignoring");
2004 artifactInfo.setArtifactCreator(user.getUserId());
2005 if (artifactInfo.getUserIdLastUpdater() != null) {
2006 log.error("userId of last updater cannot be set ignoring");
2008 artifactInfo.setUserIdLastUpdater(user.getUserId());
2009 if (artifactInfo.getCreatorFullName() != null) {
2010 log.error("creator Full name cannot be set ignoring");
2012 String fullName = user.getFirstName() + " " + user.getLastName();
2013 artifactInfo.setUpdaterFullName(fullName);
2014 if (artifactInfo.getUpdaterFullName() != null) {
2015 log.error("updater Full name cannot be set ignoring");
2017 artifactInfo.setUpdaterFullName(fullName);
2018 if (artifactInfo.getCreationDate() != null) {
2019 log.error("Creation Date cannot be set ignoring");
2021 long time = System.currentTimeMillis();
2022 artifactInfo.setCreationDate(time);
2023 if (artifactInfo.getLastUpdateDate() != null) {
2024 log.error("Last Update Date cannot be set ignoring");
2026 artifactInfo.setLastUpdateDate(time);
2027 if (artifactInfo.getEsId() != null) {
2028 log.error("es id cannot be set ignoring");
2030 artifactInfo.setEsId(null);
2033 private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName,
2034 String operationName) {
2035 String id = artifactId;
2036 if (artifactId == null || artifactId.isEmpty()) {
2037 String uniqueId = null;
2038 if (interfaceName != null && operationName != null) {
2039 uniqueId = UniqueIdBuilder
2040 .buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo.getArtifactLabel());
2042 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel());
2044 artifactInfo.setUniqueId(uniqueId);
2045 artifactInfo.setEsId(uniqueId);
2048 artifactInfo.setUniqueId(artifactId);
2049 artifactInfo.setEsId(artifactId);
2054 private Either<Boolean, ResponseFormat> validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2055 if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) {
2056 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD));
2058 return Either.left(true);
2062 Either<Boolean, ResponseFormat> validateAndSetArtifactName(ArtifactDefinition artifactInfo) {
2063 if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) {
2064 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2066 String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName());
2067 if (normalizeFileName == null || normalizeFileName.isEmpty()) {
2068 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2070 artifactInfo.setArtifactName(normalizeFileName);
2071 if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) {
2072 return Either.right(
2073 componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH)));
2075 return Either.left(true);
2078 private void validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2079 if (StringUtils.isEmpty(artifactInfo.getArtifactType())) {
2080 log.info("artifact type is missing operation ignored");
2081 throw new ByActionStatusComponentException(ActionStatus.MISSING_ARTIFACT_TYPE);
2083 if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) {
2084 log.info("artifact type cannot be changed operation ignored");
2085 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2089 private Either<ArtifactDefinition, ResponseFormat> validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo,
2090 ArtifactDefinition currentArtifact) {
2091 if (null != artifactInfo && null != currentArtifact) {
2092 if (artifactInfo.getArtifactGroupType() == null) {
2093 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2094 } else if (!currentArtifact.getArtifactGroupType().getType().equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) {
2095 log.info("artifact group type cannot be changed. operation failed");
2096 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2099 return Either.left(artifactInfo);
2102 private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact,
2103 ArtifactGroupTypeEnum type) {
2104 // on update if null add informational to current
2105 if (currentArtifact.getArtifactGroupType() == null && type != null) {
2106 currentArtifact.setArtifactGroupType(type);
2108 if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) {
2109 log.error("artifact uniqid cannot be set ignoring");
2111 artifactInfo.setUniqueId(currentArtifact.getUniqueId());
2112 if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef().equals(artifactInfo.getArtifactRef())) {
2113 log.error("artifact ref cannot be set ignoring");
2115 artifactInfo.setArtifactRef(currentArtifact.getArtifactRef());
2116 if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository().equals(artifactInfo.getArtifactRepository())) {
2117 log.error("artifact repository cannot be set ignoring");
2119 artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository());
2120 if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator().equals(artifactInfo.getUserIdCreator())) {
2121 log.error("creator uuid cannot be set ignoring");
2123 artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator());
2124 if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator().equals(artifactInfo.getArtifactCreator())) {
2125 log.error("artifact creator cannot be set ignoring");
2127 artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator());
2128 if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater().equals(artifactInfo.getUserIdLastUpdater())) {
2129 log.error("userId of last updater cannot be set ignoring");
2131 artifactInfo.setUserIdLastUpdater(user.getUserId());
2132 if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName().equals(artifactInfo.getCreatorFullName())) {
2133 log.error("creator Full name cannot be set ignoring");
2135 artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName());
2136 if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName().equals(artifactInfo.getUpdaterFullName())) {
2137 log.error("updater Full name cannot be set ignoring");
2139 String fullName = user.getFirstName() + " " + user.getLastName();
2140 artifactInfo.setUpdaterFullName(fullName);
2141 if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate().equals(artifactInfo.getCreationDate())) {
2142 log.error("Creation Date cannot be set ignoring");
2144 artifactInfo.setCreationDate(currentArtifact.getCreationDate());
2145 if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate().equals(artifactInfo.getLastUpdateDate())) {
2146 log.error("Last Update Date cannot be set ignoring");
2148 long time = System.currentTimeMillis();
2149 artifactInfo.setLastUpdateDate(time);
2150 if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) {
2151 log.error("es id cannot be set ignoring");
2153 artifactInfo.setEsId(currentArtifact.getUniqueId());
2154 if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName()
2155 .equals(artifactInfo.getArtifactDisplayName())) {
2156 log.error(" Artifact Display Name cannot be set ignoring");
2158 artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName());
2159 if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi().equals(artifactInfo.getServiceApi())) {
2160 log.debug("serviceApi cannot be set. ignoring.");
2162 artifactInfo.setServiceApi(currentArtifact.getServiceApi());
2163 if (artifactInfo.getArtifactGroupType() != null && currentArtifact.getArtifactGroupType() != artifactInfo.getArtifactGroupType()) {
2164 log.debug("artifact group cannot be set. ignoring.");
2166 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2167 artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion());
2168 if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID().isEmpty() && !currentArtifact.getArtifactUUID()
2169 .equals(artifactInfo.getArtifactUUID())) {
2170 log.debug("artifact UUID cannot be set. ignoring.");
2172 artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID());
2173 if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo.getHeatParameters().isEmpty()
2174 && !currentArtifact.getHeatParameters().isEmpty()) {
2175 checkAndSetUnupdatableHeatParams(artifactInfo.getListHeatParameters(), currentArtifact.getListHeatParameters());
2179 private void checkAndSetUnupdatableHeatParams(List<HeatParameterDefinition> heatParameters, List<HeatParameterDefinition> currentParameters) {
2180 Map<String, HeatParameterDefinition> currentParametersMap = getMapOfParameters(currentParameters);
2181 for (HeatParameterDefinition parameter : heatParameters) {
2182 HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId());
2183 if (currentParam != null) {
2184 if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) {
2185 log.debug("heat parameter name cannot be updated ({}). ignoring.", parameter.getName());
2186 parameter.setName(currentParam.getName());
2188 if (parameter.getDefaultValue() != null && !parameter.getDefaultValue().equalsIgnoreCase(currentParam.getDefaultValue())) {
2189 log.debug("heat parameter defaultValue cannot be updated ({}). ignoring.", parameter.getDefaultValue());
2190 parameter.setDefaultValue(currentParam.getDefaultValue());
2192 if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) {
2193 log.debug("heat parameter type cannot be updated ({}). ignoring.", parameter.getType());
2194 parameter.setType(currentParam.getType());
2196 if (parameter.getDescription() != null && !parameter.getDescription().equalsIgnoreCase(currentParam.getDescription())) {
2197 log.debug("heat parameter description cannot be updated ({}). ignoring.", parameter.getDescription());
2198 parameter.setDescription(currentParam.getDescription());
2200 // check and set current value
2201 if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) {
2202 log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue());
2203 parameter.setCurrentValue(currentParam.getDefaultValue());
2209 private Map<String, HeatParameterDefinition> getMapOfParameters(List<HeatParameterDefinition> currentParameters) {
2210 Map<String, HeatParameterDefinition> currentParamsMap = new HashMap<>();
2211 for (HeatParameterDefinition param : currentParameters) {
2212 currentParamsMap.put(param.getUniqueId(), param);
2214 return currentParamsMap;
2217 private Either<Boolean, ResponseFormat> validateAndServiceApiUrl(ArtifactDefinition artifactInfo) {
2218 if (StringUtils.isEmpty(artifactInfo.getApiUrl())) {
2219 log.debug("Artifact url cannot be empty.");
2220 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL));
2222 artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase());
2223 if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) {
2224 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL));
2226 if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) {
2228 .right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH)));
2230 return Either.left(true);
2233 private Either<Boolean, ResponseFormat> validateAndCleanDescription(ArtifactDefinition artifactInfo) {
2234 if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) {
2235 log.debug("Artifact description cannot be empty.");
2236 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION));
2238 String description = artifactInfo.getDescription();
2239 description = ValidationUtils.removeNoneUtf8Chars(description);
2240 description = ValidationUtils.normaliseWhitespace(description);
2241 description = ValidationUtils.stripOctets(description);
2242 description = ValidationUtils.removeHtmlTagsOnly(description);
2243 if (!ValidationUtils.validateIsEnglish(description)) {
2244 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2246 if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) {
2247 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION,
2248 String.valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)));
2250 artifactInfo.setDescription(description);
2251 return Either.left(true);
2254 private <T> Either<ArtifactDefinition, T> updateArtifactFlow(Component parent, String parentId, String artifactId,
2255 ArtifactDefinition artifactInfo, byte[] decodedPayload,
2256 ComponentTypeEnum componentType, AuditingActionEnum auditingAction) {
2257 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
2258 if (artifactData == null) {
2259 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2260 log.debug("Failed to create artifact object for ES.");
2261 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
2263 log.debug("Entry on graph is updated. Update artifact in ES");
2264 // Changing previous and current artifactId for auditing
2265 String currArtifactId = artifactInfo.getUniqueId();
2266 NodeTypeEnum parentType = convertParentType(componentType);
2267 if (decodedPayload == null) {
2268 if (!artifactInfo.getMandatory() || artifactInfo.getEsId() != null) {
2269 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactInfo.getEsId());
2270 if (artifactFromCassandra.isRight()) {
2271 throw new StorageException(artifactFromCassandra.right().value());
2273 // clone data to new artifact
2274 artifactData.setData(artifactFromCassandra.left().value().getData());
2275 artifactData.setId(artifactFromCassandra.left().value().getId());
2277 } else if (artifactInfo.getEsId() == null) {
2278 artifactInfo.setEsId(artifactInfo.getUniqueId());
2279 artifactData.setId(artifactInfo.getUniqueId());
2281 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
2282 .updateArtifactOnResource(artifactInfo, parent, artifactId, parentType, parentId, true);
2283 if (result.isRight()) {
2284 throw new StorageException(result.right().value());
2286 ArtifactDefinition artifactDefinition = result.left().value();
2287 updateGeneratedIdInHeatEnv(parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType);
2288 StorageOperationStatus storageOperationStatus = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
2289 if (storageOperationStatus != StorageOperationStatus.OK) {
2290 throw new StorageException(storageOperationStatus);
2292 if (artifactData.getData() != null) {
2293 if (!artifactDefinition.getDuplicated() || artifactData.getId() == null) {
2294 artifactData.setId(artifactDefinition.getEsId());
2296 saveArtifactInCassandra(artifactData, parent, artifactInfo, currArtifactId, artifactId, auditingAction, componentType);
2298 return Either.left(artifactDefinition);
2301 private String updateGeneratedIdInHeatEnv(Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo,
2302 ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2303 if (NodeTypeEnum.Resource == parentType) {
2304 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parent, parentId, artifactId, artifactInfo, artifactDefinition,
2307 return artifactDefinition.getUniqueId();
2310 private String updateGeneratedIdInHeatEnv(Map<String, ArtifactDefinition> deploymentArtifacts, Component parentComponent, String parentId,
2311 String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2312 NodeTypeEnum parentType, boolean isInstanceArtifact) {
2313 String artifactUniqueId;
2314 artifactUniqueId = artifactDefinition.getUniqueId();
2315 String artifactType = artifactInfo.getArtifactType();
2316 if ((ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType)
2317 || ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType)) && !artifactUniqueId.equals(artifactId)) {
2318 // need to update the generated id in heat env
2319 Optional<Entry<String, ArtifactDefinition>> findFirst = deploymentArtifacts.entrySet().stream()
2320 .filter(a -> artifactId.equals(a.getValue().getGeneratedFromId())).findFirst();
2321 if (findFirst.isPresent()) {
2322 ArtifactDefinition artifactEnvInfo = findFirst.get().getValue();
2323 artifactEnvInfo.setIsFromCsar(artifactDefinition.getIsFromCsar());
2324 artifactEnvInfo.setArtifactChecksum(null);
2325 if (isInstanceArtifact) {
2326 artifactToscaOperation
2327 .updateHeatEnvArtifactOnInstance(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2329 artifactToscaOperation
2330 .updateHeatEnvArtifact(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2334 return artifactUniqueId;
2337 private String updateGeneratedIdInHeatEnvOnInstance(ComponentInstance parent, Component parentComponent, String artifactId,
2338 ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2339 NodeTypeEnum parentType) {
2340 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parentComponent, parent.getUniqueId(), artifactId, artifactInfo,
2341 artifactDefinition, parentType, true);
2345 private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) {
2346 log.trace("Starting payload handling");
2347 byte[] payload = artifactInfo.getPayloadData();
2348 byte[] decodedPayload = null;
2349 if (payload != null && payload.length != 0) {
2350 // the generated artifacts were already decoded by the handler
2351 decodedPayload = artifactInfo.getGenerated() ? payload : Base64.decodeBase64(payload);
2352 if (decodedPayload.length == 0) {
2353 log.debug("Failed to decode the payload.");
2354 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
2355 return Either.right(responseFormat);
2357 String checkSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(decodedPayload);
2358 artifactInfo.setArtifactChecksum(checkSum);
2359 log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum);
2360 // Specific payload validations of different types
2361 Either<Boolean, ResponseFormat> result = Either.left(true);
2362 if (isDeploymentArtifact(artifactInfo)) {
2363 log.trace("Starting deployment artifacts payload validation");
2364 String artifactType = artifactInfo.getArtifactType();
2365 String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName());
2366 PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension);
2367 final Optional<ResponseFormat> pmDictionaryError = validateIfPmDictionary(artifactType, decodedPayload);
2368 if (pmDictionaryError.isPresent()) {
2369 return Either.right(pmDictionaryError.get());
2371 Either<Boolean, ActionStatus> isPayloadValid = payloadType.isValid(decodedPayload);
2372 if (isPayloadValid.isRight()) {
2373 ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType);
2374 return Either.right(responseFormat);
2376 if (payloadType.isHeatRelated()) {
2377 log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType);
2378 result = extractHeatParameters(artifactInfo);
2381 if (result.isRight()) {
2382 return Either.right(result.right().value());
2384 } // null/empty payload is normal if called from metadata update ONLY.
2386 // The validation of whether this is metadata/payload update case is
2388 // currently done separately
2390 if (!isArtifactMetadataUpdate) {
2391 log.debug("In artifact: {} Payload is missing.", artifactInfo.getArtifactName());
2392 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
2393 return Either.right(responseFormat);
2396 log.trace("Ended payload handling");
2397 return Either.left(decodedPayload);
2400 private Optional<ResponseFormat> validateIfPmDictionary(String artifactType, byte[] decodedPayload) {
2401 return new PMDictionaryValidator().validateIfPmDictionary(artifactType, decodedPayload).map(this::preparePmDictionaryResponse);
2404 private ResponseFormat preparePmDictionaryResponse(String errorMessage) {
2405 return componentsUtils.getResponseFormat(ActionStatus.INVALID_PM_DICTIONARY_FILE, errorMessage);
2408 public Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface(String resourceId, String userUserId, String artifactId,
2409 boolean inTransaction) {
2410 return toscaOperationFacade.getToscaElement(resourceId, JsonParseFlagEnum.ParseMetadata).right().map(componentsUtils.toResponseFormat())
2411 .left().bind(parentComponent -> {
2412 User user = new User(userUserId);
2413 return handleDelete(resourceId, artifactId, user, parentComponent, false, inTransaction);
2417 private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) {
2418 Operation op = new Operation();
2419 long time = System.currentTimeMillis();
2420 op.setCreationDate(time);
2421 String artifactName = artifactInfo.getArtifactName();
2422 artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName));
2423 op.setImplementation(artifactInfo);
2424 op.setLastUpdateDate(time);
2428 private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) {
2429 String newArtifactName = operationName + "_" + artifactName;
2430 log.trace("converting artifact name {} to {}", artifactName, newArtifactName);
2431 return newArtifactName;
2435 public byte[] downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion,
2436 String artifactName) {
2437 // General validation
2438 if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) {
2439 log.debug(NULL_PARAMETER);
2440 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2442 // Normalizing artifact name
2443 artifactName = ValidationUtils.normalizeFileName(artifactName);
2444 // Resource validation
2445 Resource resource = validateResourceNameAndVersion(resourceName, resourceVersion);
2446 String resourceId = resource.getUniqueId();
2447 // Service validation
2448 Service validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion);
2449 Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts();
2450 if (artifacts == null || artifacts.isEmpty()) {
2451 log.debug("Deployment artifacts of resource {} are not found", resourceId);
2452 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2454 ArtifactDefinition deploymentArtifact = null;
2455 for (ArtifactDefinition artifactDefinition : artifacts.values()) {
2456 if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName().equals(artifactName)) {
2457 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2458 deploymentArtifact = artifactDefinition;
2462 if (deploymentArtifact == null) {
2463 log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId);
2464 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2466 // Downloading the artifact
2467 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deploymentArtifact);
2468 log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId());
2469 return downloadArtifactEither.getRight();
2473 public byte[] downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) {
2474 // General validation
2475 if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) {
2476 log.debug(NULL_PARAMETER);
2477 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2479 // Normalizing artifact name
2480 artifactName = ValidationUtils.normalizeFileName(artifactName);
2481 // Service validation
2482 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2483 // ResourceInstance validation
2484 ComponentInstance resourceInstance = validateResourceInstance(service, resourceInstanceName);
2485 Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
2486 final String finalArtifactName = artifactName;
2487 Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName);
2488 ArtifactDefinition deployableArtifact =
2489 artifacts == null ? null : artifacts.values().stream().filter(filterArtifactByName).findFirst().orElse(null);
2490 if (deployableArtifact == null) {
2491 log.debug("Deployment artifact with name {} not found", artifactName);
2492 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
2494 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2495 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deployableArtifact);
2496 log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId());
2497 return downloadArtifactEither.getRight();
2500 private ComponentInstance validateResourceInstance(Service service, String resourceInstanceName) {
2501 List<ComponentInstance> riList = service.getComponentInstances();
2502 for (ComponentInstance ri : riList) {
2503 if (ri.getNormalizedName().equals(resourceInstanceName)) {
2507 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName);
2510 private ComponentInstance validateResourceInstanceById(Component component, String resourceInstanceId) {
2511 List<ComponentInstance> riList = component.getComponentInstances();
2512 for (ComponentInstance ri : riList) {
2513 if (ri.getUniqueId().equals(resourceInstanceId)) {
2517 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceInstanceId);
2520 private Service validateServiceNameAndVersion(String serviceName, String serviceVersion) {
2521 final Either<Service, StorageOperationStatus> serviceBySystemNameAndVersion
2522 = toscaOperationFacade.getBySystemNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
2523 if (serviceBySystemNameAndVersion.isRight()) {
2524 log.debug("Couldn't fetch any service with name {}", serviceName);
2525 throw new ByActionStatusComponentException(
2526 componentsUtils.convertFromStorageResponse(serviceBySystemNameAndVersion.right().value(), ComponentTypeEnum.SERVICE), serviceName);
2528 return serviceBySystemNameAndVersion.left().value();
2531 private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2532 Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade
2533 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2534 if (resourceListBySystemName.isRight()) {
2535 log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2536 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()),
2539 return resourceListBySystemName.left().value();
2542 public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2544 log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion,
2546 if (serviceName == null || serviceVersion == null || artifactName == null) {
2547 log.debug(NULL_PARAMETER);
2548 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2550 // Normalizing artifact name
2551 final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2552 // Service validation
2553 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2554 // Looking for deployment or tosca artifacts
2555 String serviceId = service.getUniqueId();
2556 if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2557 log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2558 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2560 Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2561 if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2562 foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2563 // filters artifact by name
2564 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2566 if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2567 foundArtifactOptl = service.getToscaArtifacts().values().stream()
2568 // filters TOSCA artifact by name
2569 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2571 if (!foundArtifactOptl.isPresent()) {
2572 log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2573 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2575 log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2576 // Downloading the artifact
2577 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl.get());
2578 log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2579 return downloadArtifactEither.getRight();
2582 public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2583 log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2584 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2585 if (artifactById.isRight()) {
2586 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2587 log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2588 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2590 ArtifactDefinition artifactDefinition = artifactById.left().value();
2591 if (artifactDefinition == null) {
2592 log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2593 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2595 return downloadArtifact(artifactDefinition);
2598 private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId,
2599 ComponentTypeEnum componentType, String containerComponentType) {
2600 ComponentTypeEnum componentForAudit =
2601 null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
2602 componentForAudit.getNodeType();
2603 Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaFullElement(componentId);
2604 if (componentResult.isRight()) {
2605 ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND
2606 : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
2607 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
2608 log.debug("Service not found, serviceId {}", componentId);
2609 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
2610 throw new ByActionStatusComponentException(status, componentId);
2612 return componentResult.left().value();
2615 private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId,
2616 ArtifactOperationInfo operation) {
2617 if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
2619 validateCanWorkOnComponent(component, userId);
2620 } catch (ComponentException e) {
2621 String uniqueId = component.getUniqueId();
2622 log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId);
2623 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(), component.getComponentType(),
2630 private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId,
2631 ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
2632 if (operation.isNotDownload()) {
2633 String role = user.getRole();
2634 if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
2635 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2636 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
2637 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2638 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
2643 private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId,
2644 ComponentTypeEnum componentType, boolean inTransaction) {
2647 user = validateUserExists(userId);
2648 } catch (ByResponseFormatComponentException e) {
2649 ResponseFormat responseFormat = e.getResponseFormat();
2650 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2652 } catch (ByActionStatusComponentException e) {
2653 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2654 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2660 private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId, ResponseFormat responseFormat,
2661 ComponentTypeEnum componentType, String userId) {
2662 User user = new User();
2663 user.setUserId(userId);
2664 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2667 protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
2668 AuditingActionEnum auditingAction = null;
2669 switch (operation.getArtifactOperationEnum()) {
2671 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
2674 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API
2675 : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
2678 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
2681 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
2686 return auditingAction;
2689 private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
2690 String esArtifactId = artifactDefinition.getEsId();
2691 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2692 if (artifactfromES.isRight()) {
2693 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2694 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2695 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
2696 log.debug("Error when getting artifact from ES, error: {}", actionStatus);
2697 throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
2699 DAOArtifactData DAOArtifactData = artifactfromES.left().value();
2700 byte[] data = DAOArtifactData.getDataAsArray();
2702 log.debug("Artifact data from cassandra is null");
2703 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
2705 String artifactName = artifactDefinition.getArtifactName();
2706 log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
2707 return new ImmutablePair<>(artifactName, data);
2710 public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
2711 return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
2714 private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo, String currArtifactId,
2715 String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
2716 CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
2717 if (resourceUploadStatus == CassandraOperationStatus.OK) {
2718 log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
2719 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
2720 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2721 componentType, null);
2723 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2724 log.info(FAILED_SAVE_ARTIFACT);
2725 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2726 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2727 componentType, null);
2728 throw new StorageException(resourceUploadStatus);
2732 private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
2733 return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
2736 private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
2737 return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
2740 private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
2741 return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
2744 private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
2745 final String artifactType = artifactInfo.getArtifactType();
2746 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
2747 if (artifactTypeEnum == null) {
2748 artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
2751 switch (artifactTypeEnum) {
2762 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap,
2763 String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
2764 User user = userBusinessLogic.getUser(userUserId, inTransaction);
2765 return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
2768 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
2769 ArtifactGroupTypeEnum groupType) {
2770 ArtifactDefinition artifactInfo = new ArtifactDefinition();
2771 String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
2772 String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
2773 String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
2774 artifactInfo.setArtifactDisplayName(artifactName);
2775 artifactInfo.setArtifactLabel(logicalName.toLowerCase());
2776 artifactInfo.setArtifactType(artifactType);
2777 artifactInfo.setDescription(artifactDescription);
2778 artifactInfo.setArtifactGroupType(groupType);
2779 nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
2780 setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
2781 return artifactInfo;
2784 private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
2785 String uniqueId = null;
2786 if (resourceId != null) {
2787 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
2788 artifactInfo.setUniqueId(uniqueId);
2790 artifactInfo.setUserIdCreator(user.getUserId());
2791 String fullName = user.getFullName();
2792 artifactInfo.setUpdaterFullName(fullName);
2793 long time = System.currentTimeMillis();
2794 artifactInfo.setCreatorFullName(fullName);
2795 artifactInfo.setCreationDate(time);
2796 artifactInfo.setLastUpdateDate(time);
2797 artifactInfo.setUserIdLastUpdater(user.getUserId());
2798 artifactInfo.setMandatory(true);
2801 public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType,
2802 ArtifactGroupTypeEnum groupType, String instanceId) {
2803 return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
2806 public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact,
2807 Component component, NodeTypeEnum parentType, String instanceId) {
2808 return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
2811 private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
2812 byte[] payload = payloadStr.getBytes();
2813 DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
2814 return Either.left(artifactData);
2818 * @param artifactDefinition
2821 public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType,
2822 Component component, String resourceInstanceName, User modifier,
2823 String instanceId, boolean shouldLock, boolean inTransaction) {
2824 String payload = generateHeatEnvPayload(artifactDefinition);
2825 String prevUUID = artifactDefinition.getArtifactUUID();
2826 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2827 return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2828 shouldLock, inTransaction).left()
2829 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2832 public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition,
2833 ComponentTypeEnum componentType, Component component,
2834 String resourceInstanceName, User modifier, boolean shouldLock,
2835 boolean inTransaction, String instanceId) {
2836 String payload = generateHeatEnvPayload(artifactDefinition);
2837 String prevUUID = artifactDefinition.getArtifactUUID();
2838 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2839 return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2840 shouldLock, inTransaction).left()
2841 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2845 Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID,
2846 ArtifactDefinition clonedBeforeGenerate,
2847 ArtifactDefinition updatedArtDef) {
2848 if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
2849 List<ComponentInstance> componentInstances = component.getComponentInstances();
2850 if (componentInstances != null) {
2851 Optional<ComponentInstance> findFirst = componentInstances.stream().filter(ci -> ci.getUniqueId().equals(instanceId)).findFirst();
2852 if (findFirst.isPresent()) {
2853 ComponentInstance relevantInst = findFirst.get();
2854 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate,
2855 relevantInst.getGroupInstances());
2856 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
2857 updatedGroupInstances.forEach(gi -> {
2858 gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
2859 gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
2861 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
2862 .updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
2863 if (status.isRight()) {
2864 log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
2865 ResponseFormat responseFormat = componentsUtils
2866 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(status.right().value()),
2867 clonedBeforeGenerate.getArtifactDisplayName());
2868 return Either.right(responseFormat);
2874 return Either.left(updatedArtDef);
2877 private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
2878 List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
2879 StringBuilder sb = new StringBuilder();
2880 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
2881 sb.append("parameters:\n");
2882 if (heatParameters != null) {
2883 heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2884 List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
2885 for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
2886 String heatValue = heatParameterDefinition.getCurrentValue();
2887 if (StringUtils.isEmpty(heatValue)) {
2888 heatValue = heatParameterDefinition.getDefaultValue();
2889 if (StringUtils.isEmpty(heatValue)) {
2890 empltyHeatValues.add(heatParameterDefinition);
2894 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
2898 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatValue))
2902 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ")
2903 .append(new BigDecimal(heatValue).toPlainString()).append("\n");
2905 case COMMA_DELIMITED_LIST:
2907 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatValue).append("\n");
2910 String value = heatValue;
2911 boolean starts = value.startsWith("\"");
2912 boolean ends = value.endsWith("\"");
2913 if (!(starts && ends)) {
2914 starts = value.startsWith("'");
2915 ends = value.endsWith("'");
2916 if (!(starts && ends)) {
2917 value = "\"" + value + "\"";
2920 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value);
2926 if (!empltyHeatValues.isEmpty()) {
2927 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2928 empltyHeatValues.forEach(hv -> {
2929 sb.append(" ").append(hv.getName()).append(":");
2930 HeatParameterType type = HeatParameterType.isValidType(hv.getType());
2931 if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv.getCurrentValue())
2932 || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
2933 sb.append(" \"\"").append("\n");
2935 sb.append(" ").append("\n");
2940 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
2942 return sb.toString().replace("\\\\n", "\n");
2946 * @param artifactDefinition
2950 public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2951 ComponentTypeEnum componentType, Component component,
2952 String resourceInstanceName, User modifier, String instanceId,
2953 boolean shouldLock, boolean inTransaction) {
2954 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2955 artifactDefinition::getHeatParamsUpdateDate, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2958 public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2959 ComponentTypeEnum componentType, Component component,
2960 String resourceInstanceName, User modifier,
2961 String instanceId, boolean shouldLock,
2962 boolean inTransaction) {
2963 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2964 System::currentTimeMillis, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2967 protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition,
2968 ComponentTypeEnum componentType, Component component,
2969 String resourceInstanceName, User modifier, boolean shouldLock,
2970 boolean inTransaction, Supplier<Long> payloadUpdateDateGen,
2971 Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator,
2972 String instanceId) {
2973 log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2974 if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0
2975 || artifactDefinition.getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
2976 log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2977 Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
2978 DAOArtifactData artifactData = null;
2979 if (artifactDataRes.isLeft()) {
2980 artifactData = artifactDataRes.left().value();
2982 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2983 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
2984 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
2985 resourceInstanceName);
2986 return Either.right(artifactDataRes.right().value());
2988 String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
2990 String esArtifactId = artifactDefinition.getEsId();
2991 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
2992 DAOArtifactData DAOArtifactData;
2993 if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
2994 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
2995 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2996 if (artifactfromES.isRight()) {
2997 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2998 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2999 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3000 log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
3001 return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
3003 DAOArtifactData = artifactfromES.left().value();
3004 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3006 oldCheckSum = artifactDefinition.getArtifactChecksum();
3008 Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3011 lockComponent(component, "Update Artifact - lock resource: ");
3012 } catch (ComponentException e) {
3013 handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null,
3014 artifactDefinition.getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3019 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3020 artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3021 updateArifactDefinitionStatus = artifactToscaOperation
3022 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3024 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3025 artifactDefinition.getEsId());
3026 if (updateArifactDefinitionStatus.isRight()) {
3027 ResponseFormat responseFormat = componentsUtils
3028 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3029 artifactDefinition.getArtifactDisplayName());
3030 log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3031 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3032 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3033 resourceInstanceName);
3034 return Either.right(responseFormat);
3037 artifactDefinition.getArtifactChecksum();
3038 artifactDefinition.setArtifactChecksum(newCheckSum);
3039 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3040 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3041 artifactDefinition.getEsId());
3042 updateArifactDefinitionStatus = artifactToscaOperation
3043 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3045 log.trace("Update Payload {}", artifactDefinition.getEsId());
3047 if (updateArifactDefinitionStatus.isLeft()) {
3048 artifactDefinition = updateArifactDefinitionStatus.left().value();
3049 artifactData.setId(artifactDefinition.getUniqueId());
3050 CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3051 if (saveArtifactStatus == CassandraOperationStatus.OK) {
3052 if (!inTransaction) {
3053 janusGraphDao.commit();
3055 log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3056 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3057 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3058 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3059 resourceInstanceName);
3061 if (!inTransaction) {
3062 janusGraphDao.rollback();
3064 log.info("Failed to save artifact {}.", artifactData.getId());
3065 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3066 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3067 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3068 resourceInstanceName);
3069 return Either.right(responseFormat);
3072 ResponseFormat responseFormat = componentsUtils
3073 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3074 artifactDefinition.getArtifactDisplayName());
3075 log.debug("Failed To update artifact {}", artifactData.getId());
3076 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3077 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3078 resourceInstanceName);
3079 return Either.right(responseFormat);
3083 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
3087 return Either.left(artifactDefinition);
3090 public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType,
3091 List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3093 .buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType,
3094 artifactDef.getArtifactLabel(), artifactDef.getArtifactDisplayName(), artifactDef.getDescription(), artifactDef.getPayloadData(),
3095 updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3098 public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType,
3099 ArtifactGroupTypeEnum artifactGroupType, String label, String displayName,
3100 String description, byte[] artifactContent,
3101 List<ArtifactTemplateInfo> updatedRequiredArtifacts,
3102 List<HeatParameterDefinition> heatParameters) {
3103 Map<String, Object> json = new HashMap<>();
3104 if (artifactId != null && !artifactId.isEmpty()) {
3105 json.put(Constants.ARTIFACT_ID, artifactId);
3107 json.put(Constants.ARTIFACT_NAME, artifactName);
3108 json.put(Constants.ARTIFACT_TYPE, artifactType);
3109 json.put(Constants.ARTIFACT_DESCRIPTION, description);
3110 if (artifactContent != null) {
3111 log.debug("payload is encoded. perform decode");
3112 String encodedPayload = Base64.encodeBase64String(artifactContent);
3113 json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3115 json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3116 json.put(Constants.ARTIFACT_LABEL, label);
3117 json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3118 json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3119 : updatedRequiredArtifacts.stream().filter(
3120 e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3121 .map(ArtifactTemplateInfo::getFileName).collect(Collectors.toList()));
3122 json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>() : heatParameters);
3126 public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user,
3127 Map<String, Object> json, ArtifactOperationInfo operation,
3128 ArtifactDefinition artifactInfo) {
3129 String jsonStr = gson.toJson(json);
3130 ArtifactDefinition artifactDefinitionFromJson =
3131 artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3132 String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3133 Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE,
3134 operation, artifactUniqueId, artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3135 return Either.left(uploadArtifactToService.left().value());
3138 private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo,
3139 AuditingActionEnum auditingAction, String artifactId, User user,
3140 ComponentTypeEnum componentType, Component parent, String originData,
3141 String origMd5, ArtifactOperationInfo operation) {
3142 if (origMd5 != null) {
3143 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3144 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3145 validateDeploymentArtifact(artifactInfo, parent);
3146 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3147 } else { // duplicate
3148 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3151 return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3154 private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId,
3155 ArtifactDefinition artifactInfo, User user,
3156 AuditingActionEnum auditingAction, Component parent,
3157 ComponentTypeEnum componentType, String origMd5) {
3158 Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3159 if (getRI.isRight()) {
3160 throw new ByResponseFormatComponentException(getRI.right().value());
3162 ComponentInstance ri = getRI.left().value();
3163 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3164 if (getArtifactRes.isRight()) {
3165 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3167 ArtifactDefinition currArtifact = getArtifactRes.left().value();
3168 if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType()
3169 .equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3170 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3172 List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3173 List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3175 if (origMd5 != null) {
3176 Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction,
3177 parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams,
3178 currArtifact.getArtifactName());
3179 if (uploadParamsValidationResult.isRight()) {
3180 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3182 artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3184 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo,
3185 ArtifactTypeEnum.HEAT_ENV.getType());
3186 if (validateAndConvertHeatParamers.isRight()) {
3187 throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3189 if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3190 // fill reduced heat env parameters List for updating
3191 boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3192 if (updateRequired) {
3193 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3194 currArtifact.setListHeatParameters(currentHeatEnvParams);
3195 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3196 .updateArtifactOnResource(currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3197 if (updateArtifactRes.isRight()) {
3198 log.debug("Failed to update artifact on graph - {}", artifactId);
3199 throw new StorageException(updateArtifactRes.right().value());
3201 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(),
3202 parent.getUniqueId());
3203 if (error != StorageOperationStatus.OK) {
3204 throw new StorageException(error);
3208 updateHeatMetaDataIfNeeded(componentId, user, auditingAction, componentType, parent, ri, artifactInfo);
3209 StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3210 if (error != StorageOperationStatus.OK) {
3211 throw new StorageException(error);
3213 return Either.left(currArtifact);
3216 private void updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType,
3217 Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3218 String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3219 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId,
3220 auditingAction, user);
3221 if (getArtifactRes.isRight()) {
3222 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3224 ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3225 if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3226 validateHeatMetaData(updatedHeatEnvArtifact);
3227 updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3228 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3229 .updateArtifactOnResource(heatArtifactToUpdate, parent, heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId,
3231 if (updateArtifactRes.isRight()) {
3232 log.debug("Failed to update artifact on graph - {}", heatArtifactId);
3233 throw new StorageException(updateArtifactRes.right().value());
3235 ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3236 updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition,
3237 componentType.getNodeType());
3238 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(),
3239 parent.getUniqueId());
3240 if (error != StorageOperationStatus.OK) {
3241 throw new StorageException(error);
3246 private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3247 Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3248 Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3249 Integer updateTimeout = updatedHeatEnv.getTimeout();
3250 if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3251 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3255 private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3256 // currently only timeout metadata can be updated
3257 return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3260 private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3261 // currently only timeout metadata can be updated
3262 origHeat.setTimeout(updatedHeatEnv.getTimeout());
3265 private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams,
3266 List<HeatParameterDefinition> updatedHeatEnvParams) {
3267 boolean isUpdate = false;
3268 List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3269 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3270 String paramName = heatEnvParam.getName();
3271 validateParamName(paramName, currentParamsNames);
3272 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3273 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3274 String updatedParamValue = heatEnvParam.getCurrentValue();
3275 if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3276 currHeatParam.setCurrentValue(updatedParamValue);
3285 private void validateParamName(String paramName, List<String> heatParamsNames) {
3286 if (!heatParamsNames.contains(paramName)) {
3287 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3291 private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo,
3292 AuditingActionEnum auditingAction, Component parent,
3293 ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact,
3294 boolean needToUpdateGroup) {
3295 Either<ArtifactDefinition, Operation> insideEither = null;
3296 String currentHeatId = currHeatArtifact.getUniqueId();
3297 String esArtifactId = currHeatArtifact.getEsId();
3298 Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3299 if (artifactFromES.isRight()) {
3300 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3301 throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3303 DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3304 ArtifactDefinition updatedHeatArt = currHeatArtifact;
3305 List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3306 List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3307 List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3308 if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3309 //TODO: improve complexity - currently N^2
3311 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3312 paramName = heatEnvParam.getName();
3313 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3314 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3315 String updatedParamValue = heatEnvParam.getCurrentValue();
3316 if (updatedParamValue == null) {
3317 updatedParamValue = heatEnvParam.getDefaultValue();
3319 HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3320 if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3321 throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE, ArtifactTypeEnum.HEAT_ENV.getType(),
3322 paramType.getType(), paramName);
3324 currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3325 newHeatEnvParams.add(currHeatParam);
3330 if (!newHeatEnvParams.isEmpty()) {
3331 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3332 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation
3333 .updateArtifactOnResource(currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId,
3335 if (operationStatus.isRight()) {
3336 log.debug("Failed to update artifact on graph - {}", currHeatArtifact.getUniqueId());
3337 throw new StorageException(operationStatus.right().value());
3339 updatedHeatArt = operationStatus.left().value();
3340 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3341 DAOArtifactData.setId(updatedHeatArt.getEsId());
3343 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), auditingAction,
3345 insideEither = Either.left(updatedHeatArt);
3348 Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3349 if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3350 artifactEnvInfo.setArtifactChecksum(null);
3351 updateHeatEnvArtifact = artifactToscaOperation
3352 .updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), componentType.getNodeType(),
3355 //TODO Andrey check if componentId = parent.getUniqeId
3356 updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType.getNodeType());
3358 if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3359 ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo, updateHeatEnvArtifact.left().value(), parent);
3360 if (result != ActionStatus.OK) {
3361 throw new ByActionStatusComponentException(result);
3364 if (updatedHeatEnvParams.isEmpty()) {
3365 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3367 return insideEither;
3370 private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3371 StorageOperationStatus error = StorageOperationStatus.OK;
3372 log.debug("Need to re-generate customization UUID for group instance on component instance {}", ri.getUniqueId());
3373 List<GroupInstance> groupsInstances = ri.getGroupInstances();
3374 List<String> groupInstancesId = null;
3375 if (groupsInstances != null && !groupsInstances.isEmpty()) {
3376 groupInstancesId = groupsInstances.stream()
3377 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(artifactId))
3378 .map(GroupInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
3380 if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3381 toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3386 public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent,
3387 User user, ArtifactDefinition artifactInfo,
3388 String artifactId, ComponentTypeEnum componentType,
3390 List<HeatParameterDefinition> currentHeatEnvParams,
3391 List<HeatParameterDefinition> updatedHeatEnvParams,
3392 String currArtifactName) {
3393 if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3394 ResponseFormat responseFormat = componentsUtils
3395 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName);
3396 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3397 return Either.right(responseFormat);
3399 for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3400 String paramName = uploadedHeatParam.getName();
3401 boolean isExistsInHeat = false;
3402 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3403 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3404 isExistsInHeat = true;
3405 uploadedHeatParam.setType(currHeatParam.getType());
3406 uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3407 uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3408 uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3412 if (!isExistsInHeat) {
3413 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3414 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType,
3416 return Either.right(responseFormat);
3419 return Either.left(updatedHeatEnvParams);
3422 private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId,
3423 AuditingActionEnum auditingAction, User user) {
3424 ResponseFormat responseFormat = null;
3425 List<ComponentInstance> ris = component.getComponentInstances();
3426 for (ComponentInstance ri : ris) {
3427 if (riID.equals(ri.getUniqueId())) {
3428 return Either.left(ri);
3431 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3432 log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3433 handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3434 return Either.right(responseFormat);
3437 private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId,
3438 AuditingActionEnum auditingAction, User user) {
3439 ResponseFormat responseFormat = null;
3440 Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3441 for (ArtifactDefinition artifact : rtifactsMap.values()) {
3442 if (artifactId.equals(artifact.getUniqueId())) {
3443 return Either.left(artifact);
3446 responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3447 handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3449 return Either.right(responseFormat);
3452 public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3453 ArtifactDefinition ret;
3454 if (eitherArtifact.isLeft()) {
3455 ret = eitherArtifact.left().value();
3457 ret = eitherArtifact.right().value().getImplementationArtifact();
3462 public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
3463 ResourceCommonInfo resourceCommonInfo) {
3464 Component component = getComponentByUuid(componentType, componentUuid);
3465 resourceCommonInfo.setResourceName(component.getName());
3466 return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3470 * downloads an artifact of resource instance of component by UUIDs
3472 * @param componentType
3473 * @param componentUuid
3474 * @param resourceInstanceName
3475 * @param artifactUUID
3478 public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
3479 String artifactUUID) {
3480 ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3481 if (resourceInstance != null) {
3482 return downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, resourceInstance.getName());
3484 return downloadArtifact(null, artifactUUID, null);
3489 * uploads an artifact to a component by UUID
3493 * @param componentType
3494 * @param componentUuid
3495 * @param resourceCommonInfo
3499 public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3500 String componentUuid, ResourceCommonInfo resourceCommonInfo,
3501 ArtifactOperationInfo operation) {
3502 Either<ArtifactDefinition, Operation> actionResult;
3503 Component component;
3505 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3506 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3507 String userId = request.getHeader(Constants.USER_ID_HEADER);
3508 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3509 ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3510 componentId = componentMetadataDataDefinition.getUniqueId();
3511 String componentName = componentMetadataDataDefinition.getName();
3512 if (!componentMetadataDataDefinition.getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3513 component = checkoutParentComponent(componentType, componentId, userId);
3514 if (component != null) {
3515 componentId = component.getUniqueId();
3516 componentName = component.getName();
3519 resourceCommonInfo.setResourceName(componentName);
3520 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null,
3522 return actionResult.left().value();
3526 * upload an artifact to a resource instance by UUID
3530 * @param componentType
3531 * @param componentUuid
3532 * @param resourceInstanceName
3536 public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3537 String resourceInstanceName, ArtifactOperationInfo operation) {
3538 Either<ArtifactDefinition, Operation> actionResult;
3539 Component component = null;
3540 String componentInstanceId;
3542 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3543 String userId = request.getHeader(Constants.USER_ID_HEADER);
3544 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3545 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid,
3546 resourceInstanceName);
3547 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3548 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3550 if (component == null) {
3551 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3553 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3555 componentInstanceId = componentRiPair.getRight().getUniqueId();
3556 componentId = componentRiPair.getLeft().getUniqueId();
3557 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3558 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5,
3559 data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3560 return actionResult.left().value();
3564 * updates an artifact on a component by UUID
3568 * @param componentType
3569 * @param componentUuid
3570 * @param artifactUUID
3571 * @param resourceCommonInfo
3572 * @param operation TODO
3575 public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3576 String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3577 ArtifactOperationInfo operation) {
3578 Either<ArtifactDefinition, Operation> actionResult;
3579 Component component;
3582 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3583 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3584 String userId = request.getHeader(Constants.USER_ID_HEADER);
3585 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3586 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3587 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3588 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3589 component = checkoutParentComponent(componentType, componentId, userId);
3590 if (component != null) {
3591 componentId = component.getUniqueId();
3592 componentName = component.getName();
3595 resourceCommonInfo.setResourceName(componentName);
3596 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3597 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null,
3599 if (actionResult.isRight()) {
3600 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult.right().value());
3602 return actionResult.left().value();
3606 * updates an artifact on a resource instance by UUID
3610 * @param componentType
3611 * @param componentUuid
3612 * @param resourceInstanceName
3613 * @param artifactUUID
3614 * @param operation TODO
3617 public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3618 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3619 Either<ArtifactDefinition, Operation> actionResult;
3620 Component component = null;
3621 String componentInstanceId;
3624 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3625 String userId = request.getHeader(Constants.USER_ID_HEADER);
3626 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3627 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3628 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3629 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3631 if (component == null) {
3632 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3634 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3636 componentInstanceId = componentRiPair.getRight().getUniqueId();
3637 componentId = componentRiPair.getLeft().getUniqueId();
3638 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3639 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3640 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo,
3641 origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3642 return actionResult.left().value();
3645 private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid,
3646 ArtifactDefinition artifactInfo) {
3647 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3648 if (componentStorageOperationStatusEither.isRight()) {
3649 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3650 log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
3651 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3653 Component storedComponent = componentStorageOperationStatusEither.left().value();
3654 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3655 .getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
3656 if (!optionalInterface.isPresent()) {
3657 log.debug("Failed to get resource interface for resource Id {}", componentId);
3658 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
3660 //fetch the operation from storage
3661 InterfaceDefinition gotInterface = optionalInterface.get();
3662 Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
3663 Optional<Operation> optionalOperation = operationsMap.values().stream().filter(o -> o.getUniqueId().equals(operationUuid)).findFirst();
3664 if (!optionalOperation.isPresent()) {
3665 log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
3666 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
3667 return Either.right(responseFormat);
3669 Operation operation = optionalOperation.get();
3670 ArtifactDefinition implementationArtifact = operation.getImplementationArtifact();
3671 implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
3672 implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
3673 implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
3674 implementationArtifact.setDescription(artifactInfo.getDescription());
3675 implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
3676 implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
3677 implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
3678 implementationArtifact.setEsId(artifactInfo.getEsId());
3679 operation.setImplementation(implementationArtifact);
3680 gotInterface.setOperationsMap(operationsMap);
3681 Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = interfaceOperation
3682 .updateInterfaces(storedComponent, Collections.singletonList(gotInterface));
3683 if (interfaceDefinitionStorageOperationStatusEither.isRight()) {
3684 StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
3685 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
3686 return Either.right(componentsUtils.getResponseFormat(actionStatus));
3688 return Either.left(artifactInfo);
3692 * updates an artifact on a component by UUID
3696 * @param componentType
3697 * @param componentUuid
3698 * @param artifactUUID
3702 public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(String data, HttpServletRequest request,
3703 ComponentTypeEnum componentType,
3704 String componentUuid, String interfaceUUID,
3705 String operationUUID, String artifactUUID,
3706 ResourceCommonInfo resourceCommonInfo,
3707 ArtifactOperationInfo operation) {
3708 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
3709 Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
3710 String componentId = null;
3711 ArtifactDefinition existingArtifactInfo = null;
3712 String interfaceName = null;
3713 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3714 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3715 String userId = request.getHeader(Constants.USER_ID_HEADER);
3716 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3717 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(as));
3720 if (errorWrapper.isEmpty()) {
3721 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3722 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3723 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3724 Component component = checkoutParentComponent(componentType, componentId, userId);
3725 if (component != null) {
3726 componentId = component.getUniqueId();
3727 componentName = component.getName();
3730 resourceCommonInfo.setResourceName(componentName);
3732 if (errorWrapper.isEmpty()) {
3733 Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
3734 if (interfaceNameEither.isRight()) {
3735 errorWrapper.setInnerElement(interfaceNameEither.right().value());
3737 interfaceName = interfaceNameEither.left().value();
3739 if (errorWrapper.isEmpty()) {
3740 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
3741 if (toscaComponentEither.isRight()) {
3742 StorageOperationStatus status = toscaComponentEither.right().value();
3743 log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
3744 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
3746 if (errorWrapper.isEmpty()) {
3747 NodeTypeEnum parentType = convertParentType(componentType);
3748 final List<ArtifactDefinition> existingDeploymentArtifacts = getDeploymentArtifacts(toscaComponentEither.left().value(), null);
3749 for (ArtifactDefinition artifactDefinition : existingDeploymentArtifacts) {
3750 if (artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())) {
3751 existingArtifactInfo = artifactDefinition;
3755 if (existingArtifactInfo != null) {
3756 return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
3761 if (errorWrapper.isEmpty()) {
3762 updateArtifactResult = handleArtifactRequestAndFlatten(componentId, userId, componentType, operation, artifactUUID, artifactInfo, origMd5,
3763 data, interfaceName, operationUUID);
3765 updateArtifactResult = Either.right(errorWrapper.getInnerElement());
3767 return updateArtifactResult;
3770 private Either<ArtifactDefinition, ResponseFormat> handleArtifactRequestAndFlatten(String componentId, String userId,
3771 ComponentTypeEnum componentType,
3772 ArtifactOperationInfo operation, String artifactId,
3773 ArtifactDefinition artifactInfo, String origMd5,
3774 String originData, String interfaceName,
3775 String operationName) {
3777 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
3778 operationName, null, null).right().map(op -> {
3779 log.debug("Unexpected value returned while calling handleArtifactRequest: {}", op);
3780 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3782 } catch (ComponentException e) {
3783 return Either.right(e.getResponseFormat());
3787 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid) {
3788 return fetchLatestComponentMetadataOrThrow(componentType, componentUuid, componentUuid);
3791 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid,
3792 String resourceInstanceName) {
3793 return fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3794 throw new ByActionStatusComponentException(as, resourceInstanceName);
3798 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadata(ComponentTypeEnum componentType, String componentUuid) {
3799 return toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true).right().map(sos -> {
3800 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, sos);
3801 return componentsUtils.convertFromStorageResponse(sos, componentType);
3805 private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
3806 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3807 if (componentStorageOperationStatusEither.isRight()) {
3808 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3809 log.debug("Failed to fetch component information by component id, error {}", errorStatus);
3810 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3812 Component storedComponent = componentStorageOperationStatusEither.left().value();
3813 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3814 .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
3815 if (!optionalInterface.isPresent()) {
3816 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
3818 return Either.left(optionalInterface.get().getType());
3822 * deletes an artifact on a component by UUID
3825 * @param componentType
3826 * @param componentUuid
3827 * @param artifactUUID
3828 * @param resourceCommonInfo
3829 * @param operation TODO
3832 public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3833 String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3834 ArtifactOperationInfo operation) {
3835 Either<ArtifactDefinition, Operation> actionResult;
3836 Component component;
3839 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3840 String userId = request.getHeader(Constants.USER_ID_HEADER);
3841 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3842 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3843 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3844 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3845 component = checkoutParentComponent(componentType, componentId, userId);
3846 if (component != null) {
3847 componentId = component.getUniqueId();
3848 componentName = component.getName();
3851 resourceCommonInfo.setResourceName(componentName);
3852 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3853 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
3854 return actionResult.left().value();
3858 * deletes an artifact from a resource instance by UUID
3861 * @param componentType
3862 * @param componentUuid
3863 * @param resourceInstanceName
3864 * @param artifactUUID
3865 * @param operation TODO
3868 public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3869 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3870 Either<ArtifactDefinition, Operation> actionResult;
3871 Component component = null;
3872 String componentInstanceId;
3875 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3876 String userId = request.getHeader(Constants.USER_ID_HEADER);
3877 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3878 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3879 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3880 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3882 if (component == null) {
3883 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3885 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3887 componentInstanceId = componentRiPair.getRight().getUniqueId();
3888 componentId = componentRiPair.getLeft().getUniqueId();
3889 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3890 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5,
3891 null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3892 return actionResult.left().value();
3895 private String findArtifactId(ComponentInstance instance, String artifactUUID) {
3896 String artifactId = null;
3897 ArtifactDefinition foundArtifact = null;
3898 if (instance.getDeploymentArtifacts() != null) {
3899 foundArtifact = instance.getDeploymentArtifacts().values().stream()
3900 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3902 if (foundArtifact == null && instance.getArtifacts() != null) {
3903 foundArtifact = instance.getArtifacts().values().stream()
3904 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3906 if (foundArtifact == null) {
3907 log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
3908 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
3910 artifactId = foundArtifact.getUniqueId();
3915 @SuppressWarnings("unchecked")
3916 public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact, String envType,
3917 String parentId, NodeTypeEnum parentType, String parentName, User user, Component component,
3918 Map<String, String> existingEnvVersions) {
3919 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
3920 .getDeploymentResourceInstanceArtifacts();
3921 if (deploymentResourceArtifacts == null) {
3922 log.debug("no deployment artifacts are configured for generated artifacts");
3923 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3925 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
3926 if (placeHolderData == null) {
3927 log.debug("no env type {} are configured for generated artifacts", envType);
3928 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3930 String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
3931 ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user.getUserId(),
3932 ArtifactGroupTypeEnum.DEPLOYMENT, true);
3933 ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
3934 artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
3935 artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
3936 artifactHeatEnv.setTimeout(0);
3937 artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
3938 buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
3939 // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
3940 handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
3941 ArtifactDefinition heatEnvPlaceholder;
3942 // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
3943 if (parentType != NodeTypeEnum.ResourceInstance) {
3944 String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
3945 artifactHeatEnv.setArtifactChecksum(checkSum);
3946 Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component,
3947 parentType, parentId);
3948 if (addHeatEnvArtifact.isRight()) {
3949 log.debug("failed to create heat env artifact on resource instance");
3950 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(
3951 componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact.right().value(), false), "", null));
3953 heatEnvPlaceholder = createArtifactPlaceHolder;
3955 heatEnvPlaceholder = artifactHeatEnv;
3956 artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
3957 setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
3959 ComponentTypeEnum componentType = component.getComponentType();
3960 if (parentType == NodeTypeEnum.ResourceInstance) {
3961 componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
3963 createdArtifacts.add(heatEnvPlaceholder);
3964 componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
3965 new ResourceCommonInfo(parentName, componentType.getValue()), ResourceVersionInfo.newBuilder().build(),
3966 ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(), null, heatEnvPlaceholder, null);
3967 return heatEnvPlaceholder;
3970 private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
3971 if (artifact.getListHeatParameters() == null) {
3974 List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
3975 for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
3976 HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
3977 heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
3978 heatEnvParameter.setCurrentValue(null);
3979 heatEnvParameters.add(heatEnvParameter);
3981 artifactDefinition.setListHeatParameters(heatEnvParameters);
3984 private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
3985 String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
3986 String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
3987 String name = heatArtifact.getArtifactName();
3990 name = heatArtifact.getArtifactLabel();
3991 fileName = name + "." + envExtension;
3993 fileName = name.replaceAll("." + heatExtension, "." + envExtension);
3995 heatEnvArtifact.setArtifactName(fileName);
3998 private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
3999 if (null != existingEnvVersions) {
4000 String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
4001 if (null != prevVersion) {
4002 heatEnvArtifact.setArtifactVersion(prevVersion);
4007 public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user,
4008 List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4009 ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4010 ComponentTypeEnum componentType = component.getComponentType();
4011 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4012 Either<ArtifactDefinition, Operation> result;
4014 for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4015 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4016 uploadedArtifacts.add(result.left().value());
4018 } catch (ComponentException e) {
4019 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component.getName(), e.getResponseFormat());
4020 if (operation.isCreateOrLink()) {
4021 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4025 return uploadedArtifacts;
4028 public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Component component, User user, ArtifactOperationInfo operation,
4029 boolean shouldLock, boolean inTransaction, ComponentTypeEnum componentType,
4030 ArtifactDefinition artifactDefinition) {
4031 AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4032 String componentId = component.getUniqueId();
4033 String artifactId = artifactDefinition.getUniqueId();
4034 Either<ArtifactDefinition, Operation> result;
4035 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4036 //artifact validation
4037 artifactDefinition = validateArtifact(componentId, componentType, operation, artifactId, artifactDefinition, auditingAction, user, component,
4038 shouldLock, inTransaction);
4039 switch (operation.getArtifactOperationEnum()) {
4041 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType,
4042 component, null, null);
4043 result = createArtifact(component, componentId, artifactDefinition, validPayload, componentType, auditingAction, null, null);
4046 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component,
4048 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4049 auditingAction, user, component, true);
4052 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4055 if (artifactGenerationRequired(component, artifactDefinition)) {
4056 result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4058 result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4062 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4065 throw new UnsupportedOperationException(
4066 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4071 public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component,
4072 User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4073 ArtifactOperationInfo operation, boolean shouldLock,
4074 boolean inTransaction) {
4075 List<ArtifactDefinition> handleArtifactsResult;
4076 ComponentTypeEnum componentType = component.getComponentType();
4077 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4078 Either<ArtifactDefinition, Operation> actionResult;
4082 for (ArtifactDefinition artifact : artifactsToHandle) {
4083 originData = ArtifactUtils.buildJsonStringForCsarVfcArtifact(artifact);
4084 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4085 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact.getUniqueId(),
4086 artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4087 uploadedArtifacts.add(actionResult.left().value());
4089 handleArtifactsResult = uploadedArtifacts;
4090 } catch (ComponentException e) {
4091 if (operation.isCreateOrLink()) {
4092 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4096 return handleArtifactsResult;
4099 private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName) {
4100 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4101 Option<Component> oComponent = Option.of(getComponentByUuid(componentType, componentUuid));
4102 return oComponent.toTry(componentNotFound(componentType, componentUuid)).flatMap(
4103 component -> findFirstMatching(component, ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4104 .toTry(componentInstanceNotFound(componentType, resourceInstanceName, component))).get();
4107 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName) {
4108 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4109 ComponentInstance componentInstance = findFirstMatching(component,
4110 ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4111 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4112 return new ImmutablePair<>(component, componentInstance);
4115 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid,
4116 String resourceInstanceName) {
4117 Component component = getLatestComponentByUuid(componentType, componentUuid);
4118 ComponentInstance componentInstance = findFirstMatching(component, ci -> ci.getNormalizedName().equals(resourceInstanceName))
4119 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4120 return new ImmutablePair<>(component, componentInstance);
4123 private Supplier<Throwable> componentNotFound(ComponentTypeEnum componentType, String componentUuid) {
4125 log.debug(FAILED_FETCH_COMPONENT, componentType.getValue(), componentUuid);
4126 return new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentUuid);
4130 private Supplier<Throwable> componentInstanceNotFound(ComponentTypeEnum componentType, String resourceInstanceName, Component component) {
4132 log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4133 return new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4134 RESOURCE_INSTANCE, componentType.getValue(), component.getName());
4138 private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4139 ImmutablePair<String, byte[]> downloadArtifact;
4140 List<ArtifactDefinition> artifactsList = null;
4141 ArtifactDefinition deploymentArtifact;
4142 if (artifacts != null && !artifacts.isEmpty()) {
4143 artifactsList = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID))
4144 .collect(Collectors.toList());
4146 if (artifactsList == null || artifactsList.isEmpty()) {
4147 log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4148 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4150 deploymentArtifact = artifactsList.get(0);
4151 downloadArtifact = downloadArtifact(deploymentArtifact);
4152 log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4153 return downloadArtifact.getRight();
4156 private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4157 Component component;
4158 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4159 if (getComponentRes.isRight()) {
4160 StorageOperationStatus status = getComponentRes.right().value();
4161 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4162 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4164 component = getComponentRes.left().value();
4169 private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4170 Component component;
4171 Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4172 if (getComponentRes.isRight()) {
4173 StorageOperationStatus status = getComponentRes.right().value();
4174 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4175 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4177 List<Component> value = getComponentRes.left().value();
4178 if (value.isEmpty()) {
4179 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4180 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4181 throw new ByActionStatusComponentException(status);
4183 component = value.get(0);
4189 private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4190 ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4191 StorageOperationStatus storageStatus;
4192 ArtifactDefinition latestArtifact;
4193 List<ArtifactDefinition> artifacts;
4194 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4195 if (getArtifactsRes.isRight()) {
4196 storageStatus = getArtifactsRes.right().value();
4197 log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4198 if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4199 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4201 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4203 artifacts = getArtifactsRes.left().value().values().stream()
4204 .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList());
4205 if (artifacts == null || artifacts.isEmpty()) {
4206 log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4207 parentId, actionStatus);
4208 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4210 latestArtifact = artifacts.stream().max((a1, a2) -> {
4211 int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4212 if (compareRes == 0) {
4213 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(),
4214 a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate());
4218 if (latestArtifact == null) {
4219 log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4220 parentId, actionStatus);
4221 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4223 return latestArtifact.getUniqueId();
4226 private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4227 Component component = null;
4228 User modifier = userBusinessLogic.getUser(userId, false);
4229 LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout",
4230 LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4231 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
4232 .changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4233 if (checkoutRes.isRight()) {
4234 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId,
4235 checkoutRes.right().value().getStatus());
4236 throw new ByResponseFormatComponentException(checkoutRes.right().value());
4238 return checkoutRes.left().value();
4242 void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4243 this.nodeTemplateOperation = nodeTemplateOperation;
4246 public List<ArtifactConfiguration> getConfiguration() {
4247 return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
4250 public enum ArtifactOperationEnum {
4251 CREATE, UPDATE, DELETE, DOWNLOAD, LINK;
4253 public static boolean isCreateOrLink(ArtifactOperationEnum operation) {
4254 return operation == CREATE || operation == LINK;