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.Component;
92 import org.openecomp.sdc.be.model.ComponentInstance;
93 import org.openecomp.sdc.be.model.ComponentParametersView;
94 import org.openecomp.sdc.be.model.GroupDefinition;
95 import org.openecomp.sdc.be.model.GroupInstance;
96 import org.openecomp.sdc.be.model.HeatParameterDefinition;
97 import org.openecomp.sdc.be.model.InterfaceDefinition;
98 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
99 import org.openecomp.sdc.be.model.LifecycleStateEnum;
100 import org.openecomp.sdc.be.model.Operation;
101 import org.openecomp.sdc.be.model.Resource;
102 import org.openecomp.sdc.be.model.Service;
103 import org.openecomp.sdc.be.model.User;
104 import org.openecomp.sdc.be.model.heat.HeatParameterType;
105 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
106 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
107 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeTemplateOperation;
108 import org.openecomp.sdc.be.model.operations.StorageException;
109 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
110 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
111 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
112 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
113 import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation;
114 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
115 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
116 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
117 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
118 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
119 import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation;
120 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
121 import org.openecomp.sdc.be.resources.data.DAOArtifactData;
122 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
123 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
124 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
125 import org.openecomp.sdc.be.servlets.RepresentationUtils;
126 import org.openecomp.sdc.be.tosca.CsarUtils;
127 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
128 import org.openecomp.sdc.be.user.Role;
129 import org.openecomp.sdc.be.user.UserBusinessLogic;
130 import org.openecomp.sdc.be.utils.TypeUtils;
131 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
132 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
133 import org.openecomp.sdc.common.api.Constants;
134 import org.openecomp.sdc.common.datastructure.Wrapper;
135 import org.openecomp.sdc.common.log.wrappers.Logger;
136 import org.openecomp.sdc.common.util.GeneralUtility;
137 import org.openecomp.sdc.common.util.ValidationUtils;
138 import org.openecomp.sdc.common.util.YamlToObjectConverter;
139 import org.openecomp.sdc.exception.ResponseFormat;
140 import org.springframework.beans.factory.annotation.Autowired;
141 import org.yaml.snakeyaml.Yaml;
143 @org.springframework.stereotype.Component("artifactBusinessLogic")
144 public class ArtifactsBusinessLogic extends BaseBusinessLogic {
146 public static final String HEAT_ENV_NAME = "heatEnv";
147 public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
148 public static final String HEAT_ENV_SUFFIX = "env";
149 public static final String ARTIFACT_ACTION_LOCK = "Artifact action - lock ";
150 public static final String FAILED_UPLOAD_ARTIFACT_TO_COMPONENT = "Failed to upload artifact to component with type {} and uuid {}. Status is {}. ";
151 public static final String COMPONENT_INSTANCE_NOT_FOUND = "Component instance {} was not found for component {}";
152 private static final String RESOURCE_INSTANCE = "resource instance";
153 private static final String ARTIFACT_TYPE_OTHER = "OTHER";
154 private static final String ARTIFACT_DESCRIPTION = "artifact description";
155 private static final String ARTIFACT_LABEL = "artifact label";
156 private static final String ARTIFACT_URL = "artifact url";
157 private static final String ARTIFACT_NAME = "artifact name";
158 private static final String ARTIFACT_PAYLOAD = "artifact payload";
159 private static final String ARTIFACT_PLACEHOLDER_TYPE = "type";
160 private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
161 private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
162 private static final String ARTIFACT_PLACEHOLDER_FILE_EXTENSION = "fileExtension";
163 private static final Logger log = Logger.getLogger(ArtifactsBusinessLogic.class.getName());
164 private static final String FAILED_UPDATE_GROUPS = "Failed to update groups of the component {}. ";
165 private static final String FAILED_SAVE_ARTIFACT = "Failed to save the artifact.";
166 private static final String FAILED_FETCH_COMPONENT = "Could not fetch component with type {} and uuid {}. Status is {}. ";
167 private static final String NULL_PARAMETER = "One of the function parameteres is null";
168 private static final String ROLLBACK = "all changes rollback";
169 private static final String COMMIT = "all changes committed";
170 private static final String UPDATE_ARTIFACT = "Update Artifact";
171 private static final String FOUND_DEPLOYMENT_ARTIFACT = "Found deployment artifact {}";
172 private static final String VALID_ARTIFACT_LABEL_NAME = "'A-Z', 'a-z', '0-9', '-', '@', '+' and space.";
173 private Gson gson = new GsonBuilder().setPrettyPrinting().create();
174 @javax.annotation.Resource
175 private IInterfaceLifecycleOperation interfaceLifecycleOperation;
176 @javax.annotation.Resource
177 private UserAdminOperation userOperaton;
178 @javax.annotation.Resource
179 private IElementOperation elementOperation;
180 @javax.annotation.Resource
181 private IHeatParametersOperation heatParametersOperation;
182 private ArtifactCassandraDao artifactCassandraDao;
183 private ToscaExportHandler toscaExportUtils;
184 private CsarUtils csarUtils;
185 private LifecycleBusinessLogic lifecycleBusinessLogic;
186 private UserBusinessLogic userBusinessLogic;
187 private ArtifactsResolver artifactsResolver;
188 private NodeTemplateOperation nodeTemplateOperation;
191 public ArtifactsBusinessLogic(ArtifactCassandraDao artifactCassandraDao, ToscaExportHandler toscaExportUtils, CsarUtils csarUtils,
192 LifecycleBusinessLogic lifecycleBusinessLogic, UserBusinessLogic userBusinessLogic,
193 ArtifactsResolver artifactsResolver, IElementOperation elementDao, IGroupOperation groupOperation,
194 IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation,
195 InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
196 ArtifactsOperations artifactToscaOperation) {
197 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
198 artifactToscaOperation);
199 this.artifactCassandraDao = artifactCassandraDao;
200 this.toscaExportUtils = toscaExportUtils;
201 this.csarUtils = csarUtils;
202 this.lifecycleBusinessLogic = lifecycleBusinessLogic;
203 this.userBusinessLogic = userBusinessLogic;
204 this.artifactsResolver = artifactsResolver;
207 public static <R> Either<Boolean, R> ifTrue(boolean predicate, Supplier<Either<Boolean, R>> ifTrue) {
208 return predicate ? ifTrue.get() : Either.left(false);
211 public static <L, R> Either<L, R> forEach(Either<L, R> e, Consumer<L> c) {
212 return e.left().map(l -> {
218 private static Option<ComponentInstance> findFirstMatching(Component component, Predicate<ComponentInstance> filter) {
219 return Option.ofOptional(component.getComponentInstances().stream().filter(filter).findFirst());
223 public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
224 ArtifactOperationInfo operation, String artifactId,
225 ArtifactDefinition artifactInfo, String origMd5, String originData,
226 String interfaceName, String operationName, String parentId,
227 String containerComponentType, boolean shouldLock, boolean inTransaction) {
228 // step 1 - detect auditing type
229 AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
230 // step 2 - check header
231 if (userId == null) {
232 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
233 log.debug("handleArtifactRequest - no HTTP_CSP_HEADER , component id {}", componentId);
234 handleAuditing(auditingAction, null, componentId, null, null, null, artifactId, responseFormat, componentType, null);
235 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
237 // step 3 - check user existence
239 // step 4 - check user's role
240 User user = validateUserExists(userId, auditingAction, componentId, artifactId, componentType, inTransaction);
241 validateUserRole(user, auditingAction, componentId, artifactId, componentType, operation);
244 // 5. check service/resource existence
246 // 6. check service/resource check out
248 // 7. user is owner of checkout state
249 Component component = null;
250 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
251 component = validateComponentExists(realComponentId, auditingAction, user, artifactId, componentType, containerComponentType);
252 validateWorkOnComponent(component, userId, auditingAction, user, artifactId, operation);
253 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
254 validateResourceInstanceById(component, componentId);
257 return validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
258 operationName, user, component, shouldLock, inTransaction, true);
261 public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
262 ArtifactOperationInfo operation, String artifactId,
263 ArtifactDefinition artifactInfo, String origMd5, String originData,
264 String interfaceName, String operationName, String parentId,
265 String containerComponentType) {
266 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
267 operationName, parentId, containerComponentType, true, false);
271 * This Method validates only the Artifact and does not validate user / role / component ect...<br> For regular usage use <br> {@link
272 * #handleArtifactRequest(String, String, ComponentTypeEnum, ArtifactOperationInfo, String, ArtifactDefinition, String, String, String, String,
277 public Either<ArtifactDefinition, Operation> validateAndHandleArtifact(String componentUniqueId, ComponentTypeEnum componentType,
278 ArtifactOperationInfo operation, String artifactUniqueId,
279 ArtifactDefinition artifactDefinition, String origMd5, String originData,
280 String interfaceName, String operationName, User user, Component component,
281 boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
282 AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
283 artifactDefinition = validateArtifact(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, auditingAction, user,
284 component, shouldLock, inTransaction);
286 Either<ArtifactDefinition, Operation> result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition,
287 origMd5, originData, interfaceName, operationName, auditingAction, user, component, shouldLock, inTransaction, needUpdateGroup);
288 //TODO: audit positive action
293 ArtifactDefinition validateArtifact(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId,
294 ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, User user, Component component,
295 boolean shouldLock, boolean inTransaction) {
296 ArtifactDefinition artifactInfoToReturn = artifactInfo;
297 ArtifactOperationEnum operationEnum = operation.getArtifactOperationEnum();
298 if (operationEnum == ArtifactOperationEnum.UPDATE || operationEnum == ArtifactOperationEnum.DELETE
299 || operationEnum == ArtifactOperationEnum.DOWNLOAD) {
300 ArtifactDefinition dbArtifact = getArtifactIfBelongsToComponent(componentId, componentType, artifactId, component);
301 if (operation.isDownload()) {
302 artifactInfoToReturn = dbArtifact;
303 handleHeatEnvDownload(componentId, componentType, user, component, dbArtifact, shouldLock, inTransaction);
306 return artifactInfoToReturn;
310 void handleHeatEnvDownload(String componentId, ComponentTypeEnum componentType, User user, Component component,
311 ArtifactDefinition artifactDefinition, boolean shouldLock, boolean inTransaction) {
312 if (artifactDefinition.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType()) && ComponentTypeEnum.SERVICE == component
313 .getComponentType()) {
314 ComponentInstance componentInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId))
315 .findAny().orElse(null);
316 if (componentInstance == null) {
317 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentId, "instance", "Service",
318 component.getName());
320 Map<String, ArtifactDefinition> deploymentArtifacts = componentInstance.getDeploymentArtifacts();
321 ArtifactDefinition heatEnvWithHeatParams = deploymentArtifacts.values().stream()
322 .filter(p -> p.getUniqueId().equals(artifactDefinition.getUniqueId())).findAny().orElse(null);
323 Either<ArtifactDefinition, ResponseFormat> eitherGenerated = generateHeatEnvArtifact(heatEnvWithHeatParams, componentType, component,
324 componentInstance.getName(), user, componentId, shouldLock, inTransaction);
325 if (eitherGenerated.isRight()) {
326 throw new ByResponseFormatComponentException((eitherGenerated.right().value()));
331 private boolean artifactGenerationRequired(Component component, ArtifactDefinition artifactInfo) {
332 boolean needGenerate;
333 needGenerate = artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && (
334 component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN
335 || component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
336 needGenerate = needGenerate || (ComponentTypeEnum.RESOURCE == component.getComponentType() && (
337 artifactInfo.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType()) || isAbstractVfcEmptyCsar((Resource) component,
342 private boolean isAbstractVfcEmptyCsar(Resource resource, ArtifactDefinition artifactInfo) {
343 return resource.isAbstract() && artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && artifactInfo.getArtifactType()
344 .equals(ArtifactTypeEnum.TOSCA_CSAR.getType()) && StringUtils.isEmpty(artifactInfo.getArtifactChecksum());
347 public Either<ArtifactDefinition, Operation> generateAndSaveToscaArtifact(ArtifactDefinition artifactDefinition, Component component, User user,
348 boolean isInCertificationRequest, boolean shouldLock,
349 boolean inTransaction, boolean fetchTemplatesFromDB) {
350 return decodeToscaArtifactPayload(component, isInCertificationRequest, fetchTemplatesFromDB, artifactDefinition.getArtifactType()).left()
352 // TODO: Avoid output argument
353 artifactDefinition.setPayload(payload);
354 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
355 artifactDefinition.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(payload));
356 return lockComponentAndUpdateArtifact(component.getUniqueId(), artifactDefinition, AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE,
357 artifactDefinition.getUniqueId(), user, component.getComponentType(), component, payload, shouldLock, inTransaction);
358 }).right().map(ex -> {
359 // TODO: This should not be done but in order to keep this refactoring small enough, we stop here.
361 // Bubble up this exception
366 private Either<byte[], ComponentException> decodeToscaArtifactPayload(Component parent, boolean isInCertificationRequest,
367 boolean fetchTemplatesFromDB, String artifactType) {
368 log.debug("tosca artifact generation");
369 if (ArtifactTypeEnum.TOSCA_CSAR.getType().equals(artifactType)) {
370 return csarUtils.createCsar(parent, fetchTemplatesFromDB, isInCertificationRequest).right().map(error -> {
371 log.debug("Failed to generate tosca csar for component {} error {}", parent.getUniqueId(), error);
372 return new ByResponseFormatComponentException(error);
375 return toscaExportUtils.exportComponent(parent).left().map(toscaRepresentation -> {
376 log.debug("Tosca yaml exported for component {} ", parent.getUniqueId());
377 return toscaRepresentation.getMainYaml();
378 }).right().map(toscaError -> {
379 log.debug("Failed export tosca yaml for component {} error {}", parent.getUniqueId(), toscaError);
380 return new ByActionStatusComponentException(componentsUtils.convertFromToscaError(toscaError));
385 private Either<ArtifactDefinition, Operation> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
386 String artifactId, ArtifactDefinition artifactInfo, String origMd5, String originData,
387 String interfaceName, String operationName, AuditingActionEnum auditingAction, User user,
388 Component parent, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
389 if (interfaceName != null && operationName != null) {
390 interfaceName = interfaceName.toLowerCase();
391 operationName = operationName.toLowerCase();
394 lockComponent(componentType, artifactId, auditingAction, user, parent);
396 Either<ArtifactDefinition, Operation> result;
397 boolean operationSucceeded = false;
399 switch (operation.getArtifactOperationEnum()) {
401 if (artifactGenerationRequired(parent, artifactInfo)) {
402 result = Either.left(generateNotSavedArtifact(parent, artifactInfo));
404 result = Either.left(handleDownload(componentId, artifactId, componentType, parent));
408 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, parent));
411 result = handleUpdate(componentId, componentType, operation, artifactId, artifactInfo, null, origMd5, originData, interfaceName,
412 operationName, auditingAction, user, parent, needUpdateGroup);
415 result = handleCreate(componentId, artifactInfo, operation, auditingAction, user, componentType, parent, origMd5, originData,
416 interfaceName, operationName);
419 result = Either.left(handleLink(componentId, artifactInfo, componentType, parent));
422 throw new UnsupportedOperationException(
423 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
425 operationSucceeded = true;
428 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
432 private void lockComponent(ComponentTypeEnum componentType, String artifactId, AuditingActionEnum auditingAction, User user, Component parent) {
434 lockComponent(parent, ARTIFACT_ACTION_LOCK);
435 } catch (ComponentException e) {
436 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, null, null, artifactId, e.getResponseFormat(), componentType, null);
442 public Either<ArtifactDefinition, Operation> handleUpdate(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
443 String artifactId, ArtifactDefinition artifactInfo, byte[] decodedPayload,
444 String origMd5, String originData, String interfaceName, String operationName,
445 AuditingActionEnum auditingAction, User user, Component parent,
446 boolean needUpdateGroup) {
447 Either<ArtifactDefinition, Operation> result;
448 validateArtifactType(artifactInfo);
449 final String artifactType = artifactInfo.getArtifactType();
450 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && (ArtifactTypeEnum.HEAT.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_VOL
451 .getType().equals(artifactType) || ArtifactTypeEnum.HEAT_NET.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_ENV.getType()
452 .equals(artifactType))) {
453 result = handleUpdateHeatEnvAndHeatMeta(componentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, originData,
455 if (needUpdateGroup) {
456 ActionStatus error = updateGroupInstance(artifactInfo, result.left().value(), parent, componentId);
457 if (error != ActionStatus.OK) {
458 throw new ByActionStatusComponentException(error);
461 } else if (componentType == ComponentTypeEnum.RESOURCE && ArtifactTypeEnum.HEAT_ENV.getType().equals(artifactType)) {
462 result = handleUpdateHeatWithHeatEnvParams(componentId, artifactInfo, auditingAction, componentType, parent, originData, origMd5,
463 operation, needUpdateGroup);
465 if (decodedPayload == null) {
466 decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5,
467 originData, interfaceName, operationName);
469 result = updateArtifactFlow(parent, componentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
470 if (needUpdateGroup && result.isLeft()) {
471 ArtifactDefinition updatedArtifact = result.left().value();
472 updateGroupForHeat(artifactInfo, updatedArtifact, parent);
478 private void validateArtifactType(final ArtifactDefinition artifactInfo) {
479 if (!isArtifactSupported(artifactInfo.getArtifactType())) {
480 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
484 private void validateArtifactType(final ArtifactDefinition artifactInfo, final ComponentTypeEnum componentType) {
485 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactInfo.getArtifactType()).orElse(null);
486 if (artifactConfiguration == null) {
487 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
488 log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName());
489 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE);
490 throw new ByResponseFormatComponentException(responseFormat);
492 final ArtifactGroupTypeEnum artifactGroupType = artifactInfo.getArtifactGroupType();
494 validateArtifactType(componentType, artifactGroupType, artifactConfiguration);
495 } catch (final ComponentException e) {
496 log.debug("Artifact is invalid", e);
497 BeEcompErrorManager.getInstance()
498 .logBeInvalidTypeError("Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(),
499 "Artifact " + artifactInfo.getArtifactName());
500 log.debug("Not supported artifact type = {}", artifactInfo.getArtifactType());
501 final ResponseFormat responseFormat = componentsUtils
502 .getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
503 throw new ByResponseFormatComponentException(responseFormat);
507 private void validateArtifactType(final ComponentTypeEnum componentType, final ArtifactGroupTypeEnum groupType,
508 final ArtifactConfiguration artifactConfiguration) {
509 final boolean supportComponentType =
510 CollectionUtils.isNotEmpty(artifactConfiguration.getComponentTypes()) && artifactConfiguration.getComponentTypes().stream()
511 .anyMatch(componentType1 -> componentType1.getValue().equalsIgnoreCase(componentType.getValue()));
512 if (!supportComponentType) {
513 log.debug("Artifact Type '{}' not supported for Component Type '{}'", artifactConfiguration.getType(), componentType.getValue());
514 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
516 final boolean supportResourceType = artifactConfiguration.hasSupport(groupType);
517 if (!supportResourceType) {
518 log.debug("Artifact Type '{}' not supported for Component Type '{}' and Category '{}'", artifactConfiguration.getType(),
519 componentType.getValue(), groupType.getType());
520 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
524 private boolean isArtifactSupported(final String artifactType) {
525 final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
526 final List<ArtifactConfiguration> artifactConfigurationList = configuration.getArtifacts();
527 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
530 return artifactConfigurationList.stream().anyMatch(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType));
534 public ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent) {
535 List<GroupDefinition> groups = parent.getGroups();
536 if (groups != null && !groups.isEmpty()) {
537 List<GroupDataDefinition> groupToUpdate = groups.stream()
538 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfo.getUniqueId())).collect(Collectors.toList());
539 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
540 groupToUpdate.forEach(g -> {
541 g.getArtifacts().remove(artifactInfo.getUniqueId());
542 g.getArtifactsUuid().remove(artifactInfo.getArtifactUUID());
543 g.getArtifacts().add(artAfterUpdate.getUniqueId());
544 g.getArtifactsUuid().add(artAfterUpdate.getArtifactUUID());
545 if (!artifactInfo.getArtifactUUID().equals(artAfterUpdate.getArtifactUUID())) {
546 g.setGroupUUID(UniqueIdBuilder.generateUUID());
549 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
550 if (status.isRight()) {
551 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
552 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status.right().value()));
556 return ActionStatus.OK;
560 ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfoHeat, ArtifactDefinition artHeatAfterUpdate, ArtifactDefinition artifactInfoHeatE,
561 ArtifactDefinition artHEAfterUpdate, Component parent) {
562 List<GroupDefinition> groups = parent.getGroups();
563 if (groups != null && !groups.isEmpty()) {
564 List<GroupDataDefinition> groupToUpdate = groups.stream()
565 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfoHeat.getUniqueId())).collect(Collectors.toList());
566 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
567 groupToUpdate.forEach(g -> {
568 g.getArtifacts().remove(artifactInfoHeat.getUniqueId());
569 g.getArtifactsUuid().remove(artifactInfoHeat.getArtifactUUID());
570 g.getArtifacts().remove(artifactInfoHeatE.getUniqueId());
571 g.getArtifacts().add(artHeatAfterUpdate.getUniqueId());
572 g.getArtifactsUuid().add(artHeatAfterUpdate.getArtifactUUID());
573 g.getArtifacts().add(artHEAfterUpdate.getUniqueId());
575 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
576 if (status.isRight()) {
577 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
578 return componentsUtils.convertFromStorageResponse(status.right().value());
582 return ActionStatus.OK;
585 private ActionStatus updateGroupInstance(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent, String parentId) {
586 List<GroupInstance> updatedGroupInstances = new ArrayList<>();
587 List<GroupInstance> groupInstances = null;
588 Optional<ComponentInstance> componentInstOp = parent.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(parentId))
590 if (componentInstOp.isPresent()) {
591 groupInstances = componentInstOp.get().getGroupInstances();
593 if (CollectionUtils.isNotEmpty(groupInstances)) {
594 boolean isUpdated = false;
595 for (GroupInstance groupInstance : groupInstances) {
597 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifacts()) && groupInstance.getGroupInstanceArtifacts()
598 .contains(artifactInfo.getUniqueId())) {
599 groupInstance.getGroupInstanceArtifacts().remove(artifactInfo.getUniqueId());
600 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getUniqueId());
603 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifactsUuid()) && groupInstance.getGroupInstanceArtifactsUuid()
604 .contains(artifactInfo.getArtifactUUID())) {
605 groupInstance.getGroupInstanceArtifactsUuid().remove(artifactInfo.getArtifactUUID());
606 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getArtifactUUID());
610 updatedGroupInstances.add(groupInstance);
614 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
615 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
616 if (status.isRight()) {
617 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
618 return componentsUtils.convertFromStorageResponse(status.right().value());
620 return ActionStatus.OK;
623 ArtifactDefinition generateNotSavedArtifact(Component parent, ArtifactDefinition artifactDefinition) {
624 if (artifactDefinition.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA) {
625 Either<byte[], ComponentException> decodedPayload = decodeToscaArtifactPayload(parent, false, false,
626 artifactDefinition.getArtifactType());
627 // TODO: This should not be done, but in order to keep this refactoring relatively small, we stop here
628 if (decodedPayload.isRight()) {
629 throw decodedPayload.right().value();
631 artifactDefinition.setPayload(decodedPayload.left().value());
632 return artifactDefinition;
635 String heatArtifactId = artifactDefinition.getGeneratedFromId();
636 Either<ArtifactDefinition, StorageOperationStatus> heatRes = artifactToscaOperation.getArtifactById(parent.getUniqueId(), heatArtifactId);
637 if (heatRes.isRight()) {
638 log.debug("Failed to fetch heat artifact by generated id {} for heat env {}", heatArtifactId, artifactDefinition.getUniqueId());
639 throw new StorageException(heatRes.right().value());
641 String generatedPayload = generateHeatEnvPayload(heatRes.left().value());
642 artifactDefinition.setPayloadData(generatedPayload);
643 return artifactDefinition;
647 private Either<ArtifactDefinition, Operation> handleUpdateHeatWithHeatEnvParams(String componentId, ArtifactDefinition artifactInfo,
648 AuditingActionEnum auditingAction,
649 ComponentTypeEnum componentType, Component parent,
650 String originData, String origMd5,
651 ArtifactOperationInfo operation, boolean needToUpdateGroup) {
652 Either<ArtifactDefinition, StorageOperationStatus> artifactHeatRes = artifactToscaOperation
653 .getArtifactById(componentId, artifactInfo.getGeneratedFromId());
654 ArtifactDefinition currHeatArtifact = artifactHeatRes.left().value();
655 if (origMd5 != null) {
656 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
657 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
658 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
659 } else { // duplicate
660 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
663 return updateHeatParams(componentId, artifactInfo, auditingAction, parent, componentType, currHeatArtifact, needToUpdateGroup);
666 private void handleLockingAndCommit(Component parent, boolean shouldLock, boolean inTransaction, boolean actionSucceeded) {
667 if (actionSucceeded) {
669 if (!inTransaction) {
670 janusGraphDao.commit();
674 if (!inTransaction) {
675 janusGraphDao.rollback();
679 graphLockOperation.unlockComponent(parent.getUniqueId(), parent.getComponentType().getNodeType());
683 public ImmutablePair<String, byte[]> handleDownloadToscaModelRequest(Component component, ArtifactDefinition csarArtifact) {
684 if (artifactGenerationRequired(component, csarArtifact)) {
685 Either<byte[], ResponseFormat> generated = csarUtils.createCsar(component, false, false);
686 if (generated.isRight()) {
687 log.debug("Failed to export tosca csar for component {} error {}", component.getUniqueId(), generated.right().value());
688 throw new ByResponseFormatComponentException(generated.right().value());
690 return new ImmutablePair<>(csarArtifact.getArtifactName(), generated.left().value());
692 return downloadArtifact(csarArtifact);
695 public ImmutablePair<String, byte[]> handleDownloadRequestById(String componentId, String artifactId, String userId,
696 ComponentTypeEnum componentType, String parentId, String containerComponentType) {
697 // perform all validation in common flow
698 Either<ArtifactDefinition, Operation> result = handleArtifactRequest(componentId, userId, componentType,
699 new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DOWNLOAD), artifactId, null, null, null, null, null, parentId,
700 containerComponentType);
701 ArtifactDefinition artifactDefinition;
702 Either<ArtifactDefinition, Operation> insideValue = result;
703 if (insideValue.isLeft()) {
704 artifactDefinition = insideValue.left().value();
706 artifactDefinition = insideValue.right().value().getImplementationArtifact();
708 // for tosca artifacts and heat env on VF level generated on download without saving
709 if (artifactDefinition.getPayloadData() != null) {
710 return (new ImmutablePair<>(artifactDefinition.getArtifactName(), artifactDefinition.getPayloadData()));
712 return downloadArtifact(artifactDefinition);
715 public Map<String, ArtifactDefinition> handleGetArtifactsByType(String containerComponentType, String parentId, ComponentTypeEnum componentType,
716 String componentId, String artifactGroupType, String userId) {
719 // detect auditing type
720 Map<String, ArtifactDefinition> resMap = null;
725 if (userId == null) {
726 log.debug("handleGetArtifactsByType - no HTTP_CSP_HEADER , component id {}", componentId);
727 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
731 // check user existence
736 validateUserExists(userId);
739 // 5. check service/resource existence
741 // 6. check service/resource check out
743 // 7. user is owner of checkout state
744 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
745 ComponentParametersView componentFilter = new ComponentParametersView();
746 componentFilter.disableAll();
747 componentFilter.setIgnoreArtifacts(false);
748 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
749 componentFilter.setIgnoreComponentInstances(false);
751 Component component = validateComponentExistsByFilter(realComponentId, ComponentTypeEnum.findByParamName(containerComponentType),
753 lockComponent(component, ARTIFACT_ACTION_LOCK);
754 boolean failed = false;
756 ArtifactGroupTypeEnum groupType = ArtifactGroupTypeEnum.findType(artifactGroupType);
757 if (groupType == null) {
758 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
759 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
761 if (parentId == null && groupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
762 List<ArtifactDefinition> list = getDeploymentArtifacts(component, componentId);
763 if (list != null && !list.isEmpty()) {
764 resMap = list.stream().collect(Collectors.toMap(ArtifactDataDefinition::getArtifactLabel, Function.identity()));
766 resMap = new HashMap<>();
770 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsMapStatus = getArtifacts(realComponentId,
771 componentType.getNodeType(), groupType, componentId);
772 if (artifactsMapStatus.isRight()) {
773 if (artifactsMapStatus.right().value() != StorageOperationStatus.NOT_FOUND) {
774 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
775 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
777 resMap = new HashMap<>();
780 resMap = artifactsMapStatus.left().value();
784 } catch (ComponentException e) {
791 janusGraphDao.rollback();
794 janusGraphDao.commit();
796 componentType = component.getComponentType();
797 NodeTypeEnum nodeType = componentType.getNodeType();
798 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
802 private ArtifactDefinition getArtifactIfBelongsToComponent(String componentId, ComponentTypeEnum componentType, String artifactId,
803 Component component) {
804 // check artifact existence
805 Either<ArtifactDefinition, StorageOperationStatus> artifactResult = artifactToscaOperation
806 .getArtifactById(componentId, artifactId, componentType, component.getUniqueId());
807 if (artifactResult.isRight()) {
808 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentId);
810 // verify artifact belongs to component
812 switch (componentType) {
815 found = ComponentUtils.checkArtifactInComponent(component, artifactId);
817 case RESOURCE_INSTANCE:
818 found = ComponentUtils.checkArtifactInResourceInstance(component, componentId, artifactId);
824 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentType.name().toLowerCase());
826 return artifactResult.left().value();
829 private Either<ArtifactDefinition, Operation> handleCreate(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
830 AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType,
831 Component parent, String origMd5, String originData, String interfaceType,
832 String operationName) {
833 byte[] decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, null, user, componentType, parent, origMd5,
834 originData, interfaceType, operationName);
835 return createArtifact(parent, componentId, artifactInfo, decodedPayload, componentType, auditingAction, interfaceType, operationName);
838 private ArtifactDefinition handleLink(String componentId, ArtifactDefinition artifactInfo, ComponentTypeEnum componentType, Component parent) {
839 ComponentInstance foundInstance = findComponentInstance(componentId, parent);
840 String instanceId = null;
841 if (foundInstance != null) {
842 instanceId = foundInstance.getUniqueId();
844 NodeTypeEnum nodeType = convertParentType(componentType);
845 Either<ArtifactDefinition, StorageOperationStatus> artifactDefinitionEither = artifactToscaOperation
846 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
847 if (artifactDefinitionEither.isRight()) {
848 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
850 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), componentId, componentType) != StorageOperationStatus.OK) {
851 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
853 return artifactDefinitionEither.left().value();
856 private <T> Either<ArtifactDefinition, T> lockComponentAndUpdateArtifact(String parentId, ArtifactDefinition artifactInfo,
857 AuditingActionEnum auditingAction, String artifactId, User user,
858 ComponentTypeEnum componentType, Component parent, byte[] decodedPayload,
859 boolean shouldLock, boolean inTransaction) {
860 boolean failed = false;
861 boolean writeAudit = true;
863 lockComponent(parent, shouldLock, ARTIFACT_ACTION_LOCK);
865 return updateArtifactFlow(parent, parentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
866 } catch (ComponentException ce) {
868 handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, ce.getResponseFormat(), componentType, null);
872 } catch (StorageException se) {
878 unlockComponent(failed, parent, inTransaction);
883 private byte[] validateInput(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
884 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
885 String origMd5, String originData, String interfaceType, String operationName) {
886 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
887 return getValidPayload(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, interfaceType,
891 private byte[] getValidPayload(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
892 AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
893 String interfaceType, String operationName) {
895 Either<ArtifactDefinition, ResponseFormat> validateResult = validateInput(componentId, artifactInfo, operation, artifactId, user,
896 interfaceType, operationName, componentType, parent);
897 if (validateResult.isRight()) {
898 ResponseFormat responseFormat = validateResult.right().value();
899 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
900 throw new ByResponseFormatComponentException(responseFormat);
902 Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
903 if (payloadEither.isRight()) {
904 ResponseFormat responseFormat = payloadEither.right().value();
905 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
906 log.debug("Error during handle payload");
907 throw new ByResponseFormatComponentException(responseFormat);
909 // validate heat parameters. this part must be after the parameters are
911 // extracted in "handlePayload"
912 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters = validateAndConvertHeatParameters(artifactInfo,
913 artifactInfo.getArtifactType());
914 if (validateAndConvertHeatParameters.isRight()) {
915 ResponseFormat responseFormat = validateAndConvertHeatParameters.right().value();
916 handleAuditing(auditingAction, parent, componentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null);
917 log.debug("Error during handle payload");
918 throw new ByResponseFormatComponentException(responseFormat);
920 return payloadEither.left().value();
923 public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
924 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
925 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
926 if (componentsUtils.isExternalApiEvent(auditingActionEnum)) {
931 user.setUserId("UNKNOWN");
933 handleInternalAuditEvent(auditingActionEnum, component, componentId, user, artifactDefinition, prevArtifactUuid, currentArtifactUuid,
934 responseFormat, componentTypeEnum, resourceInstanceName);
937 private void handleInternalAuditEvent(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
938 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
939 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
940 switch (componentTypeEnum) {
942 Resource resource = (Resource) component;
943 if (resource == null) {
944 // In that case, component ID should be instead of name
945 resource = new Resource();
946 resource.setName(componentId);
948 componentsUtils.auditResource(responseFormat, user, resource, resource.getName(), auditingActionEnum,
949 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(), currentArtifactUuid, artifactDefinition);
952 Service service = (Service) component;
953 if (service == null) {
954 // In that case, component ID should be instead of name
955 service = new Service();
956 service.setName(componentId);
959 .auditComponent(responseFormat, user, service, auditingActionEnum, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
960 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
961 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
963 case RESOURCE_INSTANCE:
964 if (resourceInstanceName == null) {
965 resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId);
967 componentsUtils.auditComponent(responseFormat, user, component, auditingActionEnum,
968 new ResourceCommonInfo(resourceInstanceName, ComponentTypeEnum.RESOURCE_INSTANCE.getValue()),
969 ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
970 ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
977 private String getResourceInstanceNameFromComponent(Component component, String componentId) {
978 ComponentInstance resourceInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findFirst()
980 String resourceInstanceName = null;
981 if (resourceInstance != null) {
982 resourceInstanceName = resourceInstance.getName();
984 return resourceInstanceName;
987 private void validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperationInfo operation) {
988 if (origMd5 == null) {
989 if (operation.isCreateOrLink() && ArrayUtils.isNotEmpty(payload)) {
990 log.debug("Missing md5 header during artifact create");
991 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
994 if (ArrayUtils.isNotEmpty(payload)) {
995 log.debug("Cannot have payload while md5 header is missing");
996 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
999 String encodeBase64Str = GeneralUtility.calculateMD5Base64EncodedByString(originData);
1000 if (!encodeBase64Str.equals(origMd5)) {
1001 log.debug("The calculated md5 is different then the received one");
1002 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1007 private Either<ArtifactDefinition, ResponseFormat> validateInput(final String componentId, final ArtifactDefinition artifactInfo,
1008 final ArtifactOperationInfo operation, final String artifactId, final User user,
1009 String interfaceName, String operationName,
1010 final ComponentTypeEnum componentType, final Component parentComponent) {
1011 final ArtifactDefinition existingArtifactInfo = findArtifact(parentComponent, componentType, componentId, operation, artifactId);
1012 final boolean isCreateOrLinkOperation = ArtifactOperationEnum.isCreateOrLink(operation.getArtifactOperationEnum());
1013 if (!isCreateOrLinkOperation && existingArtifactInfo == null) {
1014 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1016 final Component component;
1017 if (parentComponent.getUniqueId().equals(componentId)) {
1018 component = parentComponent;
1020 final ComponentInstance componentInstance = findComponentInstance(componentId, parentComponent);
1021 component = findComponent(componentInstance.getComponentUid());
1022 component.setComponentType(componentType);
1024 if (!isCreateOrLinkOperation) {
1025 ignoreUnupdateableFieldsInUpdate(operation, artifactInfo, existingArtifactInfo);
1027 if (isInformationalArtifact(artifactInfo)) {
1028 validateInformationalArtifact(artifactInfo, component);
1030 Either<Boolean, ResponseFormat> validateAndSetArtifactname = validateAndSetArtifactName(artifactInfo);
1031 if (validateAndSetArtifactname.isRight()) {
1032 return Either.right(validateAndSetArtifactname.right().value());
1034 if (!validateArtifactNameUniqueness(componentId, parentComponent, artifactInfo, componentType)) {
1035 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST));
1037 if (operationName != null && interfaceName != null) {
1038 operationName = operationName.toLowerCase();
1039 interfaceName = interfaceName.toLowerCase();
1041 Either<ActionStatus, ResponseFormat> logicalNameStatus = handleArtifactLabel(componentId, parentComponent, operation, artifactInfo,
1042 operationName, componentType);
1043 if (logicalNameStatus.isRight()) {
1044 return Either.right(logicalNameStatus.right().value());
1046 // This is a patch to block possibility of updating service api fields
1048 // through other artifacts flow
1049 final ArtifactGroupTypeEnum artifactGroupType =
1050 operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL;
1051 if (operation.isNotCreateOrLink()) {
1052 checkAndSetUnUpdatableFields(user, artifactInfo, existingArtifactInfo, artifactGroupType);
1054 checkCreateFields(user, artifactInfo, artifactGroupType);
1056 composeArtifactId(componentId, artifactId, artifactInfo, interfaceName, operationName);
1057 if (existingArtifactInfo != null) {
1058 artifactInfo.setMandatory(existingArtifactInfo.getMandatory());
1059 if (operation.isNotCreateOrLink()) {
1060 validateArtifactTypeNotChanged(artifactInfo, existingArtifactInfo);
1063 // artifactGroupType is not allowed to be updated
1064 if (operation.isNotCreateOrLink()) {
1065 Either<ArtifactDefinition, ResponseFormat> validateGroupType = validateOrSetArtifactGroupType(artifactInfo, existingArtifactInfo);
1066 if (validateGroupType.isRight()) {
1067 return Either.right(validateGroupType.right().value());
1070 setArtifactTimeout(artifactInfo, existingArtifactInfo);
1071 if (isHeatArtifact(artifactInfo)) {
1072 validateHeatArtifact(parentComponent, componentId, artifactInfo);
1074 if (isDeploymentArtifact(artifactInfo)) {
1075 if (componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1076 final String artifactName = artifactInfo.getArtifactName();
1077 final String existingArtifactName = (existingArtifactInfo == null) ? null : existingArtifactInfo.getArtifactName();
1078 if (operation.isCreateOrLink() || ((artifactName != null) && !artifactName.equalsIgnoreCase(existingArtifactName))) {
1079 validateSingleDeploymentArtifactName(artifactName, parentComponent);
1082 validateDeploymentArtifact(artifactInfo, component);
1084 Either<Boolean, ResponseFormat> descriptionResult = validateAndCleanDescription(artifactInfo);
1085 if (descriptionResult.isRight()) {
1086 return Either.right(descriptionResult.right().value());
1088 validateArtifactType(artifactInfo, component.getComponentType());
1089 artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase());
1090 if (existingArtifactInfo != null && existingArtifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.SERVICE_API) {
1091 // Change of type is not allowed and should be ignored
1092 artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER);
1093 Either<Boolean, ResponseFormat> validateUrl = validateAndServiceApiUrl(artifactInfo);
1094 if (validateUrl.isRight()) {
1095 return Either.right(validateUrl.right().value());
1097 Either<Boolean, ResponseFormat> validateUpdate = validateFirstUpdateHasPayload(artifactInfo, existingArtifactInfo);
1098 if (validateUpdate.isRight()) {
1099 log.debug("serviceApi first update cnnot be without payload.");
1100 return Either.right(validateUpdate.right().value());
1103 if (artifactInfo.getApiUrl() != null) {
1104 artifactInfo.setApiUrl(null);
1105 log.error("Artifact URL cannot be set through this API - ignoring");
1107 if (Boolean.TRUE.equals(artifactInfo.getServiceApi())) {
1108 artifactInfo.setServiceApi(false);
1109 log.error("Artifact service API flag cannot be changed - ignoring");
1112 return Either.left(artifactInfo);
1115 private Component findComponent(final String componentId) {
1116 Either<? extends Component, StorageOperationStatus> component = toscaOperationFacade.getToscaFullElement(componentId);
1117 if (component.isRight()) {
1118 log.debug("Component '{}' not found ", componentId);
1119 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentId);
1121 return component.left().value();
1124 private void ignoreUnupdateableFieldsInUpdate(final ArtifactOperationInfo operation, final ArtifactDefinition artifactInfo,
1125 final ArtifactDefinition currentArtifactInfo) {
1126 if (operation.isUpdate()) {
1127 artifactInfo.setArtifactType(currentArtifactInfo.getArtifactType());
1128 artifactInfo.setArtifactGroupType(currentArtifactInfo.getArtifactGroupType());
1129 artifactInfo.setArtifactLabel(currentArtifactInfo.getArtifactLabel());
1133 private ArtifactDefinition findArtifact(final Component parentComponent, final ComponentTypeEnum componentType, final String parentId,
1134 final ArtifactOperationInfo operation, final String artifactId) {
1135 ArtifactDefinition foundArtifact = null;
1136 if (StringUtils.isNotEmpty(artifactId)) {
1137 foundArtifact = findArtifact(parentComponent, componentType, parentId, artifactId);
1139 if (foundArtifact != null && operation.isCreateOrLink()) {
1140 log.debug("Artifact {} already exist", artifactId);
1141 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, foundArtifact.getArtifactLabel());
1143 if (foundArtifact == null && operation.isNotCreateOrLink()) {
1144 log.debug("The artifact {} was not found on parent component or instance {}. ", artifactId, parentId);
1145 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, "");
1147 return foundArtifact;
1150 private ArtifactDefinition findArtifact(Component parentComponent, ComponentTypeEnum componentType, String parentId, String artifactId) {
1151 ArtifactDefinition foundArtifact;
1152 if (parentComponent.getUniqueId().equals(parentId)) {
1153 foundArtifact = artifactsResolver.findArtifactOnComponent(parentComponent, componentType, artifactId);
1155 ComponentInstance instance = findComponentInstance(parentId, parentComponent);
1156 foundArtifact = artifactsResolver.findArtifactOnComponentInstance(instance, artifactId);
1158 return foundArtifact;
1161 private void validateInformationalArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1162 final ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
1163 if (groupType != ArtifactGroupTypeEnum.INFORMATIONAL) {
1166 final ComponentTypeEnum parentComponentType = component.getComponentType();
1167 final String artifactType = artifactInfo.getArtifactType();
1168 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1169 if (artifactConfiguration == null) {
1170 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1172 validateArtifactType(parentComponentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1173 if (component.getComponentType() == ComponentTypeEnum.RESOURCE || component.getComponentType() == ComponentTypeEnum.RESOURCE_INSTANCE) {
1174 final ResourceTypeEnum resourceType = ((Resource) component).getResourceType();
1175 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1177 validateArtifactExtension(artifactConfiguration, artifactInfo);
1180 private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) {
1181 if (componentType == ComponentTypeEnum.RESOURCE) {
1182 return NodeTypeEnum.Resource;
1183 } else if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1184 return NodeTypeEnum.ResourceInstance;
1186 return NodeTypeEnum.Service;
1190 // This method is here for backward compatibility - when other parts of the code are cleaned can change to use the internal version
1191 public Either<ArtifactDefinition, ResponseFormat> handleDelete(String parentId, String artifactId, User user, Component parent,
1192 boolean shouldLock, boolean inTransaction) {
1193 ResponseFormat responseFormat;
1194 boolean operationSucceeded = false;
1196 lockComponent(ComponentTypeEnum.RESOURCE, artifactId, AuditingActionEnum.ARTIFACT_DELETE, user, parent);
1199 ArtifactDefinition artifactDefinition = handleDeleteInternal(parentId, artifactId, ComponentTypeEnum.RESOURCE, parent);
1200 operationSucceeded = true;
1201 return Either.left(artifactDefinition);
1202 } catch (ComponentException ce) {
1203 responseFormat = componentsUtils.getResponseFormat(ce);
1204 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1205 ComponentTypeEnum.RESOURCE, null);
1206 return Either.right(responseFormat);
1207 } catch (StorageException se) {
1208 responseFormat = componentsUtils.getResponseFormat(se);
1209 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1210 ComponentTypeEnum.RESOURCE, null);
1211 return Either.right(responseFormat);
1213 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
1217 private ArtifactDefinition handleDeleteInternal(String parentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1218 NodeTypeEnum parentType = convertParentType(componentType);
1219 log.debug("Going to find the artifact {} on the component {}", artifactId, parent.getUniqueId());
1220 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> getArtifactRes = findArtifact(artifactId, parent, parentId,
1222 if (getArtifactRes.isRight()) {
1223 log.debug("Failed to find the artifact {} belonging to {} on the component {}", artifactId, parentId, parent.getUniqueId());
1224 throw new ByActionStatusComponentException(getArtifactRes.right().value(), artifactId);
1226 ArtifactDefinition foundArtifact = getArtifactRes.left().value().getLeft();
1227 ComponentInstance foundInstance = getArtifactRes.left().value().getRight();
1228 String esId = foundArtifact.getEsId();
1229 Either<Boolean, StorageOperationStatus> needClone = ifTrue(StringUtils.isNotEmpty(esId),
1230 () -> forEach(artifactToscaOperation.isCloneNeeded(parent.getUniqueId(), foundArtifact, parentType), b -> log
1231 .debug("handleDelete: clone is needed for deleting {} held by {} in component {} {}? {}", foundArtifact.getArtifactName(), parentType,
1232 parent.getUniqueId(), parent.getName(), b)));
1233 boolean needToClone = false;
1234 // TODO: This should not be done, but in order to keep this refactoring small, we stop here.
1236 // Remove this block once the above refactoring is merged.
1237 if (needClone.isLeft()) {
1238 needToClone = needClone.left().value();
1240 throw new StorageException(needClone.right().value(), foundArtifact.getArtifactDisplayName());
1242 boolean isNeedToDeleteArtifactFromDB =
1243 componentType == ComponentTypeEnum.RESOURCE_INSTANCE && isArtifactOnlyResourceInstanceArtifact(foundArtifact, parent, parentId);
1244 boolean isDuplicated = false;
1245 ArtifactDataDefinition updatedArtifact = deleteOrUpdateArtifactOnGraph(parent, parentId, artifactId, parentType, foundArtifact, needToClone);
1246 isDuplicated = updatedArtifact.getDuplicated();
1247 if (!needToClone && !isDuplicated && isNeedToDeleteArtifactFromDB) {
1248 log.debug("Going to delete the artifact {} from the database. ", artifactId);
1249 CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(esId);
1250 if (cassandraStatus != CassandraOperationStatus.OK) {
1251 log.debug("Failed to delete the artifact {} from the database. ", artifactId);
1252 throw new StorageException(convertToStorageOperationStatus(cassandraStatus), foundArtifact.getArtifactDisplayName());
1255 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1256 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(artifactId, foundArtifact, foundInstance.getGroupInstances());
1257 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
1258 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
1259 .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
1260 if (status.isRight()) {
1261 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1262 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1265 StorageOperationStatus status = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
1266 if (status != StorageOperationStatus.OK) {
1267 log.debug("Failed to generate new customization UUID for the component instance {}. ", parentId);
1268 throw new StorageException(status, foundArtifact.getArtifactDisplayName());
1271 List<GroupDataDefinition> updatedGroups = getUpdatedGroups(artifactId, foundArtifact, parent.getGroups());
1272 if (CollectionUtils.isNotEmpty(updatedGroups)) {
1273 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, updatedGroups);
1274 if (status.isRight()) {
1275 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1276 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1280 return foundArtifact;
1283 private boolean isArtifactOnlyResourceInstanceArtifact(ArtifactDefinition foundArtifact, Component parent, String instanceId) {
1284 Optional<ComponentInstance> componentInstanceOpt = parent.getComponentInstanceById(instanceId);
1285 if (!componentInstanceOpt.isPresent()) {
1286 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "", "", parent.getName());
1288 ComponentInstance foundInstance = componentInstanceOpt.get();
1289 String componentUid = foundInstance.getComponentUid();
1290 Either<Component, StorageOperationStatus> getContainerRes = toscaOperationFacade.getToscaElement(componentUid);
1291 if (getContainerRes.isRight()) {
1292 log.debug("Failed to fetch the container component {}. ", componentUid);
1293 throw new StorageException(getContainerRes.right().value());
1295 Component origComponent = getContainerRes.left().value();
1296 Map<String, ArtifactDefinition> deploymentArtifacts = origComponent.getDeploymentArtifacts();
1297 if (MapUtils.isNotEmpty(deploymentArtifacts)) {
1298 Optional<String> op = deploymentArtifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1299 if (op.isPresent()) {
1303 Map<String, ArtifactDefinition> artifacts = origComponent.getArtifacts();
1304 if (MapUtils.isNotEmpty(artifacts)) {
1305 Optional<String> op = artifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1306 if (op.isPresent()) {
1313 private List<GroupDataDefinition> getUpdatedGroups(String artifactId, ArtifactDefinition foundArtifact, List<GroupDefinition> groups) {
1314 List<GroupDataDefinition> updatedGroups = new ArrayList<>();
1315 boolean isUpdated = false;
1316 if (groups != null) {
1317 for (GroupDefinition group : groups) {
1319 if (CollectionUtils.isNotEmpty(group.getArtifacts()) && group.getArtifacts().contains(artifactId)) {
1320 group.getArtifacts().remove(artifactId);
1323 if (CollectionUtils.isNotEmpty(group.getArtifactsUuid()) && group.getArtifactsUuid().contains(foundArtifact.getArtifactUUID())) {
1324 group.getArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1328 updatedGroups.add(group);
1332 return updatedGroups;
1335 private List<GroupInstance> getUpdatedGroupInstances(String artifactId, ArtifactDefinition foundArtifact, List<GroupInstance> groupInstances) {
1336 if (CollectionUtils.isEmpty(groupInstances)) {
1337 return new ArrayList<>();
1339 // TODO: A defensive copy should be created here for groupInstances. Modifying
1341 // arguments (aka output arguments) is overall a bad practice as explained in
1343 // Clean Code by Robert Martin.
1345 // A better approach would be to use Lenses.
1346 return groupInstances.stream().filter(gi -> {
1347 boolean groupInstanceArtifactRemoved = gi.getGroupInstanceArtifacts() != null && gi.getGroupInstanceArtifacts().remove(artifactId);
1348 boolean groupInstanceArtifactUUIDRemoved =
1349 gi.getGroupInstanceArtifactsUuid() != null && gi.getGroupInstanceArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1350 return groupInstanceArtifactRemoved || groupInstanceArtifactUUIDRemoved;
1351 }).collect(Collectors.toList());
1354 private ArtifactDataDefinition deleteOrUpdateArtifactOnGraph(Component component, String parentId, String artifactId, NodeTypeEnum parentType,
1355 ArtifactDefinition foundArtifact, Boolean cloneIsNeeded) {
1356 Either<ArtifactDataDefinition, StorageOperationStatus> result;
1357 boolean isMandatory = foundArtifact.getMandatory() || foundArtifact.getServiceApi();
1358 String componentId = component.getUniqueId();
1359 String instanceId = componentId.equals(parentId) ? null : parentId;
1361 log.debug("Going to update mandatory artifact {} from the component {}", artifactId, parentId);
1362 resetMandatoryArtifactFields(foundArtifact);
1363 result = artifactToscaOperation.updateArtifactOnGraph(component, foundArtifact, parentType, artifactId, instanceId, true, true);
1364 } else if (cloneIsNeeded) {
1365 log.debug("Going to clone artifacts and to delete the artifact {} from the component {}", artifactId, parentId);
1366 result = artifactToscaOperation.deleteArtifactWithCloningOnGraph(componentId, foundArtifact, parentType, instanceId, false);
1368 log.debug("Going to delete the artifact {} from the component {}", artifactId, parentId);
1369 result = artifactToscaOperation.removeArtifactOnGraph(foundArtifact, componentId, instanceId, parentType, false);
1371 if (result.isRight()) {
1372 throw new StorageException(result.right().value(), foundArtifact.getArtifactDisplayName());
1374 return result.left().value();
1377 private Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> findArtifact(String artifactId,
1378 Component fetchedContainerComponent,
1380 ComponentTypeEnum componentType) {
1381 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> result = null;
1382 Map<String, ArtifactDefinition> artifacts = new HashMap<>();
1383 ComponentInstance foundInstance = null;
1384 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && StringUtils.isNotEmpty(parentId)) {
1385 Optional<ComponentInstance> componentInstanceOpt = fetchedContainerComponent.getComponentInstances().stream()
1386 .filter(i -> i.getUniqueId().equals(parentId)).findFirst();
1387 if (!componentInstanceOpt.isPresent()) {
1388 result = Either.right(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER);
1390 foundInstance = componentInstanceOpt.get();
1391 fetchArtifactsFromInstance(artifactId, artifacts, foundInstance);
1394 fetchArtifactsFromComponent(artifactId, fetchedContainerComponent, artifacts);
1396 if (result == null) {
1397 if (artifacts.containsKey(artifactId)) {
1398 result = Either.left(new ImmutablePair<>(artifacts.get(artifactId), foundInstance));
1400 result = Either.right(ActionStatus.ARTIFACT_NOT_FOUND);
1406 private void fetchArtifactsFromComponent(String artifactId, Component component, Map<String, ArtifactDefinition> artifacts) {
1407 Map<String, ArtifactDefinition> currArtifacts;
1408 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
1409 currArtifacts = component.getDeploymentArtifacts().values().stream()
1410 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, i -> i));
1411 if (MapUtils.isNotEmpty(currArtifacts)) {
1412 artifacts.putAll(currArtifacts);
1415 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1416 currArtifacts = component.getArtifacts().values().stream()
1417 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1418 if (MapUtils.isNotEmpty(currArtifacts)) {
1419 artifacts.putAll(currArtifacts);
1422 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1423 currArtifacts = component.getToscaArtifacts().values().stream()
1424 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1425 if (MapUtils.isNotEmpty(currArtifacts)) {
1426 artifacts.putAll(currArtifacts);
1431 private void fetchArtifactsFromInstance(String artifactId, Map<String, ArtifactDefinition> artifacts, ComponentInstance instance) {
1432 Map<String, ArtifactDefinition> currArtifacts;
1433 if (MapUtils.isNotEmpty(instance.getDeploymentArtifacts())) {
1434 currArtifacts = instance.getDeploymentArtifacts().values().stream()
1435 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1436 if (MapUtils.isNotEmpty(currArtifacts)) {
1437 artifacts.putAll(currArtifacts);
1440 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(instance.getArtifacts())) {
1441 currArtifacts = instance.getArtifacts().values().stream()
1442 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1443 if (MapUtils.isNotEmpty(currArtifacts)) {
1444 artifacts.putAll(currArtifacts);
1449 private StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) {
1450 StorageOperationStatus result;
1451 switch (cassandraStatus) {
1453 result = StorageOperationStatus.OK;
1456 result = StorageOperationStatus.NOT_FOUND;
1458 case CLUSTER_NOT_CONNECTED:
1459 case KEYSPACE_NOT_CONNECTED:
1460 result = StorageOperationStatus.CONNECTION_FAILURE;
1463 result = StorageOperationStatus.GENERAL_ERROR;
1469 private void resetMandatoryArtifactFields(ArtifactDefinition fetchedArtifact) {
1470 if (fetchedArtifact != null) {
1471 log.debug("Going to reset mandatory artifact {} fields. ", fetchedArtifact.getUniqueId());
1472 fetchedArtifact.setEsId(null);
1473 fetchedArtifact.setArtifactName(null);
1474 fetchedArtifact.setDescription(null);
1475 fetchedArtifact.setApiUrl(null);
1476 fetchedArtifact.setArtifactChecksum(null);
1477 nodeTemplateOperation.setDefaultArtifactTimeout(fetchedArtifact.getArtifactGroupType(), fetchedArtifact);
1478 fetchedArtifact.setArtifactUUID(null);
1479 long time = System.currentTimeMillis();
1480 fetchedArtifact.setPayloadUpdateDate(time);
1481 fetchedArtifact.setHeatParameters(null);
1482 fetchedArtifact.setHeatParamsUpdateDate(null);
1486 private StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId, ComponentTypeEnum componentType) {
1487 StorageOperationStatus error = StorageOperationStatus.OK;
1488 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1489 log.debug("Need to re-generate customization UUID for instance {}", instanceId);
1490 error = toscaOperationFacade.generateCustomizationUUIDOnInstance(componentId, instanceId);
1495 private ArtifactDefinition handleDownload(String componentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1496 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation
1497 .getArtifactById(componentId, artifactId, componentType, parent.getUniqueId());
1498 if (artifactById.isRight()) {
1499 throw new StorageException(artifactById.right().value());
1501 ArtifactDefinition artifactDefinition = artifactById.left().value();
1502 if (artifactDefinition == null) {
1503 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1505 return artifactDefinition;
1508 private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String componentId, Component parentComponent, ArtifactOperationInfo operation,
1509 ArtifactDefinition artifactInfo, String operationName,
1510 ComponentTypeEnum componentType) {
1511 String artifactLabel = artifactInfo.getArtifactLabel();
1512 if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) {
1513 BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
1514 log.debug("missing artifact logical name for component {}", componentId);
1515 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1517 if (operation.isCreateOrLink() && !artifactInfo.getMandatory()) {
1518 if (operationName != null) {
1519 if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) {
1520 log.debug("artifact label cannot be set {}", artifactLabel);
1521 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED));
1523 artifactLabel = operationName;
1526 String displayName = artifactInfo.getArtifactDisplayName();
1527 if (displayName == null || displayName.isEmpty()) {
1528 displayName = artifactLabel;
1530 displayName = ValidationUtils.cleanArtifactDisplayName(displayName);
1531 artifactInfo.setArtifactDisplayName(displayName);
1532 if (!ValidationUtils.validateArtifactLabel(artifactLabel)) {
1533 log.debug("Invalid format form Artifact label : {}", artifactLabel);
1534 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_ARTIFACT_LABEL_NAME, VALID_ARTIFACT_LABEL_NAME));
1536 artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel);
1537 if (artifactLabel.isEmpty()) {
1538 log.debug("missing normalized artifact logical name for component {}", componentId);
1539 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1541 if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) {
1542 log.debug("Invalid lenght form Artifact label : {}", artifactLabel);
1543 return Either.right(componentsUtils
1544 .getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH)));
1546 if (!validateLabelUniqueness(componentId, parentComponent, artifactLabel, componentType)) {
1547 log.debug("Non unique Artifact label : {}", artifactLabel);
1548 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel));
1551 artifactInfo.setArtifactLabel(artifactLabel);
1552 return Either.left(ActionStatus.OK);
1555 private boolean validateLabelUniqueness(String componentId, Component parentComponent, String artifactLabel, ComponentTypeEnum componentType) {
1556 boolean isUnique = true;
1557 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts;
1558 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1559 artifacts = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1561 artifacts = artifactToscaOperation.getArtifacts(componentId);
1563 if (artifacts.isLeft()) {
1564 for (String label : artifacts.left().value().keySet()) {
1565 if (label.equals(artifactLabel)) {
1571 if (componentType == ComponentTypeEnum.RESOURCE && isUnique) {
1572 isUnique = isUniqueLabelInResourceInterfaces(componentId, artifactLabel);
1577 boolean validateArtifactNameUniqueness(String componentId, Component parentComponent, ArtifactDefinition artifactInfo,
1578 ComponentTypeEnum componentType) {
1579 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = getArtifacts(componentType, parentComponent, componentId,
1580 artifactInfo.getArtifactGroupType());
1581 String artifactName = artifactInfo.getArtifactName();
1582 if (artifacts.isLeft() && Objects.nonNull(artifacts.left().value())) {
1583 if (artifacts.left().value().values().stream().anyMatch(ad -> artifactName.equals(ad.getArtifactName())
1584 //check whether it is the same artifact we hold (by label)
1585 && !artifactInfo.getArtifactLabel().equals(ad.getArtifactLabel()))) {
1589 if (ComponentTypeEnum.RESOURCE == componentType) {
1590 return isUniqueArtifactNameInResourceInterfaces(componentId, artifactName, artifactInfo.getArtifactLabel());
1595 private boolean isUniqueArtifactNameInResourceInterfaces(String componentId, String artifactName, String artifactLabel) {
1596 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1597 .getAllInterfacesOfResource(componentId, true, true);
1598 if (allInterfacesOfResource.isLeft()) {
1599 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1600 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1601 .noneMatch(add -> artifactName.equals(add.getArtifactName()) && !artifactLabel.equals(add.getArtifactLabel()));
1606 private boolean isUniqueLabelInResourceInterfaces(String componentId, String artifactLabel) {
1607 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1608 .getAllInterfacesOfResource(componentId, true, true);
1609 if (allInterfacesOfResource.isLeft()) {
1610 return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1611 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1612 .noneMatch(add -> artifactLabel.equals(add.getArtifactLabel()));
1617 private Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(ComponentTypeEnum componentType, Component parentComponent,
1619 ArtifactGroupTypeEnum artifactGroupType) {
1620 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse;
1621 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1622 artifactsResponse = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1624 artifactsResponse = artifactToscaOperation.getArtifacts(componentId);
1626 if (artifactsResponse.isRight() && artifactsResponse.right().value() == StorageOperationStatus.NOT_FOUND) {
1627 log.debug("failed to retrieve artifacts for {} ", componentId);
1628 return Either.right(artifactsResponse.right().value());
1630 return Either.left(artifactsResponse.left().value().entrySet().stream().filter(x -> artifactGroupType == x.getValue().getArtifactGroupType())
1631 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
1634 // ***************************************************************
1635 private Either<ArtifactDefinition, Operation> createArtifact(Component parent, String parentId, ArtifactDefinition artifactInfo,
1636 byte[] decodedPayload, ComponentTypeEnum componentTypeEnum,
1637 AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) {
1638 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
1639 if (artifactData == null) {
1640 BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact");
1641 log.debug("Failed to create artifact object for ES.");
1642 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1644 ComponentInstance foundInstance = findComponentInstance(parentId, parent);
1645 String instanceId = null;
1646 if (foundInstance != null) {
1647 if (foundInstance.isArtifactExists(artifactInfo.getArtifactGroupType(), artifactInfo.getArtifactLabel())) {
1648 log.debug("Failed to create artifact, already exists");
1649 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, artifactInfo.getArtifactLabel());
1651 instanceId = foundInstance.getUniqueId();
1653 // set on graph object id of artifact in ES!
1654 artifactInfo.setEsId(artifactData.getId());
1655 Either<ArtifactDefinition, Operation> operationResult;
1656 if (interfaceType != null && operationName != null) {
1657 // lifecycle artifact
1658 Operation operation = convertToOperation(artifactInfo, operationName);
1659 Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation
1660 .updateInterfaceOperation(parentId, interfaceType, operationName, operation);
1661 if (result.isRight()) {
1662 throw new StorageException(result.right().value());
1664 operationResult = Either.right(result.left().value());
1666 // information/deployment/api artifacts
1667 NodeTypeEnum nodeType = convertParentType(componentTypeEnum);
1668 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
1669 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
1670 if (result.isRight()) {
1671 throw new StorageException(result.right().value());
1673 ArtifactDefinition artifactDefinition = result.left().value();
1674 artifactData.setId(artifactDefinition.getEsId());
1675 operationResult = Either.left(artifactDefinition);
1676 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum) != StorageOperationStatus.OK) {
1677 throw new StorageException(generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum));
1680 saveArtifactInCassandra(artifactData, parent, artifactInfo, "", "", auditingActionEnum, componentTypeEnum);
1681 return operationResult;
1684 private ComponentInstance findComponentInstance(String componentInstanceId, Component containerComponent) {
1685 ComponentInstance foundInstance = null;
1686 if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
1687 foundInstance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst()
1690 return foundInstance;
1693 private void validateDeploymentArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1694 final ComponentTypeEnum componentType = component.getComponentType();
1695 if (componentType != ComponentTypeEnum.RESOURCE && componentType != ComponentTypeEnum.SERVICE
1696 && componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1697 log.debug("Invalid component type '{}' for artifact. " + "Expected Resource, Component or Resource Instance", componentType.getValue());
1698 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, componentType.getValue(),
1699 "Service, Resource or ResourceInstance", componentType.getValue());
1701 final String artifactType = artifactInfo.getArtifactType();
1702 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1703 if (artifactConfiguration == null) {
1704 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1706 validateArtifactType(componentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1707 if (componentType == ComponentTypeEnum.RESOURCE || componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1708 final Resource resource = (Resource) component;
1709 final ResourceTypeEnum resourceType = resource.getResourceType();
1710 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1712 validateArtifactExtension(artifactConfiguration, artifactInfo);
1715 private void validateHeatArtifact(final Component parentComponent, final String componentId, final ArtifactDefinition artifactDefinition) {
1716 final String artifactType = artifactDefinition.getArtifactType();
1717 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1718 if (artifactTypeEnum == null) {
1721 switch (artifactTypeEnum) {
1725 validateHeatTimeoutValue(artifactDefinition);
1728 validateHeatEnvDeploymentArtifact(parentComponent, componentId, artifactDefinition);
1735 private void setArtifactTimeout(final ArtifactDefinition newArtifactInfo, final ArtifactDefinition existingArtifactInfo) {
1736 final String artifactType = newArtifactInfo.getArtifactType();
1737 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1738 if (artifactTypeEnum == null) {
1739 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1742 switch (artifactTypeEnum) {
1746 if (newArtifactInfo.getTimeout() == null) {
1747 if (existingArtifactInfo == null) {
1748 newArtifactInfo.setTimeout(NodeTemplateOperation.getDefaultHeatTimeout());
1750 newArtifactInfo.setTimeout(existingArtifactInfo.getTimeout());
1755 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1761 void validateDeploymentArtifactTypeIsLegalForParent(ArtifactDefinition artifactInfo, ArtifactTypeEnum artifactType,
1762 Map<String, ArtifactTypeConfig> resourceDeploymentArtifacts) {
1763 if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) {
1764 log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType());
1765 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
1769 Optional<ArtifactConfiguration> loadArtifactTypeConfig(final String artifactType) {
1770 if (artifactType == null) {
1771 return Optional.empty();
1773 final List<ArtifactConfiguration> artifactConfigurationList = ConfigurationManager.getConfigurationManager().getConfiguration()
1775 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
1776 return Optional.empty();
1778 return artifactConfigurationList.stream().filter(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType))
1782 private Either<Boolean, ResponseFormat> extractHeatParameters(ArtifactDefinition artifactInfo) {
1783 // extract heat parameters
1784 if (artifactInfo.getPayloadData() != null) {
1785 String heatDecodedPayload = new String(Base64.decodeBase64(artifactInfo.getPayloadData()));
1786 Either<List<HeatParameterDefinition>, ResultStatusEnum> heatParameters = ImportUtils
1787 .getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo.getArtifactType());
1788 if (heatParameters.isRight() && (heatParameters.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND)) {
1789 log.info("failed to parse heat parameters ");
1790 ResponseFormat responseFormat = componentsUtils
1791 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactType());
1792 return Either.right(responseFormat);
1793 } else if (heatParameters.isLeft() && heatParameters.left().value() != null) {
1794 artifactInfo.setListHeatParameters(heatParameters.left().value());
1797 return Either.left(true);
1801 void validateArtifactExtension(final ArtifactConfiguration artifactConfiguration, final ArtifactDefinition artifactDefinition) {
1802 final List<String> acceptedTypes = artifactConfiguration.getAcceptedTypes();
1804 * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted.
1806 if (CollectionUtils.isEmpty(acceptedTypes)) {
1809 final String artifactName = artifactDefinition.getArtifactName();
1810 final String fileExtension = FilenameUtils.getExtension(artifactName);
1811 if (fileExtension == null || !acceptedTypes.contains(fileExtension.toLowerCase())) {
1812 final String artifactType = artifactDefinition.getArtifactType();
1813 log.debug("File extension \"{}\" is not allowed for artifact type \"{}\"", fileExtension, artifactType);
1814 throw new ByActionStatusComponentException(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, artifactType);
1819 void validateHeatEnvDeploymentArtifact(final Component parentComponent, final String parentId, final ArtifactDefinition artifactInfo) {
1820 final Wrapper<ArtifactDefinition> heatMDWrapper = new Wrapper<>();
1821 final Wrapper<byte[]> payloadWrapper = new Wrapper<>();
1822 validateYaml(artifactInfo);
1823 validateHeatExist(parentComponent.getUniqueId(), parentId, heatMDWrapper, artifactInfo, parentComponent.getComponentType());
1824 if (!heatMDWrapper.isEmpty()) {
1825 fillArtifactPayload(payloadWrapper, heatMDWrapper.getInnerElement());
1827 if (!heatMDWrapper.isEmpty()) {
1828 validateEnvVsHeat(artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement());
1832 public void fillArtifactPayload(Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactDefinition) {
1833 if (ArrayUtils.isEmpty(artifactDefinition.getPayloadData())) {
1834 Either<DAOArtifactData, CassandraOperationStatus> eitherArtifactData = artifactCassandraDao.getArtifact(artifactDefinition.getEsId());
1835 if (eitherArtifactData.isLeft()) {
1836 byte[] data = eitherArtifactData.left().value().getDataAsArray();
1837 payloadWrapper.setInnerElement(Base64.encodeBase64(data));
1839 log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName());
1840 throw new StorageException(DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()));
1843 payloadWrapper.setInnerElement(artifactDefinition.getPayloadData());
1847 private void validateEnvVsHeat(ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) {
1848 String envPayload = new String(Base64.decodeBase64(envArtifact.getPayloadData()));
1849 Map<String, Object> heatEnvToscaJson = (Map<String, Object>) new Yaml().load(envPayload);
1850 String heatDecodedPayload = new String(Base64.decodeBase64(heatPayloadData));
1851 Map<String, Object> heatToscaJson = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
1852 Either<Map<String, Object>, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils
1853 .findFirstToscaMapElement(heatEnvToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1854 if (eitherHeatEnvProperties.isRight()) {
1855 log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName());
1856 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat Env");
1858 Either<Map<String, Object>, ResultStatusEnum> eitherHeatProperties = ImportUtils
1859 .findFirstToscaMapElement(heatToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1860 if (eitherHeatProperties.isRight()) {
1861 log.debug("Invalid heat format for file:{}", heatArtifact.getArtifactName());
1862 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat");
1864 Set<String> heatPropertiesKeys = eitherHeatProperties.left().value().keySet();
1865 Set<String> heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet();
1866 heatEnvPropertiesKeys.removeAll(heatPropertiesKeys);
1867 if (!heatEnvPropertiesKeys.isEmpty()) {
1868 log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(),
1869 heatArtifact.getArtifactName());
1870 throw new ByActionStatusComponentException(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(),
1871 heatArtifact.getArtifactName());
1875 private void validateYaml(ArtifactDefinition artifactInfo) {
1876 YamlToObjectConverter yamlConverter = new YamlToObjectConverter();
1877 boolean isYamlValid = yamlConverter.isValidYamlEncoded64(artifactInfo.getPayloadData());
1879 log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName());
1880 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType());
1884 private void validateSingleDeploymentArtifactName(final String artifactName, final Component parentComponent) {
1885 boolean artifactNameFound = false;
1886 final Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, null).iterator();
1887 while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) {
1888 artifactNameFound = artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName());
1890 if (artifactNameFound) {
1891 final ComponentTypeEnum componentType = parentComponent.getComponentType();
1892 log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName);
1893 throw new ByActionStatusComponentException(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, componentType.getValue(),
1894 parentComponent.getName(), artifactName);
1898 private void validateHeatExist(String componentId, String parentRiId, Wrapper<ArtifactDefinition> heatArtifactMDWrapper,
1899 ArtifactDefinition heatEnvArtifact, ComponentTypeEnum componentType) {
1900 final Either<ArtifactDefinition, StorageOperationStatus> res = artifactToscaOperation
1901 .getHeatArtifactByHeatEnvId(parentRiId, heatEnvArtifact, componentId, componentType);
1902 if (res.isRight()) {
1903 throw new ByActionStatusComponentException(ActionStatus.MISSING_HEAT);
1905 heatArtifactMDWrapper.setInnerElement(res.left().value());
1909 void validateHeatTimeoutValue(final ArtifactDefinition artifactInfo) {
1910 log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel());
1911 // timeout > 0 for HEAT artifacts
1912 if (artifactInfo.getTimeout() == null || artifactInfo.getTimeout() < 1) {
1913 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
1915 // US649856 - Allow several HEAT files on Resource
1916 log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel());
1920 void validateResourceType(final ResourceTypeEnum resourceType, final ArtifactDefinition artifactInfo, final List<String> typeList) {
1921 if (CollectionUtils.isEmpty(typeList) || typeList.contains(resourceType.getValue())) {
1924 final String listToString = typeList.stream().collect(Collectors.joining(", "));
1925 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, artifactInfo.getArtifactGroupType().getType(),
1926 listToString, resourceType.getValue());
1930 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters(ArtifactDefinition artifactInfo, String artifactType) {
1931 if (artifactInfo.getHeatParameters() != null) {
1932 for (HeatParameterDefinition heatParam : artifactInfo.getListHeatParameters()) {
1933 String parameterType = heatParam.getType();
1934 HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType);
1935 String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType();
1936 if (heatParameterType == null) {
1937 ResponseFormat responseFormat = componentsUtils
1938 .getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam.getType());
1939 return Either.right(responseFormat);
1941 StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam);
1942 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
1943 log.debug("Heat parameter {} is invalid. Status is {}", heatParam.getName(), validateAndUpdateProperty);
1944 ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE;
1945 ResponseFormat responseFormat = componentsUtils
1946 .getResponseFormat(status, artifactTypeStr, heatParam.getType(), heatParam.getName());
1947 return Either.right(responseFormat);
1951 return Either.left(artifactInfo);
1954 public List<ArtifactDefinition> getDeploymentArtifacts(final Component component, final String ciId) {
1955 final ComponentTypeEnum componentType = component.getComponentType();
1956 if (component.getDeploymentArtifacts() == null) {
1957 return Collections.emptyList();
1959 final List<ArtifactDefinition> deploymentArtifacts = new ArrayList<>();
1960 if (ComponentTypeEnum.RESOURCE == componentType && ciId != null) {
1961 final Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(component, ciId, null, null, null);
1962 if (getRI.isRight()) {
1963 return Collections.emptyList();
1965 final ComponentInstance ri = getRI.left().value();
1966 if (ri.getDeploymentArtifacts() != null) {
1967 deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values());
1970 deploymentArtifacts.addAll(component.getDeploymentArtifacts().values());
1972 return deploymentArtifacts;
1975 private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) {
1976 // on create if null add informational to current
1977 if (artifactInfo.getArtifactGroupType() == null) {
1978 artifactInfo.setArtifactGroupType(type);
1980 if (artifactInfo.getUniqueId() != null) {
1981 log.error("artifact uniqid cannot be set ignoring");
1983 artifactInfo.setUniqueId(null);
1984 if (artifactInfo.getArtifactRef() != null) {
1985 log.error("artifact ref cannot be set ignoring");
1987 artifactInfo.setArtifactRef(null);
1988 if (artifactInfo.getArtifactRepository() != null) {
1989 log.error("artifact repository cannot be set ignoring");
1991 artifactInfo.setArtifactRepository(null);
1992 if (artifactInfo.getUserIdCreator() != null) {
1993 log.error("creator uuid cannot be set ignoring");
1995 artifactInfo.setArtifactCreator(user.getUserId());
1996 if (artifactInfo.getUserIdLastUpdater() != null) {
1997 log.error("userId of last updater cannot be set ignoring");
1999 artifactInfo.setUserIdLastUpdater(user.getUserId());
2000 if (artifactInfo.getCreatorFullName() != null) {
2001 log.error("creator Full name cannot be set ignoring");
2003 String fullName = user.getFirstName() + " " + user.getLastName();
2004 artifactInfo.setUpdaterFullName(fullName);
2005 if (artifactInfo.getUpdaterFullName() != null) {
2006 log.error("updater Full name cannot be set ignoring");
2008 artifactInfo.setUpdaterFullName(fullName);
2009 if (artifactInfo.getCreationDate() != null) {
2010 log.error("Creation Date cannot be set ignoring");
2012 long time = System.currentTimeMillis();
2013 artifactInfo.setCreationDate(time);
2014 if (artifactInfo.getLastUpdateDate() != null) {
2015 log.error("Last Update Date cannot be set ignoring");
2017 artifactInfo.setLastUpdateDate(time);
2018 if (artifactInfo.getEsId() != null) {
2019 log.error("es id cannot be set ignoring");
2021 artifactInfo.setEsId(null);
2024 private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName,
2025 String operationName) {
2026 String id = artifactId;
2027 if (artifactId == null || artifactId.isEmpty()) {
2028 String uniqueId = null;
2029 if (interfaceName != null && operationName != null) {
2030 uniqueId = UniqueIdBuilder
2031 .buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo.getArtifactLabel());
2033 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel());
2035 artifactInfo.setUniqueId(uniqueId);
2036 artifactInfo.setEsId(uniqueId);
2039 artifactInfo.setUniqueId(artifactId);
2040 artifactInfo.setEsId(artifactId);
2045 private Either<Boolean, ResponseFormat> validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2046 if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) {
2047 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD));
2049 return Either.left(true);
2053 Either<Boolean, ResponseFormat> validateAndSetArtifactName(ArtifactDefinition artifactInfo) {
2054 if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) {
2055 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2057 String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName());
2058 if (normalizeFileName == null || normalizeFileName.isEmpty()) {
2059 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2061 artifactInfo.setArtifactName(normalizeFileName);
2062 if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) {
2063 return Either.right(
2064 componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH)));
2066 return Either.left(true);
2069 private void validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2070 if (StringUtils.isEmpty(artifactInfo.getArtifactType())) {
2071 log.info("artifact type is missing operation ignored");
2072 throw new ByActionStatusComponentException(ActionStatus.MISSING_ARTIFACT_TYPE);
2074 if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) {
2075 log.info("artifact type cannot be changed operation ignored");
2076 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2080 private Either<ArtifactDefinition, ResponseFormat> validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo,
2081 ArtifactDefinition currentArtifact) {
2082 if (Objects.nonNull(artifactInfo) && Objects.nonNull(currentArtifact)) {
2083 if (artifactInfo.getArtifactGroupType() == null) {
2084 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2085 } else if (!currentArtifact.getArtifactGroupType().getType().equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) {
2086 log.info("artifact group type cannot be changed. operation failed");
2087 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2090 return Either.left(artifactInfo);
2093 private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact,
2094 ArtifactGroupTypeEnum type) {
2095 // on update if null add informational to current
2096 if (currentArtifact.getArtifactGroupType() == null && type != null) {
2097 currentArtifact.setArtifactGroupType(type);
2099 if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) {
2100 log.error("artifact uniqid cannot be set ignoring");
2102 artifactInfo.setUniqueId(currentArtifact.getUniqueId());
2103 if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef().equals(artifactInfo.getArtifactRef())) {
2104 log.error("artifact ref cannot be set ignoring");
2106 artifactInfo.setArtifactRef(currentArtifact.getArtifactRef());
2107 if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository().equals(artifactInfo.getArtifactRepository())) {
2108 log.error("artifact repository cannot be set ignoring");
2110 artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository());
2111 if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator().equals(artifactInfo.getUserIdCreator())) {
2112 log.error("creator uuid cannot be set ignoring");
2114 artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator());
2115 if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator().equals(artifactInfo.getArtifactCreator())) {
2116 log.error("artifact creator cannot be set ignoring");
2118 artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator());
2119 if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater().equals(artifactInfo.getUserIdLastUpdater())) {
2120 log.error("userId of last updater cannot be set ignoring");
2122 artifactInfo.setUserIdLastUpdater(user.getUserId());
2123 if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName().equals(artifactInfo.getCreatorFullName())) {
2124 log.error("creator Full name cannot be set ignoring");
2126 artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName());
2127 if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName().equals(artifactInfo.getUpdaterFullName())) {
2128 log.error("updater Full name cannot be set ignoring");
2130 String fullName = user.getFirstName() + " " + user.getLastName();
2131 artifactInfo.setUpdaterFullName(fullName);
2132 if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate().equals(artifactInfo.getCreationDate())) {
2133 log.error("Creation Date cannot be set ignoring");
2135 artifactInfo.setCreationDate(currentArtifact.getCreationDate());
2136 if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate().equals(artifactInfo.getLastUpdateDate())) {
2137 log.error("Last Update Date cannot be set ignoring");
2139 long time = System.currentTimeMillis();
2140 artifactInfo.setLastUpdateDate(time);
2141 if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) {
2142 log.error("es id cannot be set ignoring");
2144 artifactInfo.setEsId(currentArtifact.getUniqueId());
2145 if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName()
2146 .equals(artifactInfo.getArtifactDisplayName())) {
2147 log.error(" Artifact Display Name cannot be set ignoring");
2149 artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName());
2150 if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi().equals(artifactInfo.getServiceApi())) {
2151 log.debug("serviceApi cannot be set. ignoring.");
2153 artifactInfo.setServiceApi(currentArtifact.getServiceApi());
2154 if (artifactInfo.getArtifactGroupType() != null && currentArtifact.getArtifactGroupType() != artifactInfo.getArtifactGroupType()) {
2155 log.debug("artifact group cannot be set. ignoring.");
2157 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2158 artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion());
2159 if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID().isEmpty() && !currentArtifact.getArtifactUUID()
2160 .equals(artifactInfo.getArtifactUUID())) {
2161 log.debug("artifact UUID cannot be set. ignoring.");
2163 artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID());
2164 if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo.getHeatParameters().isEmpty()
2165 && !currentArtifact.getHeatParameters().isEmpty()) {
2166 checkAndSetUnupdatableHeatParams(artifactInfo.getListHeatParameters(), currentArtifact.getListHeatParameters());
2170 private void checkAndSetUnupdatableHeatParams(List<HeatParameterDefinition> heatParameters, List<HeatParameterDefinition> currentParameters) {
2171 Map<String, HeatParameterDefinition> currentParametersMap = getMapOfParameters(currentParameters);
2172 for (HeatParameterDefinition parameter : heatParameters) {
2173 HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId());
2174 if (currentParam != null) {
2175 if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) {
2176 log.debug("heat parameter name cannot be updated ({}). ignoring.", parameter.getName());
2177 parameter.setName(currentParam.getName());
2179 if (parameter.getDefaultValue() != null && !parameter.getDefaultValue().equalsIgnoreCase(currentParam.getDefaultValue())) {
2180 log.debug("heat parameter defaultValue cannot be updated ({}). ignoring.", parameter.getDefaultValue());
2181 parameter.setDefaultValue(currentParam.getDefaultValue());
2183 if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) {
2184 log.debug("heat parameter type cannot be updated ({}). ignoring.", parameter.getType());
2185 parameter.setType(currentParam.getType());
2187 if (parameter.getDescription() != null && !parameter.getDescription().equalsIgnoreCase(currentParam.getDescription())) {
2188 log.debug("heat parameter description cannot be updated ({}). ignoring.", parameter.getDescription());
2189 parameter.setDescription(currentParam.getDescription());
2191 // check and set current value
2192 if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) {
2193 log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue());
2194 parameter.setCurrentValue(currentParam.getDefaultValue());
2200 private Map<String, HeatParameterDefinition> getMapOfParameters(List<HeatParameterDefinition> currentParameters) {
2201 Map<String, HeatParameterDefinition> currentParamsMap = new HashMap<>();
2202 for (HeatParameterDefinition param : currentParameters) {
2203 currentParamsMap.put(param.getUniqueId(), param);
2205 return currentParamsMap;
2208 private Either<Boolean, ResponseFormat> validateAndServiceApiUrl(ArtifactDefinition artifactInfo) {
2209 if (!ValidationUtils.validateStringNotEmpty(artifactInfo.getApiUrl())) {
2210 log.debug("Artifact url cannot be empty.");
2211 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL));
2213 artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase());
2214 if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) {
2215 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL));
2217 if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) {
2219 .right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH)));
2221 return Either.left(true);
2224 private Either<Boolean, ResponseFormat> validateAndCleanDescription(ArtifactDefinition artifactInfo) {
2225 if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) {
2226 log.debug("Artifact description cannot be empty.");
2227 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION));
2229 String description = artifactInfo.getDescription();
2230 description = ValidationUtils.removeNoneUtf8Chars(description);
2231 description = ValidationUtils.normaliseWhitespace(description);
2232 description = ValidationUtils.stripOctets(description);
2233 description = ValidationUtils.removeHtmlTagsOnly(description);
2234 if (!ValidationUtils.validateIsEnglish(description)) {
2235 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2237 if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) {
2238 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION,
2239 String.valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)));
2241 artifactInfo.setDescription(description);
2242 return Either.left(true);
2245 private <T> Either<ArtifactDefinition, T> updateArtifactFlow(Component parent, String parentId, String artifactId,
2246 ArtifactDefinition artifactInfo, byte[] decodedPayload,
2247 ComponentTypeEnum componentType, AuditingActionEnum auditingAction) {
2248 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
2249 if (artifactData == null) {
2250 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2251 log.debug("Failed to create artifact object for ES.");
2252 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
2254 log.debug("Entry on graph is updated. Update artifact in ES");
2255 // Changing previous and current artifactId for auditing
2256 String currArtifactId = artifactInfo.getUniqueId();
2257 NodeTypeEnum parentType = convertParentType(componentType);
2258 if (decodedPayload == null) {
2259 if (!artifactInfo.getMandatory() || artifactInfo.getEsId() != null) {
2260 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactInfo.getEsId());
2261 if (artifactFromCassandra.isRight()) {
2262 throw new StorageException(artifactFromCassandra.right().value());
2264 // clone data to new artifact
2265 artifactData.setData(artifactFromCassandra.left().value().getData());
2266 artifactData.setId(artifactFromCassandra.left().value().getId());
2268 } else if (artifactInfo.getEsId() == null) {
2269 artifactInfo.setEsId(artifactInfo.getUniqueId());
2270 artifactData.setId(artifactInfo.getUniqueId());
2272 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
2273 .updateArtifactOnResource(artifactInfo, parent, artifactId, parentType, parentId, true);
2274 if (result.isRight()) {
2275 throw new StorageException(result.right().value());
2277 ArtifactDefinition artifactDefinition = result.left().value();
2278 updateGeneratedIdInHeatEnv(parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType);
2279 StorageOperationStatus storageOperationStatus = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
2280 if (storageOperationStatus != StorageOperationStatus.OK) {
2281 throw new StorageException(storageOperationStatus);
2283 if (artifactData.getData() != null) {
2284 if (!artifactDefinition.getDuplicated() || artifactData.getId() == null) {
2285 artifactData.setId(artifactDefinition.getEsId());
2287 saveArtifactInCassandra(artifactData, parent, artifactInfo, currArtifactId, artifactId, auditingAction, componentType);
2289 return Either.left(artifactDefinition);
2292 private String updateGeneratedIdInHeatEnv(Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo,
2293 ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2294 if (NodeTypeEnum.Resource == parentType) {
2295 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parent, parentId, artifactId, artifactInfo, artifactDefinition,
2298 return artifactDefinition.getUniqueId();
2301 private String updateGeneratedIdInHeatEnv(Map<String, ArtifactDefinition> deploymentArtifacts, Component parentComponent, String parentId,
2302 String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2303 NodeTypeEnum parentType, boolean isInstanceArtifact) {
2304 String artifactUniqueId;
2305 artifactUniqueId = artifactDefinition.getUniqueId();
2306 String artifactType = artifactInfo.getArtifactType();
2307 if ((ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType)
2308 || ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType)) && !artifactUniqueId.equals(artifactId)) {
2309 // need to update the generated id in heat env
2310 Optional<Entry<String, ArtifactDefinition>> findFirst = deploymentArtifacts.entrySet().stream()
2311 .filter(a -> artifactId.equals(a.getValue().getGeneratedFromId())).findFirst();
2312 if (findFirst.isPresent()) {
2313 ArtifactDefinition artifactEnvInfo = findFirst.get().getValue();
2314 artifactEnvInfo.setIsFromCsar(artifactDefinition.getIsFromCsar());
2315 artifactEnvInfo.setArtifactChecksum(null);
2316 if (isInstanceArtifact) {
2317 artifactToscaOperation
2318 .updateHeatEnvArtifactOnInstance(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2320 artifactToscaOperation
2321 .updateHeatEnvArtifact(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2325 return artifactUniqueId;
2328 private String updateGeneratedIdInHeatEnvOnInstance(ComponentInstance parent, Component parentComponent, String artifactId,
2329 ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2330 NodeTypeEnum parentType) {
2331 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parentComponent, parent.getUniqueId(), artifactId, artifactInfo,
2332 artifactDefinition, parentType, true);
2336 private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) {
2337 log.trace("Starting payload handling");
2338 byte[] payload = artifactInfo.getPayloadData();
2339 byte[] decodedPayload = null;
2340 if (payload != null && payload.length != 0) {
2341 // the generated artifacts were already decoded by the handler
2342 decodedPayload = artifactInfo.getGenerated() ? payload : Base64.decodeBase64(payload);
2343 if (decodedPayload.length == 0) {
2344 log.debug("Failed to decode the payload.");
2345 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
2346 return Either.right(responseFormat);
2348 String checkSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(decodedPayload);
2349 artifactInfo.setArtifactChecksum(checkSum);
2350 log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum);
2351 // Specific payload validations of different types
2352 Either<Boolean, ResponseFormat> result = Either.left(true);
2353 if (isDeploymentArtifact(artifactInfo)) {
2354 log.trace("Starting deployment artifacts payload validation");
2355 String artifactType = artifactInfo.getArtifactType();
2356 String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName());
2357 PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension);
2358 final Optional<ResponseFormat> pmDictionaryError = validateIfPmDictionary(artifactType, decodedPayload);
2359 if (pmDictionaryError.isPresent()) {
2360 return Either.right(pmDictionaryError.get());
2362 Either<Boolean, ActionStatus> isPayloadValid = payloadType.isValid(decodedPayload);
2363 if (isPayloadValid.isRight()) {
2364 ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType);
2365 return Either.right(responseFormat);
2367 if (payloadType.isHeatRelated()) {
2368 log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType);
2369 result = extractHeatParameters(artifactInfo);
2372 if (result.isRight()) {
2373 return Either.right(result.right().value());
2375 } // null/empty payload is normal if called from metadata update ONLY.
2377 // The validation of whether this is metadata/payload update case is
2379 // currently done separately
2381 if (!isArtifactMetadataUpdate) {
2382 log.debug("In artifact: {} Payload is missing.", artifactInfo.getArtifactName());
2383 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
2384 return Either.right(responseFormat);
2387 log.trace("Ended payload handling");
2388 return Either.left(decodedPayload);
2391 private Optional<ResponseFormat> validateIfPmDictionary(String artifactType, byte[] decodedPayload) {
2392 return new PMDictionaryValidator().validateIfPmDictionary(artifactType, decodedPayload).map(this::preparePmDictionaryResponse);
2395 private ResponseFormat preparePmDictionaryResponse(String errorMessage) {
2396 return componentsUtils.getResponseFormat(ActionStatus.INVALID_PM_DICTIONARY_FILE, errorMessage);
2399 public Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface(String resourceId, String userUserId, String artifactId,
2400 boolean inTransaction) {
2401 return toscaOperationFacade.getToscaElement(resourceId, JsonParseFlagEnum.ParseMetadata).right().map(componentsUtils.toResponseFormat())
2402 .left().bind(parentComponent -> {
2403 User user = new User(userUserId);
2404 return handleDelete(resourceId, artifactId, user, parentComponent, false, inTransaction);
2408 private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) {
2409 Operation op = new Operation();
2410 long time = System.currentTimeMillis();
2411 op.setCreationDate(time);
2412 String artifactName = artifactInfo.getArtifactName();
2413 artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName));
2414 op.setImplementation(artifactInfo);
2415 op.setLastUpdateDate(time);
2419 private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) {
2420 String newArtifactName = operationName + "_" + artifactName;
2421 log.trace("converting artifact name {} to {}", artifactName, newArtifactName);
2422 return newArtifactName;
2426 public byte[] downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion,
2427 String artifactName) {
2428 // General validation
2429 if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) {
2430 log.debug(NULL_PARAMETER);
2431 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2433 // Normalizing artifact name
2434 artifactName = ValidationUtils.normalizeFileName(artifactName);
2435 // Resource validation
2436 Resource resource = validateResourceNameAndVersion(resourceName, resourceVersion);
2437 String resourceId = resource.getUniqueId();
2438 // Service validation
2439 Service validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion);
2440 Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts();
2441 if (artifacts == null || artifacts.isEmpty()) {
2442 log.debug("Deployment artifacts of resource {} are not found", resourceId);
2443 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2445 ArtifactDefinition deploymentArtifact = null;
2446 for (ArtifactDefinition artifactDefinition : artifacts.values()) {
2447 if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName().equals(artifactName)) {
2448 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2449 deploymentArtifact = artifactDefinition;
2453 if (deploymentArtifact == null) {
2454 log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId);
2455 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2457 // Downloading the artifact
2458 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deploymentArtifact);
2459 log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId());
2460 return downloadArtifactEither.getRight();
2464 public byte[] downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) {
2465 // General validation
2466 if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) {
2467 log.debug(NULL_PARAMETER);
2468 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2470 // Normalizing artifact name
2471 artifactName = ValidationUtils.normalizeFileName(artifactName);
2472 // Service validation
2473 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2474 // ResourceInstance validation
2475 ComponentInstance resourceInstance = validateResourceInstance(service, resourceInstanceName);
2476 Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
2477 final String finalArtifactName = artifactName;
2478 Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName);
2479 ArtifactDefinition deployableArtifact =
2480 artifacts == null ? null : artifacts.values().stream().filter(filterArtifactByName).findFirst().orElse(null);
2481 if (deployableArtifact == null) {
2482 log.debug("Deployment artifact with name {} not found", artifactName);
2483 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
2485 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2486 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deployableArtifact);
2487 log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId());
2488 return downloadArtifactEither.getRight();
2491 private ComponentInstance validateResourceInstance(Service service, String resourceInstanceName) {
2492 List<ComponentInstance> riList = service.getComponentInstances();
2493 for (ComponentInstance ri : riList) {
2494 if (ri.getNormalizedName().equals(resourceInstanceName)) {
2498 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName);
2501 private ComponentInstance validateResourceInstanceById(Component component, String resourceInstanceId) {
2502 List<ComponentInstance> riList = component.getComponentInstances();
2503 for (ComponentInstance ri : riList) {
2504 if (ri.getUniqueId().equals(resourceInstanceId)) {
2508 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceInstanceId);
2511 private Service validateServiceNameAndVersion(String serviceName, String serviceVersion) {
2512 Either<List<Service>, StorageOperationStatus> serviceListBySystemName = toscaOperationFacade
2513 .getBySystemName(ComponentTypeEnum.SERVICE, serviceName);
2514 if (serviceListBySystemName.isRight()) {
2515 log.debug("Couldn't fetch any service with name {}", serviceName);
2516 throw new ByActionStatusComponentException(
2517 componentsUtils.convertFromStorageResponse(serviceListBySystemName.right().value(), ComponentTypeEnum.SERVICE), serviceName);
2519 List<Service> serviceList = serviceListBySystemName.left().value();
2520 if (serviceList == null || serviceList.isEmpty()) {
2521 log.debug("Couldn't fetch any service with name {}", serviceName);
2522 throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceName);
2524 Service foundService = null;
2525 for (Service service : serviceList) {
2526 if (service.getVersion().equals(serviceVersion)) {
2527 log.trace("Found service with version {}", serviceVersion);
2528 foundService = service;
2532 if (foundService == null) {
2533 log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName);
2534 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE.getValue(),
2537 return foundService;
2540 private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2541 Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade
2542 .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2543 if (resourceListBySystemName.isRight()) {
2544 log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2545 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()),
2548 return resourceListBySystemName.left().value();
2551 public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2553 log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion,
2555 if (serviceName == null || serviceVersion == null || artifactName == null) {
2556 log.debug(NULL_PARAMETER);
2557 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2559 // Normalizing artifact name
2560 final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2561 // Service validation
2562 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2563 // Looking for deployment or tosca artifacts
2564 String serviceId = service.getUniqueId();
2565 if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2566 log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2567 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2569 Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2570 if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2571 foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2572 // filters artifact by name
2573 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2575 if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2576 foundArtifactOptl = service.getToscaArtifacts().values().stream()
2577 // filters TOSCA artifact by name
2578 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2580 if (!foundArtifactOptl.isPresent()) {
2581 log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2582 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2584 log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2585 // Downloading the artifact
2586 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl.get());
2587 log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2588 return downloadArtifactEither.getRight();
2591 public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2592 log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2593 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2594 if (artifactById.isRight()) {
2595 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2596 log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2597 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2599 ArtifactDefinition artifactDefinition = artifactById.left().value();
2600 if (artifactDefinition == null) {
2601 log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2602 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2604 return downloadArtifact(artifactDefinition);
2607 private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId,
2608 ComponentTypeEnum componentType, String containerComponentType) {
2609 ComponentTypeEnum componentForAudit =
2610 null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
2611 componentForAudit.getNodeType();
2612 Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaFullElement(componentId);
2613 if (componentResult.isRight()) {
2614 ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND
2615 : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
2616 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
2617 log.debug("Service not found, serviceId {}", componentId);
2618 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
2619 throw new ByActionStatusComponentException(status, componentId);
2621 return componentResult.left().value();
2624 private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId,
2625 ArtifactOperationInfo operation) {
2626 if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
2628 validateCanWorkOnComponent(component, userId);
2629 } catch (ComponentException e) {
2630 String uniqueId = component.getUniqueId();
2631 log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId);
2632 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(), component.getComponentType(),
2639 private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId,
2640 ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
2641 if (operation.isNotDownload()) {
2642 String role = user.getRole();
2643 if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
2644 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2645 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
2646 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2647 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
2652 private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId,
2653 ComponentTypeEnum componentType, boolean inTransaction) {
2656 user = validateUserExists(userId);
2657 } catch (ByResponseFormatComponentException e) {
2658 ResponseFormat responseFormat = e.getResponseFormat();
2659 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2661 } catch (ByActionStatusComponentException e) {
2662 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2663 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2669 private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId, ResponseFormat responseFormat,
2670 ComponentTypeEnum componentType, String userId) {
2671 User user = new User();
2672 user.setUserId(userId);
2673 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2676 protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
2677 AuditingActionEnum auditingAction = null;
2678 switch (operation.getArtifactOperationEnum()) {
2680 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
2683 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API
2684 : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
2687 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
2690 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
2695 return auditingAction;
2698 private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
2699 String esArtifactId = artifactDefinition.getEsId();
2700 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2701 if (artifactfromES.isRight()) {
2702 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2703 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2704 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
2705 log.debug("Error when getting artifact from ES, error: {}", actionStatus);
2706 throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
2708 DAOArtifactData DAOArtifactData = artifactfromES.left().value();
2709 byte[] data = DAOArtifactData.getDataAsArray();
2711 log.debug("Artifact data from cassandra is null");
2712 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
2714 String artifactName = artifactDefinition.getArtifactName();
2715 log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
2716 return new ImmutablePair<>(artifactName, data);
2719 public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
2720 return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
2723 private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo, String currArtifactId,
2724 String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
2725 CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
2726 if (resourceUploadStatus == CassandraOperationStatus.OK) {
2727 log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
2728 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
2729 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2730 componentType, null);
2732 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2733 log.info(FAILED_SAVE_ARTIFACT);
2734 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2735 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2736 componentType, null);
2737 throw new StorageException(resourceUploadStatus);
2741 private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
2742 return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
2745 private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
2746 return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
2749 private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
2750 return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
2753 private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
2754 final String artifactType = artifactInfo.getArtifactType();
2755 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
2756 if (artifactTypeEnum == null) {
2757 artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
2760 switch (artifactTypeEnum) {
2771 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap,
2772 String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
2773 User user = userBusinessLogic.getUser(userUserId, inTransaction);
2774 return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
2777 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
2778 ArtifactGroupTypeEnum groupType) {
2779 ArtifactDefinition artifactInfo = new ArtifactDefinition();
2780 String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
2781 String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
2782 String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
2783 artifactInfo.setArtifactDisplayName(artifactName);
2784 artifactInfo.setArtifactLabel(logicalName.toLowerCase());
2785 artifactInfo.setArtifactType(artifactType);
2786 artifactInfo.setDescription(artifactDescription);
2787 artifactInfo.setArtifactGroupType(groupType);
2788 nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
2789 setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
2790 return artifactInfo;
2793 private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
2794 String uniqueId = null;
2795 if (resourceId != null) {
2796 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
2797 artifactInfo.setUniqueId(uniqueId);
2799 artifactInfo.setUserIdCreator(user.getUserId());
2800 String fullName = user.getFullName();
2801 artifactInfo.setUpdaterFullName(fullName);
2802 long time = System.currentTimeMillis();
2803 artifactInfo.setCreatorFullName(fullName);
2804 artifactInfo.setCreationDate(time);
2805 artifactInfo.setLastUpdateDate(time);
2806 artifactInfo.setUserIdLastUpdater(user.getUserId());
2807 artifactInfo.setMandatory(true);
2810 public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType,
2811 ArtifactGroupTypeEnum groupType, String instanceId) {
2812 return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
2815 public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact,
2816 Component component, NodeTypeEnum parentType, String instanceId) {
2817 return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
2820 private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
2821 byte[] payload = payloadStr.getBytes();
2822 DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
2823 return Either.left(artifactData);
2827 * @param artifactDefinition
2830 public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType,
2831 Component component, String resourceInstanceName, User modifier,
2832 String instanceId, boolean shouldLock, boolean inTransaction) {
2833 String payload = generateHeatEnvPayload(artifactDefinition);
2834 String prevUUID = artifactDefinition.getArtifactUUID();
2835 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2836 return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2837 shouldLock, inTransaction).left()
2838 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2841 public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition,
2842 ComponentTypeEnum componentType, Component component,
2843 String resourceInstanceName, User modifier, boolean shouldLock,
2844 boolean inTransaction, String instanceId) {
2845 String payload = generateHeatEnvPayload(artifactDefinition);
2846 String prevUUID = artifactDefinition.getArtifactUUID();
2847 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2848 return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2849 shouldLock, inTransaction).left()
2850 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2854 Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID,
2855 ArtifactDefinition clonedBeforeGenerate,
2856 ArtifactDefinition updatedArtDef) {
2857 if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
2858 List<ComponentInstance> componentInstances = component.getComponentInstances();
2859 if (componentInstances != null) {
2860 Optional<ComponentInstance> findFirst = componentInstances.stream().filter(ci -> ci.getUniqueId().equals(instanceId)).findFirst();
2861 if (findFirst.isPresent()) {
2862 ComponentInstance relevantInst = findFirst.get();
2863 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate,
2864 relevantInst.getGroupInstances());
2865 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
2866 updatedGroupInstances.forEach(gi -> {
2867 gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
2868 gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
2870 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
2871 .updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
2872 if (status.isRight()) {
2873 log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
2874 ResponseFormat responseFormat = componentsUtils
2875 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(status.right().value()),
2876 clonedBeforeGenerate.getArtifactDisplayName());
2877 return Either.right(responseFormat);
2883 return Either.left(updatedArtDef);
2886 private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
2887 List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
2888 StringBuilder sb = new StringBuilder();
2889 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
2890 sb.append("parameters:\n");
2891 if (heatParameters != null) {
2892 heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2893 List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
2894 for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
2895 String heatValue = heatParameterDefinition.getCurrentValue();
2896 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2897 heatValue = heatParameterDefinition.getDefaultValue();
2898 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2899 empltyHeatValues.add(heatParameterDefinition);
2903 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
2907 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatValue))
2911 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ")
2912 .append(new BigDecimal(heatValue).toPlainString()).append("\n");
2914 case COMMA_DELIMITED_LIST:
2916 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatValue).append("\n");
2919 String value = heatValue;
2920 boolean starts = value.startsWith("\"");
2921 boolean ends = value.endsWith("\"");
2922 if (!(starts && ends)) {
2923 starts = value.startsWith("'");
2924 ends = value.endsWith("'");
2925 if (!(starts && ends)) {
2926 value = "\"" + value + "\"";
2929 sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value);
2935 if (!empltyHeatValues.isEmpty()) {
2936 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2937 empltyHeatValues.forEach(hv -> {
2938 sb.append(" ").append(hv.getName()).append(":");
2939 HeatParameterType type = HeatParameterType.isValidType(hv.getType());
2940 if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv.getCurrentValue())
2941 || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
2942 sb.append(" \"\"").append("\n");
2944 sb.append(" ").append("\n");
2949 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
2951 return sb.toString().replace("\\\\n", "\n");
2955 * @param artifactDefinition
2959 public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2960 ComponentTypeEnum componentType, Component component,
2961 String resourceInstanceName, User modifier, String instanceId,
2962 boolean shouldLock, boolean inTransaction) {
2963 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2964 artifactDefinition::getHeatParamsUpdateDate, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2967 public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2968 ComponentTypeEnum componentType, Component component,
2969 String resourceInstanceName, User modifier,
2970 String instanceId, boolean shouldLock,
2971 boolean inTransaction) {
2972 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2973 System::currentTimeMillis, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2976 protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition,
2977 ComponentTypeEnum componentType, Component component,
2978 String resourceInstanceName, User modifier, boolean shouldLock,
2979 boolean inTransaction, Supplier<Long> payloadUpdateDateGen,
2980 Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator,
2981 String instanceId) {
2982 log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2983 if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0
2984 || artifactDefinition.getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
2985 log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2986 Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
2987 DAOArtifactData artifactData = null;
2988 if (artifactDataRes.isLeft()) {
2989 artifactData = artifactDataRes.left().value();
2991 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2992 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
2993 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
2994 resourceInstanceName);
2995 return Either.right(artifactDataRes.right().value());
2997 String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
2999 String esArtifactId = artifactDefinition.getEsId();
3000 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
3001 DAOArtifactData DAOArtifactData;
3002 if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
3003 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
3004 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3005 if (artifactfromES.isRight()) {
3006 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3007 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3008 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3009 log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
3010 return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
3012 DAOArtifactData = artifactfromES.left().value();
3013 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3015 oldCheckSum = artifactDefinition.getArtifactChecksum();
3017 Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3020 lockComponent(component, "Update Artifact - lock resource: ");
3021 } catch (ComponentException e) {
3022 handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null,
3023 artifactDefinition.getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3028 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3029 artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3030 updateArifactDefinitionStatus = artifactToscaOperation
3031 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3033 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3034 artifactDefinition.getEsId());
3035 if (updateArifactDefinitionStatus.isRight()) {
3036 ResponseFormat responseFormat = componentsUtils
3037 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3038 artifactDefinition.getArtifactDisplayName());
3039 log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3040 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3041 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3042 resourceInstanceName);
3043 return Either.right(responseFormat);
3046 artifactDefinition.getArtifactChecksum();
3047 artifactDefinition.setArtifactChecksum(newCheckSum);
3048 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3049 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3050 artifactDefinition.getEsId());
3051 updateArifactDefinitionStatus = artifactToscaOperation
3052 .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3054 log.trace("Update Payload {}", artifactDefinition.getEsId());
3056 if (updateArifactDefinitionStatus.isLeft()) {
3057 artifactDefinition = updateArifactDefinitionStatus.left().value();
3058 artifactData.setId(artifactDefinition.getUniqueId());
3059 CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3060 if (saveArtifactStatus == CassandraOperationStatus.OK) {
3061 if (!inTransaction) {
3062 janusGraphDao.commit();
3064 log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3065 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3066 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3067 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3068 resourceInstanceName);
3070 if (!inTransaction) {
3071 janusGraphDao.rollback();
3073 log.info("Failed to save artifact {}.", artifactData.getId());
3074 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3075 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3076 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3077 resourceInstanceName);
3078 return Either.right(responseFormat);
3081 ResponseFormat responseFormat = componentsUtils
3082 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3083 artifactDefinition.getArtifactDisplayName());
3084 log.debug("Failed To update artifact {}", artifactData.getId());
3085 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3086 artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3087 resourceInstanceName);
3088 return Either.right(responseFormat);
3092 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
3096 return Either.left(artifactDefinition);
3099 public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType,
3100 List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3102 .buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType,
3103 artifactDef.getArtifactLabel(), artifactDef.getArtifactDisplayName(), artifactDef.getDescription(), artifactDef.getPayloadData(),
3104 updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3107 public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType,
3108 ArtifactGroupTypeEnum artifactGroupType, String label, String displayName,
3109 String description, byte[] artifactContent,
3110 List<ArtifactTemplateInfo> updatedRequiredArtifacts,
3111 List<HeatParameterDefinition> heatParameters) {
3112 Map<String, Object> json = new HashMap<>();
3113 if (artifactId != null && !artifactId.isEmpty()) {
3114 json.put(Constants.ARTIFACT_ID, artifactId);
3116 json.put(Constants.ARTIFACT_NAME, artifactName);
3117 json.put(Constants.ARTIFACT_TYPE, artifactType);
3118 json.put(Constants.ARTIFACT_DESCRIPTION, description);
3119 if (artifactContent != null) {
3120 log.debug("payload is encoded. perform decode");
3121 String encodedPayload = Base64.encodeBase64String(artifactContent);
3122 json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3124 json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3125 json.put(Constants.ARTIFACT_LABEL, label);
3126 json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3127 json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3128 : updatedRequiredArtifacts.stream().filter(
3129 e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3130 .map(ArtifactTemplateInfo::getFileName).collect(Collectors.toList()));
3131 json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>() : heatParameters);
3135 public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user,
3136 Map<String, Object> json, ArtifactOperationInfo operation,
3137 ArtifactDefinition artifactInfo) {
3138 String jsonStr = gson.toJson(json);
3139 ArtifactDefinition artifactDefinitionFromJson =
3140 artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3141 String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3142 Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE,
3143 operation, artifactUniqueId, artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3144 return Either.left(uploadArtifactToService.left().value());
3147 private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo,
3148 AuditingActionEnum auditingAction, String artifactId, User user,
3149 ComponentTypeEnum componentType, Component parent, String originData,
3150 String origMd5, ArtifactOperationInfo operation) {
3151 if (origMd5 != null) {
3152 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3153 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3154 validateDeploymentArtifact(artifactInfo, parent);
3155 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3156 } else { // duplicate
3157 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3160 return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3163 private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId,
3164 ArtifactDefinition artifactInfo, User user,
3165 AuditingActionEnum auditingAction, Component parent,
3166 ComponentTypeEnum componentType, String origMd5) {
3167 Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3168 if (getRI.isRight()) {
3169 throw new ByResponseFormatComponentException(getRI.right().value());
3171 ComponentInstance ri = getRI.left().value();
3172 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3173 if (getArtifactRes.isRight()) {
3174 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3176 ArtifactDefinition currArtifact = getArtifactRes.left().value();
3177 if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType()
3178 .equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3179 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3181 List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3182 List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3184 if (origMd5 != null) {
3185 Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction,
3186 parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams,
3187 currArtifact.getArtifactName());
3188 if (uploadParamsValidationResult.isRight()) {
3189 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3191 artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3193 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo,
3194 ArtifactTypeEnum.HEAT_ENV.getType());
3195 if (validateAndConvertHeatParamers.isRight()) {
3196 throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3198 if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3199 // fill reduced heat env parameters List for updating
3200 boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3201 if (updateRequired) {
3202 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3203 currArtifact.setListHeatParameters(currentHeatEnvParams);
3204 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3205 .updateArtifactOnResource(currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3206 if (updateArtifactRes.isRight()) {
3207 log.debug("Failed to update artifact on graph - {}", artifactId);
3208 throw new StorageException(updateArtifactRes.right().value());
3210 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(),
3211 parent.getUniqueId());
3212 if (error != StorageOperationStatus.OK) {
3213 throw new StorageException(error);
3217 updateHeatMetaDataIfNeeded(componentId, user, auditingAction, componentType, parent, ri, artifactInfo);
3218 StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3219 if (error != StorageOperationStatus.OK) {
3220 throw new StorageException(error);
3222 return Either.left(currArtifact);
3225 private void updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType,
3226 Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3227 String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3228 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId,
3229 auditingAction, user);
3230 if (getArtifactRes.isRight()) {
3231 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3233 ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3234 if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3235 validateHeatMetaData(updatedHeatEnvArtifact);
3236 updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3237 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3238 .updateArtifactOnResource(heatArtifactToUpdate, parent, heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId,
3240 if (updateArtifactRes.isRight()) {
3241 log.debug("Failed to update artifact on graph - {}", heatArtifactId);
3242 throw new StorageException(updateArtifactRes.right().value());
3244 ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3245 updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition,
3246 componentType.getNodeType());
3247 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(),
3248 parent.getUniqueId());
3249 if (error != StorageOperationStatus.OK) {
3250 throw new StorageException(error);
3255 private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3256 Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3257 Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3258 Integer updateTimeout = updatedHeatEnv.getTimeout();
3259 if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3260 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3264 private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3265 // currently only timeout metadata can be updated
3266 return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3269 private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3270 // currently only timeout metadata can be updated
3271 origHeat.setTimeout(updatedHeatEnv.getTimeout());
3274 private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams,
3275 List<HeatParameterDefinition> updatedHeatEnvParams) {
3276 boolean isUpdate = false;
3277 List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3278 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3279 String paramName = heatEnvParam.getName();
3280 validateParamName(paramName, currentParamsNames);
3281 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3282 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3283 String updatedParamValue = heatEnvParam.getCurrentValue();
3284 if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3285 currHeatParam.setCurrentValue(updatedParamValue);
3294 private void validateParamName(String paramName, List<String> heatParamsNames) {
3295 if (!heatParamsNames.contains(paramName)) {
3296 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3300 private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo,
3301 AuditingActionEnum auditingAction, Component parent,
3302 ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact,
3303 boolean needToUpdateGroup) {
3304 Either<ArtifactDefinition, Operation> insideEither = null;
3305 String currentHeatId = currHeatArtifact.getUniqueId();
3306 String esArtifactId = currHeatArtifact.getEsId();
3307 Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3308 if (artifactFromES.isRight()) {
3309 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3310 throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3312 DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3313 ArtifactDefinition updatedHeatArt = currHeatArtifact;
3314 List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3315 List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3316 List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3317 if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3318 //TODO: improve complexity - currently N^2
3320 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3321 paramName = heatEnvParam.getName();
3322 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3323 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3324 String updatedParamValue = heatEnvParam.getCurrentValue();
3325 if (updatedParamValue == null) {
3326 updatedParamValue = heatEnvParam.getDefaultValue();
3328 HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3329 if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3330 throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE, ArtifactTypeEnum.HEAT_ENV.getType(),
3331 paramType.getType(), paramName);
3333 currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3334 newHeatEnvParams.add(currHeatParam);
3339 if (!newHeatEnvParams.isEmpty()) {
3340 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3341 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation
3342 .updateArtifactOnResource(currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId,
3344 if (operationStatus.isRight()) {
3345 log.debug("Failed to update artifact on graph - {}", currHeatArtifact.getUniqueId());
3346 throw new StorageException(operationStatus.right().value());
3348 updatedHeatArt = operationStatus.left().value();
3349 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3350 DAOArtifactData.setId(updatedHeatArt.getEsId());
3352 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), auditingAction,
3354 insideEither = Either.left(updatedHeatArt);
3357 Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3358 if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3359 artifactEnvInfo.setArtifactChecksum(null);
3360 updateHeatEnvArtifact = artifactToscaOperation
3361 .updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), componentType.getNodeType(),
3364 //TODO Andrey check if componentId = parent.getUniqeId
3365 updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType.getNodeType());
3367 if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3368 ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo, updateHeatEnvArtifact.left().value(), parent);
3369 if (result != ActionStatus.OK) {
3370 throw new ByActionStatusComponentException(result);
3373 if (updatedHeatEnvParams.isEmpty()) {
3374 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3376 return insideEither;
3379 private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3380 StorageOperationStatus error = StorageOperationStatus.OK;
3381 log.debug("Need to re-generate customization UUID for group instance on component instance {}", ri.getUniqueId());
3382 List<GroupInstance> groupsInstances = ri.getGroupInstances();
3383 List<String> groupInstancesId = null;
3384 if (groupsInstances != null && !groupsInstances.isEmpty()) {
3385 groupInstancesId = groupsInstances.stream()
3386 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(artifactId))
3387 .map(GroupInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
3389 if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3390 toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3395 public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent,
3396 User user, ArtifactDefinition artifactInfo,
3397 String artifactId, ComponentTypeEnum componentType,
3399 List<HeatParameterDefinition> currentHeatEnvParams,
3400 List<HeatParameterDefinition> updatedHeatEnvParams,
3401 String currArtifactName) {
3402 if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3403 ResponseFormat responseFormat = componentsUtils
3404 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName);
3405 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3406 return Either.right(responseFormat);
3408 for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3409 String paramName = uploadedHeatParam.getName();
3410 boolean isExistsInHeat = false;
3411 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3412 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3413 isExistsInHeat = true;
3414 uploadedHeatParam.setType(currHeatParam.getType());
3415 uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3416 uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3417 uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3421 if (!isExistsInHeat) {
3422 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3423 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType,
3425 return Either.right(responseFormat);
3428 return Either.left(updatedHeatEnvParams);
3431 private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId,
3432 AuditingActionEnum auditingAction, User user) {
3433 ResponseFormat responseFormat = null;
3434 List<ComponentInstance> ris = component.getComponentInstances();
3435 for (ComponentInstance ri : ris) {
3436 if (riID.equals(ri.getUniqueId())) {
3437 return Either.left(ri);
3440 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3441 log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3442 handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3443 return Either.right(responseFormat);
3446 private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId,
3447 AuditingActionEnum auditingAction, User user) {
3448 ResponseFormat responseFormat = null;
3449 Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3450 for (ArtifactDefinition artifact : rtifactsMap.values()) {
3451 if (artifactId.equals(artifact.getUniqueId())) {
3452 return Either.left(artifact);
3455 responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3456 handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3458 return Either.right(responseFormat);
3461 public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3462 ArtifactDefinition ret;
3463 if (eitherArtifact.isLeft()) {
3464 ret = eitherArtifact.left().value();
3466 ret = eitherArtifact.right().value().getImplementationArtifact();
3471 public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
3472 ResourceCommonInfo resourceCommonInfo) {
3473 Component component = getComponentByUuid(componentType, componentUuid);
3474 resourceCommonInfo.setResourceName(component.getName());
3475 return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3479 * downloads an artifact of resource instance of component by UUIDs
3481 * @param componentType
3482 * @param componentUuid
3483 * @param resourceInstanceName
3484 * @param artifactUUID
3487 public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
3488 String artifactUUID) {
3489 ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3490 if (resourceInstance != null) {
3491 return downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, resourceInstance.getName());
3493 return downloadArtifact(null, artifactUUID, null);
3498 * uploads an artifact to a component by UUID
3502 * @param componentType
3503 * @param componentUuid
3504 * @param resourceCommonInfo
3508 public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3509 String componentUuid, ResourceCommonInfo resourceCommonInfo,
3510 ArtifactOperationInfo operation) {
3511 Either<ArtifactDefinition, Operation> actionResult;
3512 Component component;
3514 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3515 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3516 String userId = request.getHeader(Constants.USER_ID_HEADER);
3517 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3518 ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3519 componentId = componentMetadataDataDefinition.getUniqueId();
3520 String componentName = componentMetadataDataDefinition.getName();
3521 if (!componentMetadataDataDefinition.getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3522 component = checkoutParentComponent(componentType, componentId, userId);
3523 if (component != null) {
3524 componentId = component.getUniqueId();
3525 componentName = component.getName();
3528 resourceCommonInfo.setResourceName(componentName);
3529 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null,
3531 return actionResult.left().value();
3535 * upload an artifact to a resource instance by UUID
3539 * @param componentType
3540 * @param componentUuid
3541 * @param resourceInstanceName
3545 public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3546 String resourceInstanceName, ArtifactOperationInfo operation) {
3547 Either<ArtifactDefinition, Operation> actionResult;
3548 Component component = null;
3549 String componentInstanceId;
3551 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3552 String userId = request.getHeader(Constants.USER_ID_HEADER);
3553 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3554 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid,
3555 resourceInstanceName);
3556 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3557 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3559 if (component == null) {
3560 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3562 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3564 componentInstanceId = componentRiPair.getRight().getUniqueId();
3565 componentId = componentRiPair.getLeft().getUniqueId();
3566 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3567 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5,
3568 data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3569 return actionResult.left().value();
3573 * updates an artifact on a component by UUID
3577 * @param componentType
3578 * @param componentUuid
3579 * @param artifactUUID
3580 * @param resourceCommonInfo
3581 * @param operation TODO
3584 public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3585 String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3586 ArtifactOperationInfo operation) {
3587 Either<ArtifactDefinition, Operation> actionResult;
3588 Component component;
3591 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3592 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3593 String userId = request.getHeader(Constants.USER_ID_HEADER);
3594 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3595 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3596 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3597 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3598 component = checkoutParentComponent(componentType, componentId, userId);
3599 if (component != null) {
3600 componentId = component.getUniqueId();
3601 componentName = component.getName();
3604 resourceCommonInfo.setResourceName(componentName);
3605 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3606 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null,
3608 if (actionResult.isRight()) {
3609 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult.right().value());
3611 return actionResult.left().value();
3615 * updates an artifact on a resource instance by UUID
3619 * @param componentType
3620 * @param componentUuid
3621 * @param resourceInstanceName
3622 * @param artifactUUID
3623 * @param operation TODO
3626 public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3627 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3628 Either<ArtifactDefinition, Operation> actionResult;
3629 Component component = null;
3630 String componentInstanceId;
3633 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3634 String userId = request.getHeader(Constants.USER_ID_HEADER);
3635 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3636 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3637 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3638 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3640 if (component == null) {
3641 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3643 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3645 componentInstanceId = componentRiPair.getRight().getUniqueId();
3646 componentId = componentRiPair.getLeft().getUniqueId();
3647 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3648 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3649 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo,
3650 origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3651 return actionResult.left().value();
3654 private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid,
3655 ArtifactDefinition artifactInfo) {
3656 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3657 if (componentStorageOperationStatusEither.isRight()) {
3658 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3659 log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
3660 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3662 Component storedComponent = componentStorageOperationStatusEither.left().value();
3663 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3664 .getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
3665 if (!optionalInterface.isPresent()) {
3666 log.debug("Failed to get resource interface for resource Id {}", componentId);
3667 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
3669 //fetch the operation from storage
3670 InterfaceDefinition gotInterface = optionalInterface.get();
3671 Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
3672 Optional<Operation> optionalOperation = operationsMap.values().stream().filter(o -> o.getUniqueId().equals(operationUuid)).findFirst();
3673 if (!optionalOperation.isPresent()) {
3674 log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
3675 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
3676 return Either.right(responseFormat);
3678 Operation operation = optionalOperation.get();
3679 ArtifactDefinition implementationArtifact = operation.getImplementationArtifact();
3680 implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
3681 implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
3682 implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
3683 implementationArtifact.setDescription(artifactInfo.getDescription());
3684 implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
3685 implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
3686 implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
3687 implementationArtifact.setEsId(artifactInfo.getEsId());
3688 operation.setImplementation(implementationArtifact);
3689 gotInterface.setOperationsMap(operationsMap);
3690 Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = interfaceOperation
3691 .updateInterfaces(storedComponent.getUniqueId(), Collections.singletonList(gotInterface));
3692 if (interfaceDefinitionStorageOperationStatusEither.isRight()) {
3693 StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
3694 ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
3695 return Either.right(componentsUtils.getResponseFormat(actionStatus));
3697 return Either.left(artifactInfo);
3701 * updates an artifact on a component by UUID
3705 * @param componentType
3706 * @param componentUuid
3707 * @param artifactUUID
3711 public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(String data, HttpServletRequest request,
3712 ComponentTypeEnum componentType,
3713 String componentUuid, String interfaceUUID,
3714 String operationUUID, String artifactUUID,
3715 ResourceCommonInfo resourceCommonInfo,
3716 ArtifactOperationInfo operation) {
3717 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
3718 Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
3719 String componentId = null;
3720 ArtifactDefinition existingArtifactInfo = null;
3721 String interfaceName = null;
3722 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3723 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3724 String userId = request.getHeader(Constants.USER_ID_HEADER);
3725 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3726 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(as));
3729 if (errorWrapper.isEmpty()) {
3730 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3731 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3732 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3733 Component component = checkoutParentComponent(componentType, componentId, userId);
3734 if (component != null) {
3735 componentId = component.getUniqueId();
3736 componentName = component.getName();
3739 resourceCommonInfo.setResourceName(componentName);
3741 if (errorWrapper.isEmpty()) {
3742 Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
3743 if (interfaceNameEither.isRight()) {
3744 errorWrapper.setInnerElement(interfaceNameEither.right().value());
3746 interfaceName = interfaceNameEither.left().value();
3748 if (errorWrapper.isEmpty()) {
3749 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
3750 if (toscaComponentEither.isRight()) {
3751 StorageOperationStatus status = toscaComponentEither.right().value();
3752 log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
3753 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
3755 if (errorWrapper.isEmpty()) {
3756 NodeTypeEnum parentType = convertParentType(componentType);
3757 final List<ArtifactDefinition> existingDeploymentArtifacts = getDeploymentArtifacts(toscaComponentEither.left().value(), null);
3758 for (ArtifactDefinition artifactDefinition : existingDeploymentArtifacts) {
3759 if (artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())) {
3760 existingArtifactInfo = artifactDefinition;
3764 if (existingArtifactInfo != null) {
3765 return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
3770 if (errorWrapper.isEmpty()) {
3771 updateArtifactResult = handleArtifactRequestAndFlatten(componentId, userId, componentType, operation, artifactUUID, artifactInfo, origMd5,
3772 data, interfaceName, operationUUID);
3774 updateArtifactResult = Either.right(errorWrapper.getInnerElement());
3776 return updateArtifactResult;
3779 private Either<ArtifactDefinition, ResponseFormat> handleArtifactRequestAndFlatten(String componentId, String userId,
3780 ComponentTypeEnum componentType,
3781 ArtifactOperationInfo operation, String artifactId,
3782 ArtifactDefinition artifactInfo, String origMd5,
3783 String originData, String interfaceName,
3784 String operationName) {
3786 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
3787 operationName, null, null).right().map(op -> {
3788 log.debug("Unexpected value returned while calling handleArtifactRequest: {}", op);
3789 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3791 } catch (ComponentException e) {
3792 return Either.right(e.getResponseFormat());
3796 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid) {
3797 return fetchLatestComponentMetadataOrThrow(componentType, componentUuid, componentUuid);
3800 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid,
3801 String resourceInstanceName) {
3802 return fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3803 throw new ByActionStatusComponentException(as, resourceInstanceName);
3807 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadata(ComponentTypeEnum componentType, String componentUuid) {
3808 return toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true).right().map(sos -> {
3809 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, sos);
3810 return componentsUtils.convertFromStorageResponse(sos, componentType);
3814 private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
3815 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3816 if (componentStorageOperationStatusEither.isRight()) {
3817 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3818 log.debug("Failed to fetch component information by component id, error {}", errorStatus);
3819 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3821 Component storedComponent = componentStorageOperationStatusEither.left().value();
3822 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3823 .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
3824 if (!optionalInterface.isPresent()) {
3825 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
3827 return Either.left(optionalInterface.get().getType());
3831 * deletes an artifact on a component by UUID
3834 * @param componentType
3835 * @param componentUuid
3836 * @param artifactUUID
3837 * @param resourceCommonInfo
3838 * @param operation TODO
3841 public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3842 String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3843 ArtifactOperationInfo operation) {
3844 Either<ArtifactDefinition, Operation> actionResult;
3845 Component component;
3848 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3849 String userId = request.getHeader(Constants.USER_ID_HEADER);
3850 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3851 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3852 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3853 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3854 component = checkoutParentComponent(componentType, componentId, userId);
3855 if (component != null) {
3856 componentId = component.getUniqueId();
3857 componentName = component.getName();
3860 resourceCommonInfo.setResourceName(componentName);
3861 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3862 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
3863 return actionResult.left().value();
3867 * deletes an artifact from a resource instance by UUID
3870 * @param componentType
3871 * @param componentUuid
3872 * @param resourceInstanceName
3873 * @param artifactUUID
3874 * @param operation TODO
3877 public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3878 String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3879 Either<ArtifactDefinition, Operation> actionResult;
3880 Component component = null;
3881 String componentInstanceId;
3884 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3885 String userId = request.getHeader(Constants.USER_ID_HEADER);
3886 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3887 Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3888 if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3889 component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3891 if (component == null) {
3892 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3894 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3896 componentInstanceId = componentRiPair.getRight().getUniqueId();
3897 componentId = componentRiPair.getLeft().getUniqueId();
3898 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3899 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5,
3900 null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3901 return actionResult.left().value();
3904 private String findArtifactId(ComponentInstance instance, String artifactUUID) {
3905 String artifactId = null;
3906 ArtifactDefinition foundArtifact = null;
3907 if (instance.getDeploymentArtifacts() != null) {
3908 foundArtifact = instance.getDeploymentArtifacts().values().stream()
3909 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3911 if (foundArtifact == null && instance.getArtifacts() != null) {
3912 foundArtifact = instance.getArtifacts().values().stream()
3913 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3915 if (foundArtifact == null) {
3916 log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
3917 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
3919 artifactId = foundArtifact.getUniqueId();
3924 @SuppressWarnings("unchecked")
3925 public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact, String envType,
3926 String parentId, NodeTypeEnum parentType, String parentName, User user, Component component,
3927 Map<String, String> existingEnvVersions) {
3928 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
3929 .getDeploymentResourceInstanceArtifacts();
3930 if (deploymentResourceArtifacts == null) {
3931 log.debug("no deployment artifacts are configured for generated artifacts");
3932 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3934 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
3935 if (placeHolderData == null) {
3936 log.debug("no env type {} are configured for generated artifacts", envType);
3937 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3939 String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
3940 ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user.getUserId(),
3941 ArtifactGroupTypeEnum.DEPLOYMENT, true);
3942 ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
3943 artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
3944 artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
3945 artifactHeatEnv.setTimeout(0);
3946 artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
3947 buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
3948 // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
3949 handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
3950 ArtifactDefinition heatEnvPlaceholder;
3951 // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
3952 if (parentType != NodeTypeEnum.ResourceInstance) {
3953 String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
3954 artifactHeatEnv.setArtifactChecksum(checkSum);
3955 Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component,
3956 parentType, parentId);
3957 if (addHeatEnvArtifact.isRight()) {
3958 log.debug("failed to create heat env artifact on resource instance");
3959 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(
3960 componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact.right().value(), false), "", null));
3962 heatEnvPlaceholder = createArtifactPlaceHolder;
3964 heatEnvPlaceholder = artifactHeatEnv;
3965 artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
3966 setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
3968 ComponentTypeEnum componentType = component.getComponentType();
3969 if (parentType == NodeTypeEnum.ResourceInstance) {
3970 componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
3972 createdArtifacts.add(heatEnvPlaceholder);
3973 componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
3974 new ResourceCommonInfo(parentName, componentType.getValue()), ResourceVersionInfo.newBuilder().build(),
3975 ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(), null, heatEnvPlaceholder, null);
3976 return heatEnvPlaceholder;
3979 private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
3980 if (artifact.getListHeatParameters() == null) {
3983 List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
3984 for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
3985 HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
3986 heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
3987 heatEnvParameter.setCurrentValue(null);
3988 heatEnvParameters.add(heatEnvParameter);
3990 artifactDefinition.setListHeatParameters(heatEnvParameters);
3993 private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
3994 String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
3995 String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
3996 String name = heatArtifact.getArtifactName();
3999 name = heatArtifact.getArtifactLabel();
4000 fileName = name + "." + envExtension;
4002 fileName = name.replaceAll("." + heatExtension, "." + envExtension);
4004 heatEnvArtifact.setArtifactName(fileName);
4007 private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
4008 if (null != existingEnvVersions) {
4009 String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
4010 if (null != prevVersion) {
4011 heatEnvArtifact.setArtifactVersion(prevVersion);
4016 public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user,
4017 List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4018 ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4019 ComponentTypeEnum componentType = component.getComponentType();
4020 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4021 Either<ArtifactDefinition, Operation> result;
4023 for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4024 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4025 uploadedArtifacts.add(result.left().value());
4027 } catch (ComponentException e) {
4028 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component.getName(), e.getResponseFormat());
4029 if (operation.isCreateOrLink()) {
4030 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4034 return uploadedArtifacts;
4037 public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Component component, User user, ArtifactOperationInfo operation,
4038 boolean shouldLock, boolean inTransaction, ComponentTypeEnum componentType,
4039 ArtifactDefinition artifactDefinition) {
4040 AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4041 String componentId = component.getUniqueId();
4042 String artifactId = artifactDefinition.getUniqueId();
4043 Either<ArtifactDefinition, Operation> result;
4044 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4045 //artifact validation
4046 artifactDefinition = validateArtifact(componentId, componentType, operation, artifactId, artifactDefinition, auditingAction, user, component,
4047 shouldLock, inTransaction);
4048 switch (operation.getArtifactOperationEnum()) {
4050 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType,
4051 component, null, null);
4052 result = createArtifact(component, componentId, artifactDefinition, validPayload, componentType, auditingAction, null, null);
4055 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component,
4057 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4058 auditingAction, user, component, true);
4061 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4064 if (artifactGenerationRequired(component, artifactDefinition)) {
4065 result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4067 result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4071 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4074 throw new UnsupportedOperationException(
4075 "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4080 public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component,
4081 User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4082 ArtifactOperationInfo operation, boolean shouldLock,
4083 boolean inTransaction) {
4084 List<ArtifactDefinition> handleArtifactsResult;
4085 ComponentTypeEnum componentType = component.getComponentType();
4086 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4087 Either<ArtifactDefinition, Operation> actionResult;
4091 for (ArtifactDefinition artifact : artifactsToHandle) {
4092 originData = ArtifactUtils.buildJsonStringForCsarVfcArtifact(artifact);
4093 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4094 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact.getUniqueId(),
4095 artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4096 uploadedArtifacts.add(actionResult.left().value());
4098 handleArtifactsResult = uploadedArtifacts;
4099 } catch (ComponentException e) {
4100 if (operation.isCreateOrLink()) {
4101 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4105 return handleArtifactsResult;
4108 private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName) {
4109 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4110 Option<Component> oComponent = Option.of(getComponentByUuid(componentType, componentUuid));
4111 return oComponent.toTry(componentNotFound(componentType, componentUuid)).flatMap(
4112 component -> findFirstMatching(component, ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4113 .toTry(componentInstanceNotFound(componentType, resourceInstanceName, component))).get();
4116 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName) {
4117 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4118 ComponentInstance componentInstance = findFirstMatching(component,
4119 ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4120 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4121 return new ImmutablePair<>(component, componentInstance);
4124 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid,
4125 String resourceInstanceName) {
4126 Component component = getLatestComponentByUuid(componentType, componentUuid);
4127 ComponentInstance componentInstance = findFirstMatching(component, ci -> ci.getNormalizedName().equals(resourceInstanceName))
4128 .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4129 return new ImmutablePair<>(component, componentInstance);
4132 private Supplier<Throwable> componentNotFound(ComponentTypeEnum componentType, String componentUuid) {
4134 log.debug(FAILED_FETCH_COMPONENT, componentType.getValue(), componentUuid);
4135 return new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentUuid);
4139 private Supplier<Throwable> componentInstanceNotFound(ComponentTypeEnum componentType, String resourceInstanceName, Component component) {
4141 log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4142 return new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4143 RESOURCE_INSTANCE, componentType.getValue(), component.getName());
4147 private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4148 ImmutablePair<String, byte[]> downloadArtifact;
4149 List<ArtifactDefinition> artifactsList = null;
4150 ArtifactDefinition deploymentArtifact;
4151 if (artifacts != null && !artifacts.isEmpty()) {
4152 artifactsList = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID))
4153 .collect(Collectors.toList());
4155 if (artifactsList == null || artifactsList.isEmpty()) {
4156 log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4157 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4159 deploymentArtifact = artifactsList.get(0);
4160 downloadArtifact = downloadArtifact(deploymentArtifact);
4161 log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4162 return downloadArtifact.getRight();
4165 private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4166 Component component;
4167 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4168 if (getComponentRes.isRight()) {
4169 StorageOperationStatus status = getComponentRes.right().value();
4170 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4171 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4173 component = getComponentRes.left().value();
4178 private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4179 Component component;
4180 Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4181 if (getComponentRes.isRight()) {
4182 StorageOperationStatus status = getComponentRes.right().value();
4183 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4184 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4186 List<Component> value = getComponentRes.left().value();
4187 if (value.isEmpty()) {
4188 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4189 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4190 throw new ByActionStatusComponentException(status);
4192 component = value.get(0);
4198 private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4199 ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4200 StorageOperationStatus storageStatus;
4201 ArtifactDefinition latestArtifact;
4202 List<ArtifactDefinition> artifacts;
4203 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4204 if (getArtifactsRes.isRight()) {
4205 storageStatus = getArtifactsRes.right().value();
4206 log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4207 if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4208 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4210 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4212 artifacts = getArtifactsRes.left().value().values().stream()
4213 .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList());
4214 if (artifacts == null || artifacts.isEmpty()) {
4215 log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4216 parentId, actionStatus);
4217 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4219 latestArtifact = artifacts.stream().max((a1, a2) -> {
4220 int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4221 if (compareRes == 0) {
4222 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(),
4223 a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate());
4227 if (latestArtifact == null) {
4228 log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4229 parentId, actionStatus);
4230 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4232 return latestArtifact.getUniqueId();
4235 private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4236 Component component = null;
4237 User modifier = userBusinessLogic.getUser(userId, false);
4238 LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout",
4239 LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4240 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
4241 .changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4242 if (checkoutRes.isRight()) {
4243 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId,
4244 checkoutRes.right().value().getStatus());
4245 throw new ByResponseFormatComponentException(checkoutRes.right().value());
4247 return checkoutRes.left().value();
4251 void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4252 this.nodeTemplateOperation = nodeTemplateOperation;
4255 public List<ArtifactConfiguration> getConfiguration() {
4256 return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
4259 public enum ArtifactOperationEnum {
4260 CREATE, UPDATE, DELETE, DOWNLOAD, LINK;
4262 public static boolean isCreateOrLink(ArtifactOperationEnum operation) {
4263 return operation == CREATE || operation == LINK;