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 * ================================================================================
23 package org.openecomp.sdc.be.components.impl;
25 import static org.openecomp.sdc.be.dao.api.ActionStatus.MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE;
27 import com.google.common.annotations.VisibleForTesting;
28 import com.google.gson.Gson;
29 import com.google.gson.GsonBuilder;
30 import fj.data.Either;
31 import io.vavr.control.Option;
32 import java.io.ByteArrayInputStream;
33 import java.io.IOException;
34 import java.math.BigDecimal;
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.Comparator;
38 import java.util.HashMap;
39 import java.util.Iterator;
40 import java.util.List;
42 import java.util.Map.Entry;
43 import java.util.Objects;
44 import java.util.Optional;
46 import java.util.function.Consumer;
47 import java.util.function.Function;
48 import java.util.function.Predicate;
49 import java.util.function.Supplier;
50 import java.util.stream.Collectors;
51 import javax.servlet.http.HttpServletRequest;
52 import javax.xml.XMLConstants;
53 import javax.xml.parsers.ParserConfigurationException;
54 import javax.xml.parsers.SAXParser;
55 import javax.xml.parsers.SAXParserFactory;
56 import org.apache.commons.codec.binary.Base64;
57 import org.apache.commons.collections.CollectionUtils;
58 import org.apache.commons.collections.MapUtils;
59 import org.apache.commons.io.FilenameUtils;
60 import org.apache.commons.lang.ArrayUtils;
61 import org.apache.commons.lang.StringUtils;
62 import org.apache.commons.lang3.tuple.ImmutablePair;
63 import org.openecomp.sdc.be.components.ArtifactsResolver;
64 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
65 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
66 import org.openecomp.sdc.be.components.impl.artifact.ArtifactTypeToPayloadTypeSelector;
67 import org.openecomp.sdc.be.components.impl.artifact.PayloadTypeEnum;
68 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
69 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
70 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
71 import org.openecomp.sdc.be.components.impl.utils.ComponentUtils;
72 import org.openecomp.sdc.be.components.impl.validation.PMDictionaryValidator;
73 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
74 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
75 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
76 import org.openecomp.sdc.be.components.utils.ArtifactUtils;
77 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
78 import org.openecomp.sdc.be.config.ArtifactConfiguration;
79 import org.openecomp.sdc.be.config.BeEcompErrorManager;
80 import org.openecomp.sdc.be.config.Configuration;
81 import org.openecomp.sdc.be.config.Configuration.ArtifactTypeConfig;
82 import org.openecomp.sdc.be.config.ConfigurationManager;
83 import org.openecomp.sdc.be.dao.api.ActionStatus;
84 import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
85 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
86 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
87 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
88 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
89 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
90 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
91 import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition;
92 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
93 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
94 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
95 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
96 import org.openecomp.sdc.be.info.ArtifactTemplateInfo;
97 import org.openecomp.sdc.be.model.ArtifactDefinition;
98 import org.openecomp.sdc.be.model.Component;
99 import org.openecomp.sdc.be.model.ComponentInstance;
100 import org.openecomp.sdc.be.model.ComponentParametersView;
101 import org.openecomp.sdc.be.model.GroupDefinition;
102 import org.openecomp.sdc.be.model.GroupInstance;
103 import org.openecomp.sdc.be.model.HeatParameterDefinition;
104 import org.openecomp.sdc.be.model.InterfaceDefinition;
105 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
106 import org.openecomp.sdc.be.model.LifecycleStateEnum;
107 import org.openecomp.sdc.be.model.Operation;
108 import org.openecomp.sdc.be.model.Resource;
109 import org.openecomp.sdc.be.model.Service;
110 import org.openecomp.sdc.be.model.User;
111 import org.openecomp.sdc.be.model.heat.HeatParameterType;
112 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
113 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
114 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeTemplateOperation;
115 import org.openecomp.sdc.be.model.operations.StorageException;
116 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
117 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
118 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
119 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
120 import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation;
121 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
122 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
123 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
124 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
125 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
126 import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation;
127 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
128 import org.openecomp.sdc.be.resources.data.DAOArtifactData;
129 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
130 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
131 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
132 import org.openecomp.sdc.be.servlets.RepresentationUtils;
133 import org.openecomp.sdc.be.tosca.CsarUtils;
134 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
135 import org.openecomp.sdc.be.user.Role;
136 import org.openecomp.sdc.be.user.UserBusinessLogic;
137 import org.openecomp.sdc.be.utils.TypeUtils;
138 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
139 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
140 import org.openecomp.sdc.common.api.Constants;
141 import org.openecomp.sdc.common.datastructure.Wrapper;
142 import org.openecomp.sdc.common.log.wrappers.Logger;
143 import org.openecomp.sdc.common.util.GeneralUtility;
144 import org.openecomp.sdc.common.util.ValidationUtils;
145 import org.openecomp.sdc.common.util.YamlToObjectConverter;
146 import org.openecomp.sdc.exception.ResponseFormat;
147 import org.springframework.beans.factory.annotation.Autowired;
148 import org.xml.sax.InputSource;
149 import org.xml.sax.SAXException;
150 import org.xml.sax.SAXNotRecognizedException;
151 import org.xml.sax.SAXNotSupportedException;
152 import org.xml.sax.XMLReader;
153 import org.yaml.snakeyaml.Yaml;
155 @org.springframework.stereotype.Component("artifactBusinessLogic")
156 public class ArtifactsBusinessLogic extends BaseBusinessLogic {
157 private static final String RESOURCE_INSTANCE = "resource instance";
158 private static final String ARTIFACT_TYPE_OTHER = "OTHER";
159 private static final String ARTIFACT_DESCRIPTION = "artifact description";
160 private static final String ARTIFACT_LABEL = "artifact label";
161 private static final String ARTIFACT_URL = "artifact url";
162 private static final String ARTIFACT_NAME = "artifact name";
163 private static final String ARTIFACT_PAYLOAD = "artifact payload";
165 private static final String ARTIFACT_PLACEHOLDER_TYPE = "type";
166 private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
167 private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
169 public static final String HEAT_ENV_NAME = "heatEnv";
170 public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
171 public static final String HEAT_ENV_SUFFIX = "env";
172 private static final String ARTIFACT_PLACEHOLDER_FILE_EXTENSION = "fileExtension";
174 private static final Logger log = Logger.getLogger(ArtifactsBusinessLogic.class.getName());
175 private static final String FAILED_UPDATE_GROUPS = "Failed to update groups of the component {}. ";
176 private static final String FAILED_SAVE_ARTIFACT = "Failed to save the artifact.";
177 public static final String ARTIFACT_ACTION_LOCK = "Artifact action - lock ";
178 public static final String FAILED_UPLOAD_ARTIFACT_TO_COMPONENT = "Failed to upload artifact to component with type {} and uuid {}. Status is {}. ";
179 private static final String FAILED_FETCH_COMPONENT = "Could not fetch component with type {} and uuid {}. Status is {}. ";
180 private static final String NULL_PARAMETER = "One of the function parameteres is null";
181 public static final String COMPONENT_INSTANCE_NOT_FOUND = "Component instance {} was not found for component {}";
182 private static final String ROLLBACK = "all changes rollback";
183 private static final String COMMIT = "all changes committed";
184 private static final String UPDATE_ARTIFACT = "Update Artifact";
185 private static final String FOUND_DEPLOYMENT_ARTIFACT = "Found deployment artifact {}";
186 private Gson gson = new GsonBuilder().setPrettyPrinting().create();
188 @javax.annotation.Resource
189 private IInterfaceLifecycleOperation interfaceLifecycleOperation;
190 @javax.annotation.Resource
191 private UserAdminOperation userOperaton;
193 @javax.annotation.Resource
194 private IElementOperation elementOperation;
196 @javax.annotation.Resource
197 private IHeatParametersOperation heatParametersOperation;
199 private ArtifactCassandraDao artifactCassandraDao;
200 private ToscaExportHandler toscaExportUtils;
201 private CsarUtils csarUtils;
202 private LifecycleBusinessLogic lifecycleBusinessLogic;
203 private UserBusinessLogic userBusinessLogic;
204 private ArtifactsResolver artifactsResolver;
205 private NodeTemplateOperation nodeTemplateOperation;
208 public ArtifactsBusinessLogic(ArtifactCassandraDao artifactCassandraDao, ToscaExportHandler toscaExportUtils,
209 CsarUtils csarUtils, LifecycleBusinessLogic lifecycleBusinessLogic, UserBusinessLogic userBusinessLogic,
210 ArtifactsResolver artifactsResolver, IElementOperation elementDao, IGroupOperation groupOperation,
211 IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation, InterfaceOperation interfaceOperation,
212 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsOperations artifactToscaOperation) {
213 super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation,
214 interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation);
215 this.artifactCassandraDao = artifactCassandraDao;
216 this.toscaExportUtils = toscaExportUtils;
217 this.csarUtils = csarUtils;
218 this.lifecycleBusinessLogic = lifecycleBusinessLogic;
219 this.userBusinessLogic = userBusinessLogic;
220 this.artifactsResolver = artifactsResolver;
223 public enum ArtifactOperationEnum {
224 CREATE, UPDATE, DELETE, DOWNLOAD, LINK;
226 public static boolean isCreateOrLink(ArtifactOperationEnum operation) {
227 return operation == CREATE || operation == LINK;
232 public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
233 ArtifactOperationInfo operation, String artifactId, ArtifactDefinition artifactInfo,
234 String origMd5, String originData, String interfaceName, String operationName,
235 String parentId, String containerComponentType, boolean shouldLock, boolean inTransaction) {
237 // step 1 - detect auditing type
238 AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
239 // step 2 - check header
240 if (userId == null) {
241 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
242 log.debug("handleArtifactRequest - no HTTP_CSP_HEADER , component id {}", componentId);
243 handleAuditing(auditingAction, null, componentId, null, null, null, artifactId, responseFormat, componentType, null);
244 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
246 // step 3 - check user existence
247 // step 4 - check user's role
248 User user = validateUserExists(userId, auditingAction, componentId, artifactId, componentType, inTransaction);
249 validateUserRole(user, auditingAction, componentId, artifactId, componentType, operation);
252 // 5. check service/resource existence
253 // 6. check service/resource check out
254 // 7. user is owner of checkout state
255 Component component = null;
256 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
257 component = validateComponentExists(realComponentId, auditingAction, user, artifactId, componentType, containerComponentType);
258 validateWorkOnComponent(component, userId, auditingAction, user, artifactId, operation);
259 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
260 validateResourceInstanceById(component, componentId);
264 return validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5,
265 originData, interfaceName, operationName, user, component, shouldLock, inTransaction, true);
268 public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId, ArtifactDefinition artifactInfo,
269 String origMd5, String originData, String interfaceName, String operationName, String parentId, String containerComponentType) {
270 return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName, operationName, parentId, containerComponentType, true, false);
274 * This Method validates only the Artifact and does not validate user / role / component ect...<br>
275 * For regular usage use <br>
276 * {@link #handleArtifactRequest(String, String, ComponentTypeEnum, ArtifactOperationInfo, String, ArtifactDefinition, String, String, String, String, String, String)}
280 public Either<ArtifactDefinition, Operation> validateAndHandleArtifact(
281 String componentUniqueId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactUniqueId,
282 ArtifactDefinition artifactDefinition, String origMd5, String originData, String interfaceName,
283 String operationName, User user, Component component, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
284 AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
285 artifactDefinition = validateArtifact(componentUniqueId, componentType, operation,
286 artifactUniqueId, artifactDefinition, auditingAction, user,
287 component, shouldLock, inTransaction);
290 Either<ArtifactDefinition, Operation> result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition,
291 origMd5, originData, interfaceName, operationName, auditingAction, user, component, shouldLock, inTransaction, needUpdateGroup);
292 //TODO: audit positive action
297 ArtifactDefinition validateArtifact(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, User user,
298 Component component, boolean shouldLock, boolean inTransaction) {
299 ArtifactDefinition artifactInfoToReturn = artifactInfo;
300 ArtifactOperationEnum operationEnum = operation.getArtifactOperationEnum();
301 if (operationEnum == ArtifactOperationEnum.UPDATE || operationEnum == ArtifactOperationEnum.DELETE || operationEnum == ArtifactOperationEnum.DOWNLOAD) {
302 ArtifactDefinition dbArtifact = getArtifactIfBelongsToComponent(componentId, componentType, artifactId, component);
303 if (operation.isDownload()) {
304 artifactInfoToReturn = dbArtifact;
305 handleHeatEnvDownload(componentId, componentType, user, component, dbArtifact, shouldLock, inTransaction);
308 return artifactInfoToReturn;
312 void handleHeatEnvDownload(String componentId, ComponentTypeEnum componentType, User user, Component component,
313 ArtifactDefinition artifactDefinition, boolean shouldLock, boolean inTransaction) {
315 if (artifactDefinition.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType())
316 && ComponentTypeEnum.SERVICE == component.getComponentType()) {
317 ComponentInstance componentInstance = component.getComponentInstances()
319 .filter(p -> p.getUniqueId().equals(componentId))
322 if (componentInstance == null) {
323 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentId,
324 "instance", "Service", component.getName());
326 Map<String, ArtifactDefinition> deploymentArtifacts = componentInstance.getDeploymentArtifacts();
328 ArtifactDefinition heatEnvWithHeatParams = deploymentArtifacts.values()
330 .filter(p -> p.getUniqueId()
331 .equals(artifactDefinition.getUniqueId()))
334 Either<ArtifactDefinition, ResponseFormat> eitherGenerated = generateHeatEnvArtifact(heatEnvWithHeatParams,
335 componentType, component, componentInstance.getName(), user, componentId, shouldLock, inTransaction);
336 if (eitherGenerated.isRight()) {
337 throw new ByResponseFormatComponentException((eitherGenerated.right().value()));
342 private boolean artifactGenerationRequired(Component component, ArtifactDefinition artifactInfo) {
343 boolean needGenerate;
344 needGenerate = artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && (component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || component
345 .getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
346 needGenerate = needGenerate || (ComponentTypeEnum.RESOURCE == component.getComponentType() && (artifactInfo.getArtifactType()
347 .equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV
348 .getType()) || isAbstractVfcEmptyCsar((Resource) component, artifactInfo)));
352 private boolean isAbstractVfcEmptyCsar(Resource resource, ArtifactDefinition artifactInfo) {
353 return resource.isAbstract() && artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && artifactInfo
355 .equals(ArtifactTypeEnum.TOSCA_CSAR.getType()) && StringUtils.isEmpty(artifactInfo.getArtifactChecksum());
358 public Either<ArtifactDefinition, Operation> generateAndSaveToscaArtifact(
359 ArtifactDefinition artifactDefinition, Component component,
360 User user, boolean isInCertificationRequest, boolean shouldLock, boolean inTransaction,
361 boolean fetchTemplatesFromDB) {
363 return decodeToscaArtifactPayload(
364 component, isInCertificationRequest, fetchTemplatesFromDB, artifactDefinition.getArtifactType()
365 ).left().bind(payload -> {
366 // TODO: Avoid output argument
367 artifactDefinition.setPayload(payload);
368 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
369 artifactDefinition.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(payload));
370 return lockComponentAndUpdateArtifact(component.getUniqueId(), artifactDefinition,
371 AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, artifactDefinition.getUniqueId(),
372 user, component.getComponentType(), component, payload, shouldLock, inTransaction
374 }).right().map(ex -> {
375 // TODO: This should not be done but in order to keep this refactoring small enough, we stop here.
376 // Bubble up this exception
381 private Either<byte[], ComponentException> decodeToscaArtifactPayload(
383 boolean isInCertificationRequest,
384 boolean fetchTemplatesFromDB,
387 log.debug("tosca artifact generation");
388 if (ArtifactTypeEnum.TOSCA_CSAR.getType().equals(artifactType)) {
390 .createCsar(parent, fetchTemplatesFromDB, isInCertificationRequest)
391 .right().map(error -> {
392 log.debug("Failed to generate tosca csar for component {} error {}", parent.getUniqueId(), error);
393 return new ByResponseFormatComponentException(error);
396 return toscaExportUtils
397 .exportComponent(parent)
398 .left().map(toscaRepresentation -> {
399 log.debug("Tosca yaml exported for component {} ", parent.getUniqueId());
400 return toscaRepresentation.getMainYaml();
401 }).right().map(toscaError -> {
402 log.debug("Failed export tosca yaml for component {} error {}", parent.getUniqueId(), toscaError);
403 return new ByActionStatusComponentException(componentsUtils.convertFromToscaError(toscaError));
408 private Either<ArtifactDefinition, Operation> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId, ArtifactDefinition artifactInfo, String origMd5,
409 String originData, String interfaceName, String operationName, AuditingActionEnum auditingAction, User user, Component parent, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
410 if (interfaceName != null && operationName != null) {
411 interfaceName = interfaceName.toLowerCase();
412 operationName = operationName.toLowerCase();
415 lockComponent(componentType, artifactId, auditingAction, user, parent);
417 Either<ArtifactDefinition, Operation> result;
418 boolean operationSucceeded = false;
420 switch (operation.getArtifactOperationEnum()) {
422 if (artifactGenerationRequired(parent, artifactInfo)) {
423 result = Either.left(generateNotSavedArtifact(parent, artifactInfo));
425 result = Either.left(handleDownload(componentId, artifactId, componentType, parent));
429 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, parent));
432 result = handleUpdate(componentId, componentType, operation, artifactId, artifactInfo, null, origMd5, originData, interfaceName, operationName,
433 auditingAction, user, parent, needUpdateGroup);
436 result = handleCreate(componentId, artifactInfo, operation, auditingAction, user, componentType, parent, origMd5, originData, interfaceName,
440 result = Either.left(handleLink(componentId, artifactInfo, componentType, parent));
443 throw new UnsupportedOperationException("In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
445 operationSucceeded = true;
449 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
453 private void lockComponent(ComponentTypeEnum componentType, String artifactId, AuditingActionEnum auditingAction, User user, Component parent) {
455 lockComponent(parent, ARTIFACT_ACTION_LOCK);
456 }catch (ComponentException e){
457 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, null, null, artifactId, e.getResponseFormat(),
458 componentType, null);
464 public Either<ArtifactDefinition, Operation> handleUpdate(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId,
465 ArtifactDefinition artifactInfo, byte[] decodedPayload, String origMd5, String originData, String interfaceName,
466 String operationName, AuditingActionEnum auditingAction, User user, Component parent,
467 boolean needUpdateGroup) {
468 Either<ArtifactDefinition, Operation> result;
469 validateArtifactType(artifactInfo);
470 final String artifactType = artifactInfo.getArtifactType();
471 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE &&
472 (ArtifactTypeEnum.HEAT.getType().equals(artifactType) ||
473 ArtifactTypeEnum.HEAT_VOL.getType().equals(artifactType) ||
474 ArtifactTypeEnum.HEAT_NET.getType().equals(artifactType) ||
475 ArtifactTypeEnum.HEAT_ENV.getType().equals(artifactType))) {
476 result = handleUpdateHeatEnvAndHeatMeta(componentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, originData, origMd5, operation);
477 if (needUpdateGroup) {
478 ActionStatus error = updateGroupInstance(artifactInfo, result.left().value(), parent, componentId);
479 if (error != ActionStatus.OK) {
480 throw new ByActionStatusComponentException(error);
484 else if (componentType == ComponentTypeEnum.RESOURCE && ArtifactTypeEnum.HEAT_ENV.getType().equals(artifactType)) {
485 result = handleUpdateHeatWithHeatEnvParams(componentId, artifactInfo, auditingAction, componentType, parent, originData, origMd5, operation, needUpdateGroup);
488 if (decodedPayload == null) {
489 decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, artifactId, user,
490 componentType, parent, origMd5, originData, interfaceName, operationName);
492 result = updateArtifactFlow(parent, componentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction
494 if (needUpdateGroup && result.isLeft()) {
495 ArtifactDefinition updatedArtifact = result.left().value();
496 updateGroupForHeat(artifactInfo, updatedArtifact, parent);
502 private void validateArtifactType(final ArtifactDefinition artifactInfo) {
503 if (!isArtifactSupported(artifactInfo.getArtifactType())) {
504 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
508 private void validateArtifactType(final ArtifactDefinition artifactInfo,
509 final ComponentTypeEnum componentType) {
510 final ArtifactConfiguration artifactConfiguration =
511 loadArtifactTypeConfig(artifactInfo.getArtifactType()).orElse(null);
512 if (artifactConfiguration == null) {
513 BeEcompErrorManager.getInstance()
514 .logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
515 log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName());
516 final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE);
517 throw new ByResponseFormatComponentException(responseFormat);
520 final ArtifactGroupTypeEnum artifactGroupType = artifactInfo.getArtifactGroupType();
522 validateArtifactType(componentType, artifactGroupType, artifactConfiguration);
523 } catch (final ComponentException e) {
524 log.debug("Artifact is invalid", e);
525 BeEcompErrorManager.getInstance()
526 .logBeInvalidTypeError("Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo
527 .getArtifactType(), "Artifact " + artifactInfo.getArtifactName());
528 log.debug("Not supported artifact type = {}", artifactInfo.getArtifactType());
529 final ResponseFormat responseFormat = componentsUtils
530 .getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo
532 throw new ByResponseFormatComponentException(responseFormat);
536 private void validateArtifactType(final ComponentTypeEnum componentType, final ArtifactGroupTypeEnum groupType,
537 final ArtifactConfiguration artifactConfiguration) {
538 final boolean supportComponentType =
539 CollectionUtils.isNotEmpty(artifactConfiguration.getComponentTypes()) &&
540 artifactConfiguration.getComponentTypes().stream()
541 .anyMatch(componentType1 -> componentType1.getValue().equalsIgnoreCase(componentType.getValue()));
542 if (!supportComponentType) {
543 log.debug("Artifact Type '{}' not supported for Component Type '{}'",
544 artifactConfiguration.getType(), componentType.getValue());
545 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED,
546 artifactConfiguration.getType());
549 final boolean supportResourceType = artifactConfiguration.hasSupport(groupType);
550 if (!supportResourceType) {
551 log.debug("Artifact Type '{}' not supported for Component Type '{}' and Category '{}'",
552 artifactConfiguration.getType(), componentType.getValue(), groupType.getType());
553 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED,
554 artifactConfiguration.getType());
558 private boolean isArtifactSupported(final String artifactType) {
559 final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
560 final List<ArtifactConfiguration> artifactConfigurationList = configuration.getArtifacts();
561 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
564 return artifactConfigurationList.stream()
565 .anyMatch(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType));
569 public ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent) {
570 List<GroupDefinition> groups = parent.getGroups();
571 if (groups != null && !groups.isEmpty()) {
572 List<GroupDataDefinition> groupToUpdate = groups.stream()
573 .filter(g -> g.getArtifacts() != null && g.getArtifacts()
574 .contains(artifactInfo
576 .collect(Collectors.toList());
577 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
578 groupToUpdate.forEach(g -> {
579 g.getArtifacts().remove(artifactInfo.getUniqueId());
580 g.getArtifactsUuid().remove(artifactInfo.getArtifactUUID());
581 g.getArtifacts().add(artAfterUpdate.getUniqueId());
582 g.getArtifactsUuid().add(artAfterUpdate.getArtifactUUID());
583 if(!artifactInfo.getArtifactUUID().equals(artAfterUpdate.getArtifactUUID())){
584 g.setGroupUUID(UniqueIdBuilder.generateUUID());
587 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
588 if (status.isRight()) {
589 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
590 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status.right().value()));
594 return ActionStatus.OK;
598 ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfoHeat, ArtifactDefinition artHeatAfterUpdate, ArtifactDefinition artifactInfoHeatE, ArtifactDefinition artHEAfterUpdate, Component parent) {
599 List<GroupDefinition> groups = parent.getGroups();
600 if (groups != null && !groups.isEmpty()) {
601 List<GroupDataDefinition> groupToUpdate = groups.stream()
602 .filter(g -> g.getArtifacts() != null && g.getArtifacts()
603 .contains(artifactInfoHeat
605 .collect(Collectors.toList());
606 if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
607 groupToUpdate.forEach(g -> {
608 g.getArtifacts().remove(artifactInfoHeat.getUniqueId());
609 g.getArtifactsUuid().remove(artifactInfoHeat.getArtifactUUID());
610 g.getArtifacts().remove(artifactInfoHeatE.getUniqueId());
611 g.getArtifacts().add(artHeatAfterUpdate.getUniqueId());
612 g.getArtifactsUuid().add(artHeatAfterUpdate.getArtifactUUID());
613 g.getArtifacts().add(artHEAfterUpdate.getUniqueId());
615 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
616 if (status.isRight()) {
617 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
618 return componentsUtils.convertFromStorageResponse(status.right().value());
622 return ActionStatus.OK;
625 private ActionStatus updateGroupInstance(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent, String parentId) {
626 List<GroupInstance> updatedGroupInstances = new ArrayList<>();
627 List<GroupInstance> groupInstances = null;
628 Optional<ComponentInstance> componentInstOp = parent.getComponentInstances()
630 .filter(ci -> ci.getUniqueId().equals(parentId))
632 if (componentInstOp.isPresent()) {
633 groupInstances = componentInstOp.get().getGroupInstances();
635 if (CollectionUtils.isNotEmpty(groupInstances)) {
636 boolean isUpdated = false;
637 for (GroupInstance groupInstance : groupInstances) {
639 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifacts()) && groupInstance.getGroupInstanceArtifacts()
640 .contains(artifactInfo
642 groupInstance.getGroupInstanceArtifacts().remove(artifactInfo.getUniqueId());
643 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getUniqueId());
646 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifactsUuid()) && groupInstance.getGroupInstanceArtifactsUuid()
647 .contains(artifactInfo
648 .getArtifactUUID())) {
649 groupInstance.getGroupInstanceArtifactsUuid().remove(artifactInfo.getArtifactUUID());
650 groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getArtifactUUID());
654 updatedGroupInstances.add(groupInstance);
658 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade.updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
659 if (status.isRight()) {
660 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
661 return componentsUtils.convertFromStorageResponse(status.right().value());
663 return ActionStatus.OK;
666 ArtifactDefinition generateNotSavedArtifact(Component parent, ArtifactDefinition artifactDefinition) {
667 if (artifactDefinition.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA) {
668 Either<byte[], ComponentException> decodedPayload = decodeToscaArtifactPayload(parent, false,
669 false, artifactDefinition.getArtifactType());
670 // TODO: This should not be done, but in order to keep this refactoring relatively small, we stop here
671 if(decodedPayload.isRight())
672 throw decodedPayload.right().value();
674 artifactDefinition.setPayload(decodedPayload.left().value());
675 return artifactDefinition;
679 String heatArtifactId = artifactDefinition.getGeneratedFromId();
680 Either<ArtifactDefinition, StorageOperationStatus> heatRes = artifactToscaOperation.getArtifactById(parent.getUniqueId(), heatArtifactId);
681 if (heatRes.isRight()) {
682 log.debug("Failed to fetch heat artifact by generated id {} for heat env {}", heatArtifactId, artifactDefinition.getUniqueId());
683 throw new StorageException(heatRes.right().value());
685 String generatedPayload = generateHeatEnvPayload(heatRes.left().value());
686 artifactDefinition.setPayloadData(generatedPayload);
687 return artifactDefinition;
691 private Either<ArtifactDefinition, Operation> handleUpdateHeatWithHeatEnvParams(String componentId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction,
692 ComponentTypeEnum componentType, Component parent, String originData, String origMd5, ArtifactOperationInfo operation,
693 boolean needToUpdateGroup) {
694 Either<ArtifactDefinition, StorageOperationStatus> artifactHeatRes = artifactToscaOperation.getArtifactById(componentId, artifactInfo
695 .getGeneratedFromId());
696 ArtifactDefinition currHeatArtifact = artifactHeatRes.left().value();
697 if (origMd5 != null) {
698 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
699 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
700 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
701 } else { // duplicate
702 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
705 return updateHeatParams(componentId, artifactInfo, auditingAction, parent, componentType, currHeatArtifact, needToUpdateGroup);
708 private void handleLockingAndCommit(Component parent, boolean shouldLock, boolean inTransaction, boolean actionSucceeded) {
709 if (actionSucceeded) {
711 if (!inTransaction) {
712 janusGraphDao.commit();
716 if (!inTransaction) {
717 janusGraphDao.rollback();
721 graphLockOperation.unlockComponent(parent.getUniqueId(), parent.getComponentType().getNodeType());
725 public ImmutablePair<String, byte[]> handleDownloadToscaModelRequest(Component component, ArtifactDefinition csarArtifact) {
726 if (artifactGenerationRequired(component, csarArtifact)) {
727 Either<byte[], ResponseFormat> generated = csarUtils.createCsar(component, false, false);
729 if (generated.isRight()) {
730 log.debug("Failed to export tosca csar for component {} error {}", component.getUniqueId(), generated.right()
732 throw new ByResponseFormatComponentException(generated.right().value());
734 return new ImmutablePair<>(csarArtifact.getArtifactName(), generated.left().value());
736 return downloadArtifact(csarArtifact);
739 public ImmutablePair<String, byte[]> handleDownloadRequestById(String componentId, String artifactId, String userId, ComponentTypeEnum componentType, String parentId, String containerComponentType) {
740 // perform all validation in common flow
741 Either<ArtifactDefinition, Operation> result = handleArtifactRequest(componentId, userId, componentType, new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DOWNLOAD), artifactId, null, null, null, null,
742 null, parentId, containerComponentType);
743 ArtifactDefinition artifactDefinition;
744 Either<ArtifactDefinition, Operation> insideValue = result;
745 if (insideValue.isLeft()) {
746 artifactDefinition = insideValue.left().value();
749 artifactDefinition = insideValue.right().value().getImplementationArtifact();
751 // for tosca artifacts and heat env on VF level generated on download without saving
752 if (artifactDefinition.getPayloadData() != null) {
753 return (new ImmutablePair<>(artifactDefinition.getArtifactName(), artifactDefinition
756 return downloadArtifact(artifactDefinition);
759 public Map<String, ArtifactDefinition> handleGetArtifactsByType(String containerComponentType, String parentId, ComponentTypeEnum componentType, String componentId, String artifactGroupType, String userId) {
761 // detect auditing type
762 Map<String, ArtifactDefinition> resMap = null;
767 if (userId == null) {
768 log.debug("handleGetArtifactsByType - no HTTP_CSP_HEADER , component id {}", componentId);
769 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
772 // check user existence
776 validateUserExists(userId);
778 // 5. check service/resource existence
779 // 6. check service/resource check out
780 // 7. user is owner of checkout state
781 String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
782 ComponentParametersView componentFilter = new ComponentParametersView();
783 componentFilter.disableAll();
784 componentFilter.setIgnoreArtifacts(false);
785 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
786 componentFilter.setIgnoreComponentInstances(false);
789 Component component = validateComponentExistsByFilter(realComponentId, ComponentTypeEnum
790 .findByParamName(containerComponentType), componentFilter);
791 lockComponent(component, ARTIFACT_ACTION_LOCK);
792 boolean failed = false;
794 ArtifactGroupTypeEnum groupType = ArtifactGroupTypeEnum.findType(artifactGroupType);
796 if (groupType == null) {
797 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
798 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
800 if (parentId == null && groupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
801 List<ArtifactDefinition> list = getDeploymentArtifacts(component, componentId);
802 if (list != null && !list.isEmpty()) {
803 resMap = list.stream().collect(Collectors.toMap(ArtifactDataDefinition::getArtifactLabel, Function.identity()));
806 resMap = new HashMap<>();
811 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsMapStatus = getArtifacts(realComponentId, componentType
812 .getNodeType(), groupType, componentId);
813 if (artifactsMapStatus.isRight()) {
814 if (artifactsMapStatus.right().value() != StorageOperationStatus.NOT_FOUND) {
815 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
816 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
819 resMap = new HashMap<>();
823 resMap = artifactsMapStatus.left().value();
827 }catch (ComponentException e){
834 janusGraphDao.rollback();
838 janusGraphDao.commit();
841 componentType = component.getComponentType();
842 NodeTypeEnum nodeType = componentType.getNodeType();
843 graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
848 private ArtifactDefinition getArtifactIfBelongsToComponent(String componentId, ComponentTypeEnum componentType, String artifactId, Component component) {
849 // check artifact existence
850 Either<ArtifactDefinition, StorageOperationStatus> artifactResult = artifactToscaOperation.getArtifactById(componentId, artifactId,
851 componentType, component.getUniqueId());
852 if (artifactResult.isRight()) {
853 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentId);
855 // verify artifact belongs to component
857 switch (componentType) {
860 found = ComponentUtils.checkArtifactInComponent(component, artifactId);
862 case RESOURCE_INSTANCE:
863 found = ComponentUtils.checkArtifactInResourceInstance(component, componentId, artifactId);
869 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentType.name().toLowerCase());
871 return artifactResult.left().value();
874 private Either<ArtifactDefinition, Operation> handleCreate(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation, AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType,
875 Component parent, String origMd5, String originData, String interfaceType, String operationName) {
876 byte[] decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, null, user, componentType, parent, origMd5, originData, interfaceType, operationName);
877 return createArtifact(parent, componentId, artifactInfo, decodedPayload, componentType, auditingAction, interfaceType, operationName);
880 private ArtifactDefinition handleLink(String componentId, ArtifactDefinition artifactInfo, ComponentTypeEnum componentType,
882 ComponentInstance foundInstance = findComponentInstance(componentId, parent);
883 String instanceId = null;
884 if (foundInstance != null) {
885 instanceId = foundInstance.getUniqueId();
887 NodeTypeEnum nodeType = convertParentType(componentType);
888 Either<ArtifactDefinition, StorageOperationStatus> artifactDefinitionEither = artifactToscaOperation.addArtifactToComponent(artifactInfo, parent,
889 nodeType, true, instanceId);
890 if (artifactDefinitionEither.isRight()) {
891 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
893 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), componentId, componentType) != StorageOperationStatus.OK) {
894 throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
896 return artifactDefinitionEither.left().value();
899 private <T> Either<ArtifactDefinition, T> lockComponentAndUpdateArtifact(
900 String parentId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, String artifactId,
901 User user, ComponentTypeEnum componentType, Component parent, byte[] decodedPayload,
902 boolean shouldLock, boolean inTransaction) {
904 boolean failed = false;
905 boolean writeAudit = true;
907 lockComponent(parent, shouldLock, ARTIFACT_ACTION_LOCK);
909 return updateArtifactFlow(parent, parentId, artifactId, artifactInfo, decodedPayload, componentType,
912 catch (ComponentException ce) {
914 handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, ce.getResponseFormat(),
915 componentType, null);
920 catch (StorageException se) {
927 unlockComponent(failed, parent, inTransaction);
932 private byte[] validateInput(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation, AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType,
933 Component parent, String origMd5, String originData, String interfaceType, String operationName) {
934 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
935 return getValidPayload(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, interfaceType, operationName);
938 private byte[] getValidPayload(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation, AuditingActionEnum auditingAction,
939 String artifactId, User user, ComponentTypeEnum componentType, Component parent, String interfaceType, String operationName) {
941 Either<ArtifactDefinition, ResponseFormat> validateResult = validateInput(componentId, artifactInfo, operation, artifactId, user, interfaceType, operationName, componentType, parent);
942 if (validateResult.isRight()) {
943 ResponseFormat responseFormat = validateResult.right().value();
944 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
945 throw new ByResponseFormatComponentException(responseFormat);
948 Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
949 if (payloadEither.isRight()) {
950 ResponseFormat responseFormat = payloadEither.right().value();
951 handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
952 log.debug("Error during handle payload");
953 throw new ByResponseFormatComponentException(responseFormat);
955 // validate heat parameters. this part must be after the parameters are
956 // extracted in "handlePayload"
957 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters = validateAndConvertHeatParameters(artifactInfo, artifactInfo
959 if (validateAndConvertHeatParameters.isRight()) {
960 ResponseFormat responseFormat = validateAndConvertHeatParameters.right().value();
961 handleAuditing(auditingAction, parent, componentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null);
962 log.debug("Error during handle payload");
963 throw new ByResponseFormatComponentException(responseFormat);
965 return payloadEither.left().value();
968 public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
969 ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
970 ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
972 if (componentsUtils.isExternalApiEvent(auditingActionEnum)) {
978 user.setUserId("UNKNOWN");
980 handleInternalAuditEvent(auditingActionEnum, component, componentId, user, artifactDefinition, prevArtifactUuid, currentArtifactUuid, responseFormat, componentTypeEnum, resourceInstanceName);
983 private void handleInternalAuditEvent(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user, ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid, ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
984 switch (componentTypeEnum) {
986 Resource resource = (Resource) component;
987 if (resource == null) {
988 // In that case, component ID should be instead of name
989 resource = new Resource();
990 resource.setName(componentId);
992 componentsUtils.auditResource(responseFormat, user, resource, resource.getName(), auditingActionEnum,
993 ResourceVersionInfo.newBuilder()
994 .artifactUuid(prevArtifactUuid)
995 .build(), currentArtifactUuid, artifactDefinition);
999 Service service = (Service) component;
1000 if (service == null) {
1001 // In that case, component ID should be instead of name
1002 service = new Service();
1003 service.setName(componentId);
1005 componentsUtils.auditComponent(responseFormat, user, service, auditingActionEnum, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1006 ResourceVersionInfo.newBuilder()
1007 .artifactUuid(prevArtifactUuid)
1009 ResourceVersionInfo.newBuilder()
1010 .artifactUuid(currentArtifactUuid)
1012 null, artifactDefinition, null);
1015 case RESOURCE_INSTANCE:
1016 if (resourceInstanceName == null) {
1017 resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId);
1019 componentsUtils.auditComponent(responseFormat, user, component, auditingActionEnum,
1020 new ResourceCommonInfo(resourceInstanceName, ComponentTypeEnum.RESOURCE_INSTANCE.getValue()),
1021 ResourceVersionInfo.newBuilder()
1022 .artifactUuid(prevArtifactUuid)
1024 ResourceVersionInfo.newBuilder()
1025 .artifactUuid(currentArtifactUuid)
1027 null, artifactDefinition, null);
1034 private String getResourceInstanceNameFromComponent(Component component, String componentId) {
1035 ComponentInstance resourceInstance = component.getComponentInstances()
1037 .filter(p -> p.getUniqueId().equals(componentId))
1040 String resourceInstanceName = null;
1041 if (resourceInstance != null) {
1042 resourceInstanceName = resourceInstance.getName();
1044 return resourceInstanceName;
1047 private void validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperationInfo operation) {
1048 if (origMd5 == null) {
1049 if (operation.isCreateOrLink() && ArrayUtils.isNotEmpty(payload)) {
1050 log.debug("Missing md5 header during artifact create");
1051 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1054 if (ArrayUtils.isNotEmpty(payload)) {
1055 log.debug("Cannot have payload while md5 header is missing");
1056 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
1059 String encodeBase64Str = GeneralUtility.calculateMD5Base64EncodedByString(originData);
1060 if (!encodeBase64Str.equals(origMd5)) {
1061 log.debug("The calculated md5 is different then the received one");
1062 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1067 private Either<ArtifactDefinition, ResponseFormat> validateInput(final String componentId,
1068 final ArtifactDefinition artifactInfo,
1069 final ArtifactOperationInfo operation,
1070 final String artifactId, final User user,
1071 String interfaceName,
1072 String operationName,
1073 final ComponentTypeEnum componentType,
1074 final Component parentComponent) {
1076 final ArtifactDefinition existingArtifactInfo =
1077 findArtifact(parentComponent, componentType, componentId, operation, artifactId);
1078 final boolean isCreateOrLinkOperation =
1079 ArtifactOperationEnum.isCreateOrLink(operation.getArtifactOperationEnum());
1080 if (!isCreateOrLinkOperation && existingArtifactInfo == null) {
1081 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1083 final Component component;
1084 if (parentComponent.getUniqueId().equals(componentId)) {
1085 component = parentComponent;
1087 final ComponentInstance componentInstance = findComponentInstance(componentId, parentComponent);
1088 component = findComponent(componentInstance.getComponentUid());
1089 component.setComponentType(componentType);
1091 if (!isCreateOrLinkOperation) {
1092 ignoreUnupdateableFieldsInUpdate(operation, artifactInfo, existingArtifactInfo);
1094 if (isInformationalArtifact(artifactInfo)) {
1095 validateInformationalArtifact(artifactInfo, component);
1097 Either<Boolean, ResponseFormat> validateAndSetArtifactname = validateAndSetArtifactName(artifactInfo);
1098 if (validateAndSetArtifactname.isRight()) {
1099 return Either.right(validateAndSetArtifactname.right().value());
1101 if (!validateArtifactNameUniqueness(componentId, parentComponent, artifactInfo, componentType)) {
1102 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST));
1104 if (operationName != null && interfaceName != null) {
1105 operationName = operationName.toLowerCase();
1106 interfaceName = interfaceName.toLowerCase();
1108 Either<ActionStatus, ResponseFormat> logicalNameStatus = handleArtifactLabel(componentId, parentComponent, operation, artifactInfo, operationName, componentType);
1109 if (logicalNameStatus.isRight()) {
1110 return Either.right(logicalNameStatus.right().value());
1112 // This is a patch to block possibility of updating service api fields
1113 // through other artifacts flow
1115 final ArtifactGroupTypeEnum artifactGroupType =
1116 operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL;
1117 if (operation.isNotCreateOrLink()) {
1118 checkAndSetUnUpdatableFields(user, artifactInfo, existingArtifactInfo, artifactGroupType);
1120 checkCreateFields(user, artifactInfo, artifactGroupType);
1123 composeArtifactId(componentId, artifactId, artifactInfo, interfaceName, operationName);
1124 if (existingArtifactInfo != null) {
1125 artifactInfo.setMandatory(existingArtifactInfo.getMandatory());
1126 if (operation.isNotCreateOrLink()) {
1127 validateArtifactTypeNotChanged(artifactInfo, existingArtifactInfo);
1131 // artifactGroupType is not allowed to be updated
1132 if (operation.isNotCreateOrLink()) {
1133 Either<ArtifactDefinition, ResponseFormat> validateGroupType = validateOrSetArtifactGroupType(artifactInfo, existingArtifactInfo);
1134 if (validateGroupType.isRight()) {
1135 return Either.right(validateGroupType.right().value());
1139 setArtifactTimeout(artifactInfo, existingArtifactInfo);
1140 if (isHeatArtifact(artifactInfo)) {
1141 validateHeatArtifact(parentComponent, componentId, artifactInfo);
1143 if (isDeploymentArtifact(artifactInfo)) {
1144 if (componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1145 final String artifactName = artifactInfo.getArtifactName();
1146 final String existingArtifactName =
1147 (existingArtifactInfo == null) ? null : existingArtifactInfo.getArtifactName();
1149 if (operation.isCreateOrLink()
1150 || ((artifactName != null) && !artifactName.equalsIgnoreCase(existingArtifactName))) {
1151 validateSingleDeploymentArtifactName(artifactName, parentComponent);
1154 validateDeploymentArtifact(artifactInfo, component);
1157 Either<Boolean, ResponseFormat> descriptionResult = validateAndCleanDescription(artifactInfo);
1158 if (descriptionResult.isRight()) {
1159 return Either.right(descriptionResult.right().value());
1162 validateArtifactType(artifactInfo, component.getComponentType());
1163 artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase());
1164 if (existingArtifactInfo != null && existingArtifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.SERVICE_API) {
1165 // Change of type is not allowed and should be ignored
1167 artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER);
1169 Either<Boolean, ResponseFormat> validateUrl = validateAndServiceApiUrl(artifactInfo);
1170 if (validateUrl.isRight()) {
1171 return Either.right(validateUrl.right().value());
1174 Either<Boolean, ResponseFormat> validateUpdate = validateFirstUpdateHasPayload(artifactInfo, existingArtifactInfo);
1175 if (validateUpdate.isRight()) {
1176 log.debug("serviceApi first update cnnot be without payload.");
1177 return Either.right(validateUpdate.right().value());
1180 if (artifactInfo.getApiUrl() != null) {
1181 artifactInfo.setApiUrl(null);
1182 log.error("Artifact URL cannot be set through this API - ignoring");
1185 if (Boolean.TRUE.equals(artifactInfo.getServiceApi())) {
1186 artifactInfo.setServiceApi(false);
1187 log.error("Artifact service API flag cannot be changed - ignoring");
1191 return Either.left(artifactInfo);
1194 private Component findComponent(final String componentId) {
1195 Either<? extends Component, StorageOperationStatus> component = toscaOperationFacade.getToscaFullElement(componentId);
1196 if (component.isRight()) {
1197 log.debug("Component '{}' not found ", componentId);
1198 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentId);
1201 return component.left().value();
1204 private void ignoreUnupdateableFieldsInUpdate(final ArtifactOperationInfo operation,
1205 final ArtifactDefinition artifactInfo,
1206 final ArtifactDefinition currentArtifactInfo) {
1207 if (operation.isUpdate()) {
1208 artifactInfo.setArtifactType(currentArtifactInfo.getArtifactType());
1209 artifactInfo.setArtifactGroupType(currentArtifactInfo.getArtifactGroupType());
1210 artifactInfo.setArtifactLabel(currentArtifactInfo.getArtifactLabel());
1214 private ArtifactDefinition findArtifact(final Component parentComponent, final ComponentTypeEnum componentType,
1215 final String parentId, final ArtifactOperationInfo operation,
1216 final String artifactId) {
1217 ArtifactDefinition foundArtifact = null;
1218 if (StringUtils.isNotEmpty(artifactId)) {
1219 foundArtifact = findArtifact(parentComponent, componentType, parentId, artifactId);
1221 if (foundArtifact != null && operation.isCreateOrLink()) {
1222 log.debug("Artifact {} already exist", artifactId);
1223 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, foundArtifact.getArtifactLabel());
1225 if (foundArtifact == null && operation.isNotCreateOrLink()) {
1226 log.debug("The artifact {} was not found on parent component or instance {}. ", artifactId, parentId);
1227 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, "");
1229 return foundArtifact;
1232 private ArtifactDefinition findArtifact(Component parentComponent, ComponentTypeEnum componentType, String parentId, String artifactId) {
1233 ArtifactDefinition foundArtifact;
1234 if (parentComponent.getUniqueId().equals(parentId)) {
1235 foundArtifact = artifactsResolver.findArtifactOnComponent(parentComponent, componentType, artifactId);
1238 ComponentInstance instance = findComponentInstance(parentId, parentComponent);
1239 foundArtifact = artifactsResolver.findArtifactOnComponentInstance(instance, artifactId);
1241 return foundArtifact;
1244 private void validateInformationalArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1245 final ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
1246 if (groupType != ArtifactGroupTypeEnum.INFORMATIONAL) {
1249 final ComponentTypeEnum parentComponentType = component.getComponentType();
1250 final String artifactType = artifactInfo.getArtifactType();
1251 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1252 if (artifactConfiguration == null) {
1253 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1255 validateArtifactType(parentComponentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1257 if (component.getComponentType() == ComponentTypeEnum.RESOURCE ||
1258 component.getComponentType() == ComponentTypeEnum.RESOURCE_INSTANCE) {
1260 final ResourceTypeEnum resourceType = ((Resource) component).getResourceType();
1261 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1263 validateArtifactExtension(artifactConfiguration, artifactInfo);
1266 private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) {
1267 if (componentType == ComponentTypeEnum.RESOURCE) {
1268 return NodeTypeEnum.Resource;
1270 else if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1271 return NodeTypeEnum.ResourceInstance;
1274 return NodeTypeEnum.Service;
1278 // This method is here for backward compatibility - when other parts of the code are cleaned can change to use the internal version
1279 public Either<ArtifactDefinition, ResponseFormat> handleDelete(
1280 String parentId, String artifactId, User user, Component parent,
1281 boolean shouldLock, boolean inTransaction) {
1283 ResponseFormat responseFormat;
1284 boolean operationSucceeded = false;
1286 lockComponent(ComponentTypeEnum.RESOURCE, artifactId, AuditingActionEnum.ARTIFACT_DELETE, user, parent);
1289 ArtifactDefinition artifactDefinition = handleDeleteInternal(parentId, artifactId,
1290 ComponentTypeEnum.RESOURCE, parent);
1291 operationSucceeded = true;
1292 return Either.left(artifactDefinition);
1294 catch (ComponentException ce) {
1295 responseFormat = componentsUtils.getResponseFormat(ce);
1296 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null,
1297 artifactId, responseFormat, ComponentTypeEnum.RESOURCE, null);
1298 return Either.right(responseFormat);
1300 catch (StorageException se) {
1301 responseFormat = componentsUtils.getResponseFormat(se);
1302 handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null,
1303 artifactId, responseFormat, ComponentTypeEnum.RESOURCE, null);
1304 return Either.right(responseFormat);
1306 handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
1310 private ArtifactDefinition handleDeleteInternal(
1311 String parentId, String artifactId,
1312 ComponentTypeEnum componentType, Component parent
1314 NodeTypeEnum parentType = convertParentType(componentType);
1315 log.debug("Going to find the artifact {} on the component {}", artifactId, parent.getUniqueId());
1317 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> getArtifactRes =
1318 findArtifact(artifactId, parent, parentId, componentType);
1319 if (getArtifactRes.isRight()) {
1320 log.debug("Failed to find the artifact {} belonging to {} on the component {}",
1321 artifactId, parentId, parent.getUniqueId());
1322 throw new ByActionStatusComponentException(getArtifactRes.right().value(), artifactId);
1324 ArtifactDefinition foundArtifact = getArtifactRes.left().value().getLeft();
1325 ComponentInstance foundInstance = getArtifactRes.left().value().getRight();
1327 String esId = foundArtifact.getEsId();
1328 Either<Boolean, StorageOperationStatus> needClone = ifTrue(StringUtils.isNotEmpty(esId), () -> forEach(
1329 artifactToscaOperation.isCloneNeeded(parent.getUniqueId(), foundArtifact, parentType),
1330 b -> log.debug("handleDelete: clone is needed for deleting {} held by {} in component {} {}? {}",
1331 foundArtifact.getArtifactName(), parentType, parent.getUniqueId(), parent.getName(), b)
1334 boolean needToClone = false;
1335 // TODO: This should not be done, but in order to keep this refactoring small, we stop here.
1336 // Remove this block once the above refactoring is merged.
1337 if(needClone.isLeft()) {
1338 needToClone = needClone.left().value();
1340 throw new StorageException(needClone.right().value(), foundArtifact.getArtifactDisplayName());
1343 boolean isNeedToDeleteArtifactFromDB =
1344 componentType == ComponentTypeEnum.RESOURCE_INSTANCE &&
1345 isArtifactOnlyResourceInstanceArtifact(foundArtifact, parent, parentId);
1347 boolean isDuplicated = false;
1349 ArtifactDataDefinition updatedArtifact = deleteOrUpdateArtifactOnGraph(parent, parentId, artifactId, parentType, foundArtifact, needToClone);
1350 isDuplicated = updatedArtifact.getDuplicated();
1352 if (!needToClone && !isDuplicated && isNeedToDeleteArtifactFromDB) {
1353 log.debug("Going to delete the artifact {} from the database. ", artifactId);
1354 CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(esId);
1355 if (cassandraStatus != CassandraOperationStatus.OK) {
1356 log.debug("Failed to delete the artifact {} from the database. ", artifactId);
1357 throw new StorageException(convertToStorageOperationStatus(cassandraStatus), foundArtifact.getArtifactDisplayName());
1360 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1361 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(artifactId, foundArtifact, foundInstance.getGroupInstances());
1362 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
1363 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade.updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
1364 if (status.isRight()) {
1365 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1366 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1369 StorageOperationStatus status = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
1370 if (status != StorageOperationStatus.OK) {
1371 log.debug("Failed to generate new customization UUID for the component instance {}. ", parentId);
1372 throw new StorageException(status, foundArtifact.getArtifactDisplayName());
1375 List<GroupDataDefinition> updatedGroups = getUpdatedGroups(artifactId, foundArtifact, parent.getGroups());
1376 if (CollectionUtils.isNotEmpty(updatedGroups)) {
1377 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, updatedGroups);
1378 if (status.isRight()) {
1379 log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1380 throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1384 return foundArtifact;
1387 public static <R> Either<Boolean, R> ifTrue(boolean predicate, Supplier<Either<Boolean, R>> ifTrue) {
1388 return predicate ? ifTrue.get() : Either.left(false);
1391 public static <L, R> Either<L, R> forEach(Either<L, R> e, Consumer<L> c) {
1392 return e.left().map(l -> {
1398 private boolean isArtifactOnlyResourceInstanceArtifact(ArtifactDefinition foundArtifact, Component parent, String instanceId) {
1399 Optional<ComponentInstance> componentInstanceOpt = parent.getComponentInstanceById(instanceId);
1400 if (!componentInstanceOpt.isPresent()) {
1401 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "", "", parent.getName());
1403 ComponentInstance foundInstance = componentInstanceOpt.get();
1404 String componentUid = foundInstance.getComponentUid();
1405 Either<Component, StorageOperationStatus> getContainerRes = toscaOperationFacade.getToscaElement(componentUid);
1406 if (getContainerRes.isRight()) {
1407 log.debug("Failed to fetch the container component {}. ", componentUid);
1408 throw new StorageException(getContainerRes.right().value());
1410 Component origComponent = getContainerRes.left().value();
1411 Map<String, ArtifactDefinition> deploymentArtifacts = origComponent.getDeploymentArtifacts();
1412 if (MapUtils.isNotEmpty(deploymentArtifacts)) {
1413 Optional<String> op = deploymentArtifacts.keySet()
1415 .filter(a -> a.equals(foundArtifact.getArtifactLabel()))
1417 if (op.isPresent()) {
1421 Map<String, ArtifactDefinition> artifacts = origComponent.getArtifacts();
1422 if (MapUtils.isNotEmpty(artifacts)) {
1423 Optional<String> op = artifacts.keySet()
1425 .filter(a -> a.equals(foundArtifact.getArtifactLabel()))
1427 if (op.isPresent()) {
1434 private List<GroupDataDefinition> getUpdatedGroups(String artifactId, ArtifactDefinition foundArtifact, List<GroupDefinition> groups) {
1435 List<GroupDataDefinition> updatedGroups = new ArrayList<>();
1436 boolean isUpdated = false;
1437 if (groups != null) {
1438 for (GroupDefinition group : groups) {
1440 if (CollectionUtils.isNotEmpty(group.getArtifacts()) && group.getArtifacts().contains(artifactId)) {
1441 group.getArtifacts().remove(artifactId);
1444 if (CollectionUtils.isNotEmpty(group.getArtifactsUuid()) && group.getArtifactsUuid()
1445 .contains(foundArtifact.getArtifactUUID())) {
1446 group.getArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1450 updatedGroups.add(group);
1454 return updatedGroups;
1457 private List<GroupInstance> getUpdatedGroupInstances(
1458 String artifactId, ArtifactDefinition foundArtifact, List<GroupInstance> groupInstances
1460 if (CollectionUtils.isEmpty(groupInstances)) {
1461 return new ArrayList<>();
1463 // TODO: A defensive copy should be created here for groupInstances. Modifying
1464 // arguments (aka output arguments) is overall a bad practice as explained in
1465 // Clean Code by Robert Martin.
1466 // A better approach would be to use Lenses.
1468 return groupInstances.stream().filter(gi -> {
1469 boolean groupInstanceArtifactRemoved = gi.getGroupInstanceArtifacts() != null &&
1470 gi.getGroupInstanceArtifacts().remove(artifactId);
1471 boolean groupInstanceArtifactUUIDRemoved = gi.getGroupInstanceArtifactsUuid() != null &&
1472 gi.getGroupInstanceArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1474 return groupInstanceArtifactRemoved || groupInstanceArtifactUUIDRemoved;
1475 }).collect(Collectors.toList());
1478 private ArtifactDataDefinition deleteOrUpdateArtifactOnGraph(Component component, String parentId, String artifactId, NodeTypeEnum parentType, ArtifactDefinition foundArtifact, Boolean cloneIsNeeded) {
1480 Either<ArtifactDataDefinition, StorageOperationStatus> result;
1481 boolean isMandatory = foundArtifact.getMandatory() || foundArtifact.getServiceApi();
1482 String componentId = component.getUniqueId();
1483 String instanceId = componentId.equals(parentId) ? null : parentId;
1485 log.debug("Going to update mandatory artifact {} from the component {}", artifactId, parentId);
1486 resetMandatoryArtifactFields(foundArtifact);
1487 result = artifactToscaOperation.updateArtifactOnGraph(component, foundArtifact, parentType, artifactId, instanceId, true, true);
1489 else if (cloneIsNeeded) {
1490 log.debug("Going to clone artifacts and to delete the artifact {} from the component {}", artifactId, parentId);
1491 result = artifactToscaOperation.deleteArtifactWithCloningOnGraph(componentId, foundArtifact, parentType, instanceId, false);
1494 log.debug("Going to delete the artifact {} from the component {}", artifactId, parentId);
1495 result = artifactToscaOperation.removeArtifactOnGraph(foundArtifact, componentId, instanceId, parentType, false);
1497 if (result.isRight()) {
1498 throw new StorageException(result.right().value(), foundArtifact.getArtifactDisplayName());
1500 return result.left().value();
1503 private Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> findArtifact(String artifactId, Component fetchedContainerComponent, String parentId, ComponentTypeEnum componentType) {
1505 Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> result = null;
1506 Map<String, ArtifactDefinition> artifacts = new HashMap<>();
1507 ComponentInstance foundInstance = null;
1508 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && StringUtils.isNotEmpty(parentId)) {
1509 Optional<ComponentInstance> componentInstanceOpt = fetchedContainerComponent.getComponentInstances()
1511 .filter(i -> i.getUniqueId()
1514 if (!componentInstanceOpt.isPresent()) {
1515 result = Either.right(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER);
1518 foundInstance = componentInstanceOpt.get();
1519 fetchArtifactsFromInstance(artifactId, artifacts, foundInstance);
1523 fetchArtifactsFromComponent(artifactId, fetchedContainerComponent, artifacts);
1525 if (result == null) {
1526 if (artifacts.containsKey(artifactId)) {
1527 result = Either.left(new ImmutablePair<>(artifacts.get(artifactId), foundInstance));
1530 result = Either.right(ActionStatus.ARTIFACT_NOT_FOUND);
1536 private void fetchArtifactsFromComponent(String artifactId, Component component, Map<String, ArtifactDefinition> artifacts) {
1537 Map<String, ArtifactDefinition> currArtifacts;
1538 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
1539 currArtifacts = component.getDeploymentArtifacts()
1542 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, i -> i));
1543 if (MapUtils.isNotEmpty(currArtifacts)) {
1544 artifacts.putAll(currArtifacts);
1547 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1548 currArtifacts = component.getArtifacts()
1551 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1552 if (MapUtils.isNotEmpty(currArtifacts)) {
1553 artifacts.putAll(currArtifacts);
1556 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1557 currArtifacts = component.getToscaArtifacts()
1560 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1561 if (MapUtils.isNotEmpty(currArtifacts)) {
1562 artifacts.putAll(currArtifacts);
1567 private void fetchArtifactsFromInstance(String artifactId, Map<String, ArtifactDefinition> artifacts, ComponentInstance instance) {
1568 Map<String, ArtifactDefinition> currArtifacts;
1569 if (MapUtils.isNotEmpty(instance.getDeploymentArtifacts())) {
1570 currArtifacts = instance.getDeploymentArtifacts()
1573 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1574 if (MapUtils.isNotEmpty(currArtifacts)) {
1575 artifacts.putAll(currArtifacts);
1578 if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(instance.getArtifacts())) {
1579 currArtifacts = instance.getArtifacts()
1582 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1583 if (MapUtils.isNotEmpty(currArtifacts)) {
1584 artifacts.putAll(currArtifacts);
1589 private StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) {
1590 StorageOperationStatus result;
1591 switch (cassandraStatus) {
1593 result = StorageOperationStatus.OK;
1596 result = StorageOperationStatus.NOT_FOUND;
1598 case CLUSTER_NOT_CONNECTED:
1599 case KEYSPACE_NOT_CONNECTED:
1600 result = StorageOperationStatus.CONNECTION_FAILURE;
1603 result = StorageOperationStatus.GENERAL_ERROR;
1609 private void resetMandatoryArtifactFields(ArtifactDefinition fetchedArtifact) {
1610 if (fetchedArtifact != null) {
1611 log.debug("Going to reset mandatory artifact {} fields. ", fetchedArtifact.getUniqueId());
1612 fetchedArtifact.setEsId(null);
1613 fetchedArtifact.setArtifactName(null);
1614 fetchedArtifact.setDescription(null);
1615 fetchedArtifact.setApiUrl(null);
1616 fetchedArtifact.setArtifactChecksum(null);
1617 nodeTemplateOperation.setDefaultArtifactTimeout(fetchedArtifact.getArtifactGroupType(), fetchedArtifact);
1618 fetchedArtifact.setArtifactUUID(null);
1619 long time = System.currentTimeMillis();
1620 fetchedArtifact.setPayloadUpdateDate(time);
1621 fetchedArtifact.setHeatParameters(null);
1622 fetchedArtifact.setHeatParamsUpdateDate(null);
1626 private StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId, ComponentTypeEnum componentType) {
1627 StorageOperationStatus error = StorageOperationStatus.OK;
1628 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1629 log.debug("Need to re-generate customization UUID for instance {}", instanceId);
1630 error = toscaOperationFacade.generateCustomizationUUIDOnInstance(componentId, instanceId);
1635 private ArtifactDefinition handleDownload(String componentId, String artifactId, ComponentTypeEnum componentType,
1637 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(componentId, artifactId, componentType,
1638 parent.getUniqueId());
1639 if (artifactById.isRight()) {
1640 throw new StorageException(artifactById.right().value());
1642 ArtifactDefinition artifactDefinition = artifactById.left().value();
1643 if (artifactDefinition == null) {
1644 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1646 return artifactDefinition;
1649 private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String componentId, Component parentComponent, ArtifactOperationInfo operation, ArtifactDefinition artifactInfo, String operationName,
1650 ComponentTypeEnum componentType) {
1652 String artifactLabel = artifactInfo.getArtifactLabel();
1653 if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel()
1655 BeEcompErrorManager.getInstance()
1656 .logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
1657 log.debug("missing artifact logical name for component {}", componentId);
1658 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1660 if (operation.isCreateOrLink() && !artifactInfo.getMandatory()) {
1662 if (operationName != null) {
1663 if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) {
1664 log.debug("artifact label cannot be set {}", artifactLabel);
1665 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED));
1668 artifactLabel = operationName;
1671 String displayName = artifactInfo.getArtifactDisplayName();
1672 if (displayName == null || displayName.isEmpty()) {
1673 displayName = artifactLabel;
1675 displayName = ValidationUtils.cleanArtifactDisplayName(displayName);
1676 artifactInfo.setArtifactDisplayName(displayName);
1678 if (!ValidationUtils.validateArtifactLabel(artifactLabel)) {
1679 log.debug("Invalid format form Artifact label : {}", artifactLabel);
1680 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1682 artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel);
1684 if (artifactLabel.isEmpty()) {
1685 log.debug("missing normalized artifact logical name for component {}", componentId);
1686 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1689 if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) {
1690 log.debug("Invalid lenght form Artifact label : {}", artifactLabel);
1691 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String
1692 .valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH)));
1694 if (!validateLabelUniqueness(componentId, parentComponent, artifactLabel, componentType)) {
1695 log.debug("Non unique Artifact label : {}", artifactLabel);
1696 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel));
1699 artifactInfo.setArtifactLabel(artifactLabel);
1701 return Either.left(ActionStatus.OK);
1704 private boolean validateLabelUniqueness(String componentId, Component parentComponent, String artifactLabel, ComponentTypeEnum componentType) {
1705 boolean isUnique = true;
1706 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts;
1707 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1708 artifacts = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1711 artifacts = artifactToscaOperation.getArtifacts(componentId);
1714 if (artifacts.isLeft()) {
1715 for (String label : artifacts.left().value().keySet()) {
1716 if (label.equals(artifactLabel)) {
1722 if (componentType == ComponentTypeEnum.RESOURCE && isUnique) {
1723 isUnique = isUniqueLabelInResourceInterfaces(componentId, artifactLabel);
1728 boolean validateArtifactNameUniqueness(String componentId, Component parentComponent, ArtifactDefinition artifactInfo,
1729 ComponentTypeEnum componentType) {
1730 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = getArtifacts(componentType,
1731 parentComponent, componentId, artifactInfo.getArtifactGroupType());
1732 String artifactName = artifactInfo.getArtifactName();
1733 if (artifacts.isLeft() && Objects.nonNull(artifacts.left().value())){
1734 if (artifacts.left().value().values().stream()
1735 .anyMatch(ad -> artifactName.equals(ad.getArtifactName())
1736 //check whether it is the same artifact we hold (by label)
1737 && !artifactInfo.getArtifactLabel().equals(ad.getArtifactLabel()))){
1741 if (ComponentTypeEnum.RESOURCE == componentType) {
1742 return isUniqueArtifactNameInResourceInterfaces(componentId, artifactName, artifactInfo.getArtifactLabel());
1747 private boolean isUniqueArtifactNameInResourceInterfaces(String componentId, String artifactName, String artifactLabel) {
1748 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1749 .getAllInterfacesOfResource(componentId, true, true);
1751 if (allInterfacesOfResource.isLeft()){
1752 return allInterfacesOfResource.left().value()
1754 .stream().map(InterfaceDefinition :: getOperationsMap)
1755 .flatMap(map -> map.values().stream())
1756 .map(OperationDataDefinition::getImplementation)
1757 .filter(Objects::nonNull)
1758 .noneMatch(add -> artifactName.equals(add.getArtifactName())
1759 && !artifactLabel.equals(add.getArtifactLabel()));
1764 private boolean isUniqueLabelInResourceInterfaces(String componentId, String artifactLabel) {
1765 Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1766 .getAllInterfacesOfResource(componentId, true, true);
1768 if (allInterfacesOfResource.isLeft()){
1769 return allInterfacesOfResource.left().value()
1771 .stream().map(InterfaceDefinition :: getOperationsMap)
1772 .flatMap(map -> map.values().stream())
1773 .map(OperationDataDefinition::getImplementation)
1774 .filter(Objects::nonNull)
1775 .noneMatch(add -> artifactLabel.equals(add.getArtifactLabel()));
1780 private Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(ComponentTypeEnum componentType, Component parentComponent,
1781 String componentId, ArtifactGroupTypeEnum artifactGroupType) {
1782 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse;
1783 if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1784 artifactsResponse = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1787 artifactsResponse = artifactToscaOperation.getArtifacts(componentId);
1789 if (artifactsResponse.isRight() && artifactsResponse.right().value() == StorageOperationStatus.NOT_FOUND) {
1790 log.debug("failed to retrieve artifacts for {} ", componentId);
1791 return Either.right(artifactsResponse.right().value());
1793 return Either.left(artifactsResponse.left().value().entrySet()
1795 .filter(x -> artifactGroupType == x.getValue().getArtifactGroupType())
1796 .collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
1799 // ***************************************************************
1801 private Either<ArtifactDefinition, Operation> createArtifact(Component parent, String parentId, ArtifactDefinition artifactInfo, byte[] decodedPayload,
1802 ComponentTypeEnum componentTypeEnum, AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) {
1804 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
1805 if (artifactData == null) {
1806 BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact");
1807 log.debug("Failed to create artifact object for ES.");
1808 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1810 ComponentInstance foundInstance = findComponentInstance(parentId, parent);
1811 String instanceId = null;
1812 if (foundInstance != null) {
1813 if (foundInstance.isArtifactExists(artifactInfo.getArtifactGroupType(), artifactInfo.getArtifactLabel())) {
1814 log.debug("Failed to create artifact, already exists");
1815 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, artifactInfo.getArtifactLabel());
1817 instanceId = foundInstance.getUniqueId();
1819 // set on graph object id of artifact in ES!
1820 artifactInfo.setEsId(artifactData.getId());
1822 Either<ArtifactDefinition, Operation> operationResult;
1823 if (interfaceType != null && operationName != null) {
1824 // lifecycle artifact
1825 Operation operation = convertToOperation(artifactInfo, operationName);
1826 Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation.updateInterfaceOperation(parentId, interfaceType, operationName, operation);
1827 if (result.isRight()) {
1828 throw new StorageException(result.right().value());
1830 operationResult = Either.right(result.left().value());
1833 // information/deployment/api artifacts
1834 NodeTypeEnum nodeType = convertParentType(componentTypeEnum);
1835 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation.addArtifactToComponent(
1836 artifactInfo, parent, nodeType, true, instanceId);
1837 if (result.isRight()) {
1838 throw new StorageException(result.right().value());
1840 ArtifactDefinition artifactDefinition = result.left().value();
1841 artifactData.setId(artifactDefinition.getEsId());
1842 operationResult = Either.left(artifactDefinition);
1844 if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum) != StorageOperationStatus.OK) {
1845 throw new StorageException(generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum));
1848 saveArtifactInCassandra(artifactData, parent, artifactInfo, "", "", auditingActionEnum, componentTypeEnum);
1849 return operationResult;
1852 private ComponentInstance findComponentInstance(String componentInstanceId, Component containerComponent) {
1853 ComponentInstance foundInstance = null;
1854 if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
1855 foundInstance = containerComponent.getComponentInstances()
1857 .filter(i -> i.getUniqueId().equals(componentInstanceId))
1861 return foundInstance;
1864 private void validateDeploymentArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1865 final ComponentTypeEnum componentType = component.getComponentType();
1866 if (componentType != ComponentTypeEnum.RESOURCE &&
1867 componentType != ComponentTypeEnum.SERVICE &&
1868 componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1869 log.debug("Invalid component type '{}' for artifact. "
1870 + "Expected Resource, Component or Resource Instance", componentType.getValue());
1871 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE,
1872 componentType.getValue(), "Service, Resource or ResourceInstance", componentType.getValue());
1874 final String artifactType = artifactInfo.getArtifactType();
1875 final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1876 if (artifactConfiguration == null) {
1877 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1879 validateArtifactType(componentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1880 if (componentType == ComponentTypeEnum.RESOURCE || componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1881 final Resource resource = (Resource) component;
1882 final ResourceTypeEnum resourceType = resource.getResourceType();
1884 validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1887 validateArtifactExtension(artifactConfiguration, artifactInfo);
1890 private void validateHeatArtifact(final Component parentComponent, final String componentId,
1891 final ArtifactDefinition artifactDefinition) {
1892 final String artifactType = artifactDefinition.getArtifactType();
1893 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1894 if (artifactTypeEnum == null) {
1898 switch (artifactTypeEnum) {
1902 validateHeatTimeoutValue(artifactDefinition);
1905 validateHeatEnvDeploymentArtifact(parentComponent, componentId, artifactDefinition);
1912 private void setArtifactTimeout(final ArtifactDefinition newArtifactInfo,
1913 final ArtifactDefinition existingArtifactInfo) {
1915 final String artifactType = newArtifactInfo.getArtifactType();
1916 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1917 if (artifactTypeEnum == null) {
1918 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1921 switch (artifactTypeEnum) {
1925 if (newArtifactInfo.getTimeout() == null) {
1926 if (existingArtifactInfo == null) {
1927 newArtifactInfo.setTimeout(NodeTemplateOperation.getDefaultHeatTimeout());
1929 newArtifactInfo.setTimeout(existingArtifactInfo.getTimeout());
1934 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1940 void validateDeploymentArtifactTypeIsLegalForParent(ArtifactDefinition artifactInfo, ArtifactTypeEnum artifactType, Map<String, ArtifactTypeConfig> resourceDeploymentArtifacts) {
1941 if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) {
1942 log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType());
1943 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
1947 Optional<ArtifactConfiguration> loadArtifactTypeConfig(final String artifactType) {
1948 if (artifactType == null) {
1949 return Optional.empty();
1951 final List<ArtifactConfiguration> artifactConfigurationList =
1952 ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
1953 if (CollectionUtils.isEmpty(artifactConfigurationList)) {
1954 return Optional.empty();
1957 return artifactConfigurationList.stream()
1958 .filter(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType))
1962 private Either<Boolean, ResponseFormat> extractHeatParameters(ArtifactDefinition artifactInfo) {
1963 // extract heat parameters
1964 if (artifactInfo.getPayloadData() != null) {
1965 String heatDecodedPayload = new String(Base64.decodeBase64(artifactInfo.getPayloadData()));
1966 Either<List<HeatParameterDefinition>, ResultStatusEnum> heatParameters = ImportUtils.getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo
1967 .getArtifactType());
1968 if (heatParameters.isRight() && (heatParameters.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND)) {
1969 log.info("failed to parse heat parameters ");
1970 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo
1971 .getArtifactType());
1972 return Either.right(responseFormat);
1974 else if (heatParameters.isLeft() && heatParameters.left().value() != null) {
1975 artifactInfo.setListHeatParameters(heatParameters.left().value());
1978 return Either.left(true);
1983 void validateArtifactExtension(final ArtifactConfiguration artifactConfiguration,
1984 final ArtifactDefinition artifactDefinition) {
1985 final List<String> acceptedTypes = artifactConfiguration.getAcceptedTypes();
1987 * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted.
1989 if (CollectionUtils.isEmpty(acceptedTypes)) {
1992 final String artifactName = artifactDefinition.getArtifactName();
1993 final String fileExtension = FilenameUtils.getExtension(artifactName);
1995 if (fileExtension == null || !acceptedTypes.contains(fileExtension.toLowerCase())) {
1996 final String artifactType = artifactDefinition.getArtifactType();
1997 log.debug("File extension \"{}\" is not allowed for artifact type \"{}\"", fileExtension, artifactType);
1998 throw new ByActionStatusComponentException(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, artifactType);
2003 void validateHeatEnvDeploymentArtifact(final Component parentComponent, final String parentId,
2004 final ArtifactDefinition artifactInfo) {
2005 final Wrapper<ArtifactDefinition> heatMDWrapper = new Wrapper<>();
2006 final Wrapper<byte[]> payloadWrapper = new Wrapper<>();
2008 validateYaml(artifactInfo);
2009 validateHeatExist(parentComponent.getUniqueId(), parentId, heatMDWrapper, artifactInfo, parentComponent.getComponentType());
2011 if (!heatMDWrapper.isEmpty()) {
2012 fillArtifactPayload(payloadWrapper, heatMDWrapper.getInnerElement());
2015 if (!heatMDWrapper.isEmpty()) {
2016 validateEnvVsHeat(artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement());
2020 public void fillArtifactPayload(Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactDefinition) {
2021 if (ArrayUtils.isEmpty(artifactDefinition.getPayloadData())) {
2022 Either<DAOArtifactData, CassandraOperationStatus> eitherArtifactData = artifactCassandraDao.getArtifact(artifactDefinition.getEsId());
2023 if (eitherArtifactData.isLeft()) {
2024 byte[] data = eitherArtifactData.left().value().getDataAsArray();
2025 payloadWrapper.setInnerElement(Base64.encodeBase64(data));
2028 log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName());
2029 throw new StorageException(DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()));
2033 payloadWrapper.setInnerElement(artifactDefinition.getPayloadData());
2037 private void validateEnvVsHeat(ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) {
2038 String envPayload = new String(Base64.decodeBase64(envArtifact.getPayloadData()));
2039 Map<String, Object> heatEnvToscaJson = (Map<String, Object>) new Yaml().load(envPayload);
2040 String heatDecodedPayload = new String(Base64.decodeBase64(heatPayloadData));
2041 Map<String, Object> heatToscaJson = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
2043 Either<Map<String, Object>, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils.findFirstToscaMapElement(heatEnvToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
2044 if (eitherHeatEnvProperties.isRight()) {
2045 log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName());
2046 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat Env");
2048 Either<Map<String, Object>, ResultStatusEnum> eitherHeatProperties = ImportUtils.findFirstToscaMapElement(heatToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
2049 if (eitherHeatProperties.isRight()) {
2050 log.debug("Invalid heat format for file:{}", heatArtifact.getArtifactName());
2051 throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat");
2053 Set<String> heatPropertiesKeys = eitherHeatProperties.left().value().keySet();
2054 Set<String> heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet();
2055 heatEnvPropertiesKeys.removeAll(heatPropertiesKeys);
2056 if (!heatEnvPropertiesKeys.isEmpty()) {
2057 log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(), heatArtifact.getArtifactName());
2058 throw new ByActionStatusComponentException(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(), heatArtifact.getArtifactName());
2062 private void validateYaml(ArtifactDefinition artifactInfo) {
2063 YamlToObjectConverter yamlConverter = new YamlToObjectConverter();
2064 boolean isYamlValid = yamlConverter.isValidYamlEncoded64(artifactInfo.getPayloadData());
2066 log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName());
2067 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType());
2071 private boolean isValidXml(byte[] xmlToParse) {
2072 boolean isXmlValid = true;
2074 SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
2075 saxParser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
2076 saxParser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
2077 XMLReader reader = saxParser.getXMLReader();
2078 setFeatures(reader);
2079 reader.parse(new InputSource(new ByteArrayInputStream(xmlToParse)));
2081 catch (ParserConfigurationException | IOException | SAXException e) {
2082 log.debug("Xml is invalid : {}", e.getMessage(), e);
2088 private void setFeatures(XMLReader reader) throws SAXNotSupportedException {
2090 reader.setFeature("http://apache.org/xml/features/validation/schema", false);
2091 reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
2093 catch (SAXNotRecognizedException e) {
2094 log.debug("Xml parser couldn't set feature: \"http://apache.org/xml/features/validation/schema\", false", e.getMessage(), e);
2098 private void validateSingleDeploymentArtifactName(final String artifactName, final Component parentComponent) {
2099 boolean artifactNameFound = false;
2100 final Iterator<ArtifactDefinition> parentDeploymentArtifactsItr =
2101 getDeploymentArtifacts(parentComponent, null).iterator();
2103 while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) {
2104 artifactNameFound = artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName());
2106 if (artifactNameFound) {
2107 final ComponentTypeEnum componentType = parentComponent.getComponentType();
2108 log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName);
2109 throw new ByActionStatusComponentException(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS,
2110 componentType.getValue(), parentComponent.getName(), artifactName);
2114 private void validateHeatExist(String componentId, String parentRiId, Wrapper<ArtifactDefinition> heatArtifactMDWrapper, ArtifactDefinition heatEnvArtifact,
2115 ComponentTypeEnum componentType) {
2116 final Either<ArtifactDefinition, StorageOperationStatus> res = artifactToscaOperation
2117 .getHeatArtifactByHeatEnvId(parentRiId, heatEnvArtifact, componentId, componentType);
2118 if (res.isRight()) {
2119 throw new ByActionStatusComponentException(ActionStatus.MISSING_HEAT);
2122 heatArtifactMDWrapper.setInnerElement(res.left().value());
2126 void validateHeatTimeoutValue(final ArtifactDefinition artifactInfo) {
2127 log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel());
2128 // timeout > 0 for HEAT artifacts
2129 if (artifactInfo.getTimeout() == null || artifactInfo.getTimeout() < 1) {
2130 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
2132 // US649856 - Allow several HEAT files on Resource
2133 log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel());
2137 void validateResourceType(final ResourceTypeEnum resourceType, final ArtifactDefinition artifactInfo,
2138 final List<String> typeList) {
2139 if (CollectionUtils.isEmpty(typeList) || typeList.contains(resourceType.getValue())) {
2142 final String listToString = typeList.stream().collect(Collectors.joining(", "));
2143 throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE,
2144 artifactInfo.getArtifactGroupType().getType(), listToString, resourceType.getValue());
2148 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters(ArtifactDefinition artifactInfo, String artifactType) {
2149 if (artifactInfo.getHeatParameters() != null) {
2150 for (HeatParameterDefinition heatParam : artifactInfo.getListHeatParameters()) {
2151 String parameterType = heatParam.getType();
2152 HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType);
2153 String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType();
2154 if (heatParameterType == null) {
2155 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam
2157 return Either.right(responseFormat);
2160 StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam);
2161 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
2162 log.debug("Heat parameter {} is invalid. Status is {}", heatParam.getName(), validateAndUpdateProperty);
2163 ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE;
2164 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, artifactTypeStr, heatParam
2165 .getType(), heatParam.getName());
2166 return Either.right(responseFormat);
2170 return Either.left(artifactInfo);
2173 public List<ArtifactDefinition> getDeploymentArtifacts(final Component component, final String ciId) {
2174 final ComponentTypeEnum componentType = component.getComponentType();
2175 if (component.getDeploymentArtifacts() == null) {
2176 return Collections.emptyList();
2178 final List<ArtifactDefinition> deploymentArtifacts = new ArrayList<>();
2179 if (ComponentTypeEnum.RESOURCE == componentType && ciId != null) {
2180 final Either<ComponentInstance, ResponseFormat> getRI =
2181 getRIFromComponent(component, ciId, null, null, null);
2182 if (getRI.isRight()) {
2183 return Collections.emptyList();
2185 final ComponentInstance ri = getRI.left().value();
2186 if (ri.getDeploymentArtifacts() != null) {
2187 deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values());
2190 deploymentArtifacts.addAll(component.getDeploymentArtifacts().values());
2192 return deploymentArtifacts;
2195 private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) {
2196 // on create if null add informational to current
2197 if (artifactInfo.getArtifactGroupType() == null) {
2198 artifactInfo.setArtifactGroupType(type);
2200 if (artifactInfo.getUniqueId() != null) {
2201 log.error("artifact uniqid cannot be set ignoring");
2203 artifactInfo.setUniqueId(null);
2205 if (artifactInfo.getArtifactRef() != null) {
2206 log.error("artifact ref cannot be set ignoring");
2208 artifactInfo.setArtifactRef(null);
2210 if (artifactInfo.getArtifactRepository() != null) {
2211 log.error("artifact repository cannot be set ignoring");
2213 artifactInfo.setArtifactRepository(null);
2215 if (artifactInfo.getUserIdCreator() != null) {
2216 log.error("creator uuid cannot be set ignoring");
2218 artifactInfo.setArtifactCreator(user.getUserId());
2220 if (artifactInfo.getUserIdLastUpdater() != null) {
2221 log.error("userId of last updater cannot be set ignoring");
2223 artifactInfo.setUserIdLastUpdater(user.getUserId());
2225 if (artifactInfo.getCreatorFullName() != null) {
2226 log.error("creator Full name cannot be set ignoring");
2228 String fullName = user.getFirstName() + " " + user.getLastName();
2229 artifactInfo.setUpdaterFullName(fullName);
2231 if (artifactInfo.getUpdaterFullName() != null) {
2232 log.error("updater Full name cannot be set ignoring");
2234 artifactInfo.setUpdaterFullName(fullName);
2236 if (artifactInfo.getCreationDate() != null) {
2237 log.error("Creation Date cannot be set ignoring");
2239 long time = System.currentTimeMillis();
2240 artifactInfo.setCreationDate(time);
2242 if (artifactInfo.getLastUpdateDate() != null) {
2243 log.error("Last Update Date cannot be set ignoring");
2245 artifactInfo.setLastUpdateDate(time);
2247 if (artifactInfo.getEsId() != null) {
2248 log.error("es id cannot be set ignoring");
2250 artifactInfo.setEsId(null);
2255 private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName, String operationName) {
2256 String id = artifactId;
2257 if (artifactId == null || artifactId.isEmpty()) {
2258 String uniqueId = null;
2259 if (interfaceName != null && operationName != null) {
2260 uniqueId = UniqueIdBuilder.buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo
2261 .getArtifactLabel());
2264 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel());
2266 artifactInfo.setUniqueId(uniqueId);
2267 artifactInfo.setEsId(uniqueId);
2271 artifactInfo.setUniqueId(artifactId);
2272 artifactInfo.setEsId(artifactId);
2277 private Either<Boolean, ResponseFormat> validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2278 if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) {
2279 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD));
2281 return Either.left(true);
2286 Either<Boolean, ResponseFormat> validateAndSetArtifactName(ArtifactDefinition artifactInfo) {
2287 if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) {
2288 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2290 String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName());
2291 if (normalizeFileName == null || normalizeFileName.isEmpty()) {
2292 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2294 artifactInfo.setArtifactName(normalizeFileName);
2296 if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) {
2297 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH)));
2300 return Either.left(true);
2303 private void validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2304 if (StringUtils.isEmpty(artifactInfo.getArtifactType())) {
2305 log.info("artifact type is missing operation ignored");
2306 throw new ByActionStatusComponentException(ActionStatus.MISSING_ARTIFACT_TYPE);
2309 if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) {
2310 log.info("artifact type cannot be changed operation ignored");
2311 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2315 private Either<ArtifactDefinition, ResponseFormat> validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2317 if (Objects.nonNull(artifactInfo) && Objects.nonNull(currentArtifact)) {
2318 if (artifactInfo.getArtifactGroupType() == null) {
2319 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2320 } else if (!currentArtifact.getArtifactGroupType()
2322 .equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) {
2323 log.info("artifact group type cannot be changed. operation failed");
2324 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2327 return Either.left(artifactInfo);
2330 private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact, ArtifactGroupTypeEnum type) {
2332 // on update if null add informational to current
2333 if (currentArtifact.getArtifactGroupType() == null && type != null) {
2334 currentArtifact.setArtifactGroupType(type);
2337 if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) {
2338 log.error("artifact uniqid cannot be set ignoring");
2340 artifactInfo.setUniqueId(currentArtifact.getUniqueId());
2342 if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef()
2343 .equals(artifactInfo.getArtifactRef())) {
2344 log.error("artifact ref cannot be set ignoring");
2346 artifactInfo.setArtifactRef(currentArtifact.getArtifactRef());
2348 if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository()
2349 .equals(artifactInfo.getArtifactRepository())) {
2350 log.error("artifact repository cannot be set ignoring");
2352 artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository());
2354 if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator()
2355 .equals(artifactInfo.getUserIdCreator())) {
2356 log.error("creator uuid cannot be set ignoring");
2358 artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator());
2360 if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator()
2361 .equals(artifactInfo.getArtifactCreator())) {
2362 log.error("artifact creator cannot be set ignoring");
2364 artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator());
2366 if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater()
2367 .equals(artifactInfo.getUserIdLastUpdater())) {
2368 log.error("userId of last updater cannot be set ignoring");
2370 artifactInfo.setUserIdLastUpdater(user.getUserId());
2372 if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName()
2373 .equals(artifactInfo.getCreatorFullName())) {
2374 log.error("creator Full name cannot be set ignoring");
2376 artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName());
2378 if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName()
2379 .equals(artifactInfo.getUpdaterFullName())) {
2380 log.error("updater Full name cannot be set ignoring");
2382 String fullName = user.getFirstName() + " " + user.getLastName();
2383 artifactInfo.setUpdaterFullName(fullName);
2385 if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate()
2386 .equals(artifactInfo.getCreationDate())) {
2387 log.error("Creation Date cannot be set ignoring");
2389 artifactInfo.setCreationDate(currentArtifact.getCreationDate());
2391 if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate()
2392 .equals(artifactInfo.getLastUpdateDate())) {
2393 log.error("Last Update Date cannot be set ignoring");
2395 long time = System.currentTimeMillis();
2396 artifactInfo.setLastUpdateDate(time);
2398 if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) {
2399 log.error("es id cannot be set ignoring");
2401 artifactInfo.setEsId(currentArtifact.getUniqueId());
2403 if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName()
2404 .equals(artifactInfo.getArtifactDisplayName())) {
2405 log.error(" Artifact Display Name cannot be set ignoring");
2407 artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName());
2409 if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi()
2410 .equals(artifactInfo.getServiceApi())) {
2411 log.debug("serviceApi cannot be set. ignoring.");
2413 artifactInfo.setServiceApi(currentArtifact.getServiceApi());
2415 if (artifactInfo.getArtifactGroupType() != null && currentArtifact.getArtifactGroupType() != artifactInfo.getArtifactGroupType()) {
2416 log.debug("artifact group cannot be set. ignoring.");
2418 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2420 artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion());
2422 if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID()
2423 .isEmpty() && !currentArtifact.getArtifactUUID()
2424 .equals(artifactInfo.getArtifactUUID())) {
2425 log.debug("artifact UUID cannot be set. ignoring.");
2427 artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID());
2429 if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo
2430 .getHeatParameters()
2431 .isEmpty() && !currentArtifact.getHeatParameters().isEmpty()) {
2432 checkAndSetUnupdatableHeatParams(artifactInfo.getListHeatParameters(), currentArtifact.getListHeatParameters());
2436 private void checkAndSetUnupdatableHeatParams(List<HeatParameterDefinition> heatParameters, List<HeatParameterDefinition> currentParameters) {
2438 Map<String, HeatParameterDefinition> currentParametersMap = getMapOfParameters(currentParameters);
2439 for (HeatParameterDefinition parameter : heatParameters) {
2440 HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId());
2442 if (currentParam != null) {
2444 if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) {
2445 log.debug("heat parameter name cannot be updated ({}). ignoring.", parameter.getName());
2446 parameter.setName(currentParam.getName());
2448 if (parameter.getDefaultValue() != null && !parameter.getDefaultValue()
2449 .equalsIgnoreCase(currentParam.getDefaultValue())) {
2450 log.debug("heat parameter defaultValue cannot be updated ({}). ignoring.", parameter.getDefaultValue());
2451 parameter.setDefaultValue(currentParam.getDefaultValue());
2453 if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) {
2454 log.debug("heat parameter type cannot be updated ({}). ignoring.", parameter.getType());
2455 parameter.setType(currentParam.getType());
2457 if (parameter.getDescription() != null && !parameter.getDescription()
2458 .equalsIgnoreCase(currentParam.getDescription())) {
2459 log.debug("heat parameter description cannot be updated ({}). ignoring.", parameter.getDescription());
2460 parameter.setDescription(currentParam.getDescription());
2463 // check and set current value
2464 if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) {
2465 log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue());
2466 parameter.setCurrentValue(currentParam.getDefaultValue());
2472 private Map<String, HeatParameterDefinition> getMapOfParameters(List<HeatParameterDefinition> currentParameters) {
2474 Map<String, HeatParameterDefinition> currentParamsMap = new HashMap<>();
2475 for (HeatParameterDefinition param : currentParameters) {
2476 currentParamsMap.put(param.getUniqueId(), param);
2478 return currentParamsMap;
2481 private Either<Boolean, ResponseFormat> validateAndServiceApiUrl(ArtifactDefinition artifactInfo) {
2482 if (!ValidationUtils.validateStringNotEmpty(artifactInfo.getApiUrl())) {
2483 log.debug("Artifact url cannot be empty.");
2484 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL));
2486 artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase());
2488 if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) {
2489 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL));
2491 if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) {
2492 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH)));
2495 return Either.left(true);
2498 private Either<Boolean, ResponseFormat> validateAndCleanDescription(ArtifactDefinition artifactInfo) {
2499 if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) {
2500 log.debug("Artifact description cannot be empty.");
2501 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION));
2503 String description = artifactInfo.getDescription();
2504 description = ValidationUtils.removeNoneUtf8Chars(description);
2505 description = ValidationUtils.normaliseWhitespace(description);
2506 description = ValidationUtils.stripOctets(description);
2507 description = ValidationUtils.removeHtmlTagsOnly(description);
2508 if (!ValidationUtils.validateIsEnglish(description)) {
2509 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2511 if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) {
2512 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION, String
2513 .valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)));
2515 artifactInfo.setDescription(description);
2516 return Either.left(true);
2519 private <T> Either<ArtifactDefinition, T> updateArtifactFlow(Component parent, String parentId, String artifactId,
2520 ArtifactDefinition artifactInfo, byte[] decodedPayload,
2521 ComponentTypeEnum componentType, AuditingActionEnum auditingAction) {
2522 DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
2523 if (artifactData == null) {
2524 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2525 log.debug("Failed to create artifact object for ES.");
2526 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
2528 log.debug("Entry on graph is updated. Update artifact in ES");
2529 // Changing previous and current artifactId for auditing
2530 String currArtifactId = artifactInfo.getUniqueId();
2532 NodeTypeEnum parentType = convertParentType(componentType);
2534 if (decodedPayload == null) {
2535 if (!artifactInfo.getMandatory() || artifactInfo.getEsId() != null) {
2536 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactInfo.getEsId());
2537 if (artifactFromCassandra.isRight()) {
2538 throw new StorageException(artifactFromCassandra.right().value());
2540 // clone data to new artifact
2541 artifactData.setData(artifactFromCassandra.left().value().getData());
2542 artifactData.setId(artifactFromCassandra.left().value().getId());
2544 } else if (artifactInfo.getEsId() == null) {
2545 artifactInfo.setEsId(artifactInfo.getUniqueId());
2546 artifactData.setId(artifactInfo.getUniqueId());
2549 Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation.updateArtifactOnResource(artifactInfo,
2550 parent, artifactId, parentType, parentId, true);
2551 if (result.isRight()) {
2552 throw new StorageException(result.right().value());
2554 ArtifactDefinition artifactDefinition = result.left().value();
2555 updateGeneratedIdInHeatEnv(parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType);
2557 StorageOperationStatus storageOperationStatus = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
2558 if (storageOperationStatus != StorageOperationStatus.OK) {
2559 throw new StorageException(storageOperationStatus);
2561 if (artifactData.getData() != null) {
2562 if (!artifactDefinition.getDuplicated() || artifactData.getId() == null) {
2563 artifactData.setId(artifactDefinition.getEsId());
2565 saveArtifactInCassandra(artifactData, parent, artifactInfo, currArtifactId, artifactId, auditingAction, componentType);
2567 return Either.left(artifactDefinition);
2570 private String updateGeneratedIdInHeatEnv(Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2571 if (NodeTypeEnum.Resource == parentType) {
2572 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType, false);
2574 return artifactDefinition.getUniqueId();
2577 private String updateGeneratedIdInHeatEnv(Map<String, ArtifactDefinition> deploymentArtifacts, Component parentComponent, String parentId, String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition, NodeTypeEnum parentType, boolean isInstanceArtifact) {
2578 String artifactUniqueId;
2579 artifactUniqueId = artifactDefinition.getUniqueId();
2580 String artifactType = artifactInfo.getArtifactType();
2581 if ((ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) ||
2582 ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType) ||
2583 ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType))
2584 && !artifactUniqueId.equals(artifactId)) {
2585 // need to update the generated id in heat env
2586 Optional<Entry<String, ArtifactDefinition>> findFirst = deploymentArtifacts.entrySet()
2588 .filter(a -> artifactId.equals(a.getValue().getGeneratedFromId()))
2590 if (findFirst.isPresent()) {
2591 ArtifactDefinition artifactEnvInfo = findFirst.get().getValue();
2592 artifactEnvInfo.setIsFromCsar(artifactDefinition.getIsFromCsar());
2593 artifactEnvInfo.setArtifactChecksum(null);
2594 if (isInstanceArtifact) {
2595 artifactToscaOperation.updateHeatEnvArtifactOnInstance(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2597 artifactToscaOperation.updateHeatEnvArtifact(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2601 return artifactUniqueId;
2604 private String updateGeneratedIdInHeatEnvOnInstance(ComponentInstance parent, Component parentComponent, String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2605 return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parentComponent, parent.getUniqueId(),artifactId, artifactInfo, artifactDefinition, parentType, true);
2609 private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) {
2610 log.trace("Starting payload handling");
2611 byte[] payload = artifactInfo.getPayloadData();
2612 byte[] decodedPayload = null;
2614 if (payload != null && payload.length != 0) {
2615 // the generated artifacts were already decoded by the handler
2616 decodedPayload = artifactInfo.getGenerated() ? payload : Base64.decodeBase64(payload);
2617 if (decodedPayload.length == 0) {
2618 log.debug("Failed to decode the payload.");
2619 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
2620 return Either.right(responseFormat);
2623 String checkSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(decodedPayload);
2624 artifactInfo.setArtifactChecksum(checkSum);
2625 log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum);
2627 // Specific payload validations of different types
2628 Either<Boolean, ResponseFormat> result = Either.left(true);
2629 if (isDeploymentArtifact(artifactInfo)) {
2630 log.trace("Starting deployment artifacts payload validation");
2631 String artifactType = artifactInfo.getArtifactType();
2632 String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName());
2633 PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension);
2635 final Optional<ResponseFormat> pmDictionaryError = validateIfPmDictionary(artifactType, decodedPayload);
2636 if (pmDictionaryError.isPresent()) {
2637 return Either.right(pmDictionaryError.get());
2640 Either<Boolean, ActionStatus> isPayloadValid = payloadType.isValid(decodedPayload);
2641 if (isPayloadValid.isRight()) {
2642 ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType);
2643 return Either.right(responseFormat);
2646 if (payloadType.isHeatRelated()) {
2647 log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType);
2648 result = extractHeatParameters(artifactInfo);
2651 if (result.isRight()) {
2652 return Either.right(result.right().value());
2655 } // null/empty payload is normal if called from metadata update ONLY.
2656 // The validation of whether this is metadata/payload update case is
2657 // currently done separately
2659 if (!isArtifactMetadataUpdate) {
2660 log.debug("In artifact: {} Payload is missing.",artifactInfo.getArtifactName());
2661 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
2662 return Either.right(responseFormat);
2665 log.trace("Ended payload handling");
2666 return Either.left(decodedPayload);
2669 private Optional<ResponseFormat> validateIfPmDictionary(String artifactType, byte[] decodedPayload) {
2670 return new PMDictionaryValidator()
2671 .validateIfPmDictionary(artifactType, decodedPayload)
2672 .map(this::preparePmDictionaryResponse);
2675 private ResponseFormat preparePmDictionaryResponse(String errorMessage) {
2676 return componentsUtils.getResponseFormat(ActionStatus.INVALID_PM_DICTIONARY_FILE, errorMessage);
2679 public Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface(
2680 String resourceId, String userUserId, String artifactId, boolean inTransaction) {
2682 return toscaOperationFacade
2683 .getToscaElement(resourceId, JsonParseFlagEnum.ParseMetadata)
2684 .right().map(componentsUtils.toResponseFormat())
2685 .left().bind(parentComponent -> {
2686 User user = new User(userUserId);
2687 return handleDelete(resourceId, artifactId, user,
2689 false, inTransaction);
2693 private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) {
2694 Operation op = new Operation();
2695 long time = System.currentTimeMillis();
2696 op.setCreationDate(time);
2698 String artifactName = artifactInfo.getArtifactName();
2699 artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName));
2701 op.setImplementation(artifactInfo);
2702 op.setLastUpdateDate(time);
2706 private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) {
2707 String newArtifactName = operationName + "_" + artifactName;
2708 log.trace("converting artifact name {} to {}", artifactName, newArtifactName);
2709 return newArtifactName;
2713 public byte[] downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion, String artifactName) {
2715 // General validation
2716 if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) {
2717 log.debug(NULL_PARAMETER);
2718 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2721 // Normalizing artifact name
2722 artifactName = ValidationUtils.normalizeFileName(artifactName);
2724 // Resource validation
2725 Resource resource = validateResourceNameAndVersion(resourceName, resourceVersion);
2726 String resourceId = resource.getUniqueId();
2728 // Service validation
2729 Service validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion);
2731 Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts();
2732 if (artifacts == null || artifacts.isEmpty()) {
2733 log.debug("Deployment artifacts of resource {} are not found", resourceId);
2734 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2737 ArtifactDefinition deploymentArtifact = null;
2739 for (ArtifactDefinition artifactDefinition : artifacts.values()) {
2740 if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName()
2741 .equals(artifactName)) {
2742 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2743 deploymentArtifact = artifactDefinition;
2748 if (deploymentArtifact == null) {
2749 log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId);
2750 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2753 // Downloading the artifact
2754 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deploymentArtifact);
2755 log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId());
2756 return downloadArtifactEither.getRight();
2760 public byte[] downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) {
2762 // General validation
2763 if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) {
2764 log.debug(NULL_PARAMETER);
2765 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2768 // Normalizing artifact name
2769 artifactName = ValidationUtils.normalizeFileName(artifactName);
2771 // Service validation
2772 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2774 // ResourceInstance validation
2775 ComponentInstance resourceInstance = validateResourceInstance(service, resourceInstanceName);
2777 Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
2779 final String finalArtifactName = artifactName;
2780 Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName);
2782 ArtifactDefinition deployableArtifact = artifacts==null ? null :
2783 artifacts.values().stream()
2784 .filter(filterArtifactByName)
2788 if (deployableArtifact == null) {
2789 log.debug("Deployment artifact with name {} not found", artifactName);
2790 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
2793 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2794 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deployableArtifact);
2796 log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId());
2797 return downloadArtifactEither.getRight();
2800 private ComponentInstance validateResourceInstance(Service service, String resourceInstanceName) {
2802 List<ComponentInstance> riList = service.getComponentInstances();
2803 for (ComponentInstance ri : riList) {
2804 if (ri.getNormalizedName().equals(resourceInstanceName)) {
2808 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName);
2811 private ComponentInstance validateResourceInstanceById(Component component, String resourceInstanceId) {
2813 List<ComponentInstance> riList = component.getComponentInstances();
2814 for (ComponentInstance ri : riList) {
2815 if (ri.getUniqueId().equals(resourceInstanceId)) {
2819 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceInstanceId);
2822 private Service validateServiceNameAndVersion(String serviceName, String serviceVersion) {
2824 Either<List<Service>, StorageOperationStatus> serviceListBySystemName = toscaOperationFacade.getBySystemName(ComponentTypeEnum.SERVICE, serviceName);
2825 if (serviceListBySystemName.isRight()) {
2826 log.debug("Couldn't fetch any service with name {}", serviceName);
2827 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(serviceListBySystemName
2829 .value(), ComponentTypeEnum.SERVICE), serviceName);
2831 List<Service> serviceList = serviceListBySystemName.left().value();
2832 if (serviceList == null || serviceList.isEmpty()) {
2833 log.debug("Couldn't fetch any service with name {}", serviceName);
2834 throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceName);
2837 Service foundService = null;
2838 for (Service service : serviceList) {
2839 if (service.getVersion().equals(serviceVersion)) {
2840 log.trace("Found service with version {}", serviceVersion);
2841 foundService = service;
2846 if (foundService == null) {
2847 log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName);
2848 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE
2849 .getValue(), serviceVersion);
2851 return foundService;
2854 private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2856 Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2857 if (resourceListBySystemName.isRight()) {
2858 log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2859 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName
2861 .value()), resourceName);
2863 return resourceListBySystemName.left().value();
2866 public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2868 log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion, artifactName);
2869 if (serviceName == null || serviceVersion == null || artifactName == null) {
2870 log.debug(NULL_PARAMETER);
2871 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2874 // Normalizing artifact name
2875 final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2877 // Service validation
2878 Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2879 // Looking for deployment or tosca artifacts
2880 String serviceId = service.getUniqueId();
2882 if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2883 log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2884 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2887 Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2889 if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2890 foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2891 // filters artifact by name
2892 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2894 if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2895 foundArtifactOptl = service.getToscaArtifacts().values().stream()
2896 // filters TOSCA artifact by name
2897 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2899 if (!foundArtifactOptl.isPresent()) {
2900 log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2901 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2903 log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2904 // Downloading the artifact
2905 ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl
2907 log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2908 return downloadArtifactEither.getRight();
2911 public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2912 log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2913 Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2914 if (artifactById.isRight()) {
2915 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2916 log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2917 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2919 ArtifactDefinition artifactDefinition = artifactById.left().value();
2920 if (artifactDefinition == null) {
2921 log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2922 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2925 return downloadArtifact(artifactDefinition);
2928 private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId, ComponentTypeEnum componentType,
2929 String containerComponentType) {
2931 ComponentTypeEnum componentForAudit = null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
2932 componentForAudit.getNodeType();
2934 Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade
2935 .getToscaFullElement(componentId);
2937 if (componentResult.isRight()) {
2938 ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
2939 ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
2940 log.debug("Service not found, serviceId {}", componentId);
2941 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
2942 throw new ByActionStatusComponentException(status, componentId);
2944 return componentResult.left().value();
2947 private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId, ArtifactOperationInfo operation) {
2948 if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
2950 validateCanWorkOnComponent(component, userId);
2951 }catch (ComponentException e) {
2952 String uniqueId = component.getUniqueId();
2953 log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId);
2954 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(),
2955 component.getComponentType(), null);
2961 private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
2963 if (operation.isNotDownload()) {
2964 String role = user.getRole();
2965 if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
2966 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2967 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
2968 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2969 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
2974 private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType, boolean inTransaction) {
2977 user = validateUserExists(userId);
2978 } catch(ByResponseFormatComponentException e){
2979 ResponseFormat responseFormat = e.getResponseFormat();
2980 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2982 } catch(ByActionStatusComponentException e){
2983 ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2984 handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2990 private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId,
2991 ResponseFormat responseFormat, ComponentTypeEnum componentType, String userId){
2992 User user = new User();
2993 user.setUserId(userId);
2994 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2997 protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
2998 AuditingActionEnum auditingAction = null;
2999 switch (operation.getArtifactOperationEnum()) {
3001 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
3004 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
3007 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
3010 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
3015 return auditingAction;
3018 private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
3019 String esArtifactId = artifactDefinition.getEsId();
3020 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3021 if (artifactfromES.isRight()) {
3022 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3023 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3024 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3025 log.debug("Error when getting artifact from ES, error: {}", actionStatus);
3026 throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
3029 DAOArtifactData DAOArtifactData = artifactfromES.left().value();
3030 byte[] data = DAOArtifactData.getDataAsArray();
3032 log.debug("Artifact data from cassandra is null");
3033 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
3035 String artifactName = artifactDefinition.getArtifactName();
3036 log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
3037 return new ImmutablePair<>(artifactName, data);
3040 public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
3041 return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
3044 private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo,
3045 String currArtifactId, String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
3046 CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
3048 if (resourceUploadStatus == CassandraOperationStatus.OK) {
3049 log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
3050 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3051 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId,
3052 currArtifactId, responseFormat, componentType, null);
3055 BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
3056 log.info(FAILED_SAVE_ARTIFACT);
3057 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3058 handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null);
3059 throw new StorageException(resourceUploadStatus);
3063 private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
3064 return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
3067 private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
3068 return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
3071 private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
3072 return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
3075 private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
3076 final String artifactType = artifactInfo.getArtifactType();
3077 final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
3078 if (artifactTypeEnum == null) {
3079 artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
3082 switch (artifactTypeEnum) {
3094 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
3095 User user = userBusinessLogic.getUser(userUserId, inTransaction);
3096 return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
3099 public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user, ArtifactGroupTypeEnum groupType) {
3100 ArtifactDefinition artifactInfo = new ArtifactDefinition();
3102 String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
3103 String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
3104 String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
3106 artifactInfo.setArtifactDisplayName(artifactName);
3107 artifactInfo.setArtifactLabel(logicalName.toLowerCase());
3108 artifactInfo.setArtifactType(artifactType);
3109 artifactInfo.setDescription(artifactDescription);
3110 artifactInfo.setArtifactGroupType(groupType);
3111 nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
3113 setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
3115 return artifactInfo;
3118 private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
3119 String uniqueId = null;
3121 if (resourceId != null) {
3122 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel()
3124 artifactInfo.setUniqueId(uniqueId);
3126 artifactInfo.setUserIdCreator(user.getUserId());
3127 String fullName = user.getFullName();
3128 artifactInfo.setUpdaterFullName(fullName);
3130 long time = System.currentTimeMillis();
3132 artifactInfo.setCreatorFullName(fullName);
3133 artifactInfo.setCreationDate(time);
3135 artifactInfo.setLastUpdateDate(time);
3136 artifactInfo.setUserIdLastUpdater(user.getUserId());
3138 artifactInfo.setMandatory(true);
3141 public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, ArtifactGroupTypeEnum groupType, String instanceId) {
3142 return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
3145 public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact, Component component, NodeTypeEnum parentType, String instanceId) {
3146 return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
3149 private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
3151 byte[] payload = payloadStr.getBytes();
3153 DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
3154 return Either.left(artifactData);
3158 * @param artifactDefinition
3161 public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType, Component component, String resourceInstanceName, User modifier,
3162 String instanceId, boolean shouldLock, boolean inTransaction) {
3163 String payload = generateHeatEnvPayload(artifactDefinition);
3164 String prevUUID = artifactDefinition.getArtifactUUID();
3165 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
3166 return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId, shouldLock, inTransaction)
3168 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
3171 public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType, Component component, String resourceInstanceName, User modifier,
3172 boolean shouldLock, boolean inTransaction, String instanceId) {
3173 String payload = generateHeatEnvPayload(artifactDefinition);
3174 String prevUUID = artifactDefinition.getArtifactUUID();
3175 ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
3176 return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId, shouldLock, inTransaction)
3178 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
3182 Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID, ArtifactDefinition clonedBeforeGenerate, ArtifactDefinition updatedArtDef) {
3183 if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
3184 List<ComponentInstance> componentInstances = component.getComponentInstances();
3185 if (componentInstances != null) {
3186 Optional<ComponentInstance> findFirst = componentInstances.stream()
3187 .filter(ci -> ci.getUniqueId()
3188 .equals(instanceId))
3190 if (findFirst.isPresent()) {
3191 ComponentInstance relevantInst = findFirst.get();
3192 List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate, relevantInst
3193 .getGroupInstances());
3195 if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
3196 updatedGroupInstances.forEach(gi -> {
3197 gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
3198 gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
3200 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade.updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
3201 if (status.isRight()) {
3202 log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
3203 ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils
3204 .convertFromStorageResponse(status.right()
3205 .value()), clonedBeforeGenerate.getArtifactDisplayName());
3206 return Either.right(responseFormat);
3212 return Either.left(updatedArtDef);
3215 private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
3216 List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
3217 StringBuilder sb = new StringBuilder();
3218 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
3219 sb.append("parameters:\n");
3220 if (heatParameters != null) {
3221 heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
3223 List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
3225 for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
3227 String heatValue = heatParameterDefinition.getCurrentValue();
3228 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
3229 heatValue = heatParameterDefinition.getDefaultValue();
3230 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
3231 empltyHeatValues.add(heatParameterDefinition);
3235 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
3240 .append(heatParameterDefinition.getName())
3243 .append(Boolean.parseBoolean(heatValue))
3248 .append(heatParameterDefinition.getName())
3251 .append(new BigDecimal(heatValue).toPlainString())
3254 case COMMA_DELIMITED_LIST:
3257 .append(heatParameterDefinition.getName())
3264 String value = heatValue;
3265 boolean starts = value.startsWith("\"");
3266 boolean ends = value.endsWith("\"");
3267 if (!(starts && ends)) {
3268 starts = value.startsWith("'");
3269 ends = value.endsWith("'");
3270 if (!(starts && ends)) {
3271 value = "\"" + value + "\"";
3275 .append(heatParameterDefinition.getName())
3285 if (!empltyHeatValues.isEmpty()) {
3286 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
3287 empltyHeatValues.forEach(hv -> {
3288 sb.append(" ").append(hv.getName()).append(":");
3289 HeatParameterType type = HeatParameterType.isValidType(hv.getType());
3290 if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv
3291 .getCurrentValue()) || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
3292 sb.append(" \"\"").append("\n");
3295 sb.append(" ").append("\n");
3300 sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
3303 return sb.toString().replaceAll("\\\\n", "\n");
3307 * @param artifactDefinition
3311 public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload, ComponentTypeEnum componentType, Component component, String resourceInstanceName,
3312 User modifier, String instanceId, boolean shouldLock, boolean inTransaction) {
3313 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction, artifactDefinition::getHeatParamsUpdateDate,
3314 () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
3318 public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload, ComponentTypeEnum componentType, Component component, String resourceInstanceName,
3319 User modifier, String instanceId, boolean shouldLock, boolean inTransaction) {
3320 return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction, System::currentTimeMillis,
3321 () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
3325 protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType, Component component, String resourceInstanceName, User modifier,
3326 boolean shouldLock, boolean inTransaction, Supplier<Long> payloadUpdateDateGen, Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator, String instanceId) {
3328 log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition
3330 if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0 || artifactDefinition
3331 .getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
3333 log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
3334 Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
3335 DAOArtifactData artifactData = null;
3337 if (artifactDataRes.isLeft()) {
3338 artifactData = artifactDataRes.left().value();
3341 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3342 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3343 .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3344 ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3346 return Either.right(artifactDataRes.right().value());
3348 String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
3350 String esArtifactId = artifactDefinition.getEsId();
3351 Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
3352 DAOArtifactData DAOArtifactData;
3353 if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
3354 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
3355 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3356 if (artifactfromES.isRight()) {
3357 CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3358 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3359 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3360 log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
3361 return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
3363 DAOArtifactData = artifactfromES.left().value();
3364 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3367 oldCheckSum = artifactDefinition.getArtifactChecksum();
3370 Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3374 lockComponent(component, "Update Artifact - lock resource: ");
3375 }catch (ComponentException e){
3376 handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null, artifactDefinition
3377 .getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3382 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3384 artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3385 updateArifactDefinitionStatus = artifactToscaOperation.updateArtifactOnResource(artifactDefinition, component
3386 ,artifactDefinition.getUniqueId(), componentType.getNodeType(), instanceId, true);
3387 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition
3388 .getArtifactType(), artifactDefinition.getEsId());
3389 if (updateArifactDefinitionStatus.isRight()) {
3390 ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus
3392 .value()), artifactDefinition.getArtifactDisplayName());
3393 log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3394 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3395 .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3396 ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3398 return Either.right(responseFormat);
3402 artifactDefinition.getArtifactChecksum();
3403 artifactDefinition.setArtifactChecksum(newCheckSum);
3404 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3405 log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition
3406 .getArtifactType(), artifactDefinition.getEsId());
3407 updateArifactDefinitionStatus = artifactToscaOperation.updateArtifactOnResource(artifactDefinition, component,
3408 artifactDefinition.getUniqueId(), componentType.getNodeType(), instanceId, true);
3410 log.trace("Update Payload {}", artifactDefinition.getEsId());
3412 if (updateArifactDefinitionStatus.isLeft()) {
3414 artifactDefinition = updateArifactDefinitionStatus.left().value();
3415 artifactData.setId(artifactDefinition.getUniqueId());
3416 CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3418 if (saveArtifactStatus == CassandraOperationStatus.OK) {
3419 if (!inTransaction) {
3420 janusGraphDao.commit();
3422 log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3423 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3424 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3425 .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3426 ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3430 if (!inTransaction) {
3431 janusGraphDao.rollback();
3433 log.info("Failed to save artifact {}.", artifactData.getId());
3434 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3435 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3436 .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3437 ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3439 return Either.right(responseFormat);
3443 ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus
3445 .value()), artifactDefinition.getArtifactDisplayName());
3446 log.debug("Failed To update artifact {}", artifactData.getId());
3447 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3448 .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3449 ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3451 return Either.right(responseFormat);
3457 graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType()
3463 return Either.left(artifactDefinition);
3467 public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType, List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3468 return this.buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType, artifactDef
3469 .getArtifactLabel(), artifactDef.getArtifactDisplayName(),
3470 artifactDef.getDescription(), artifactDef.getPayloadData(), updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3474 public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType, ArtifactGroupTypeEnum artifactGroupType, String label, String displayName, String description, byte[] artifactContent,
3475 List<ArtifactTemplateInfo> updatedRequiredArtifacts, List<HeatParameterDefinition> heatParameters) {
3477 Map<String, Object> json = new HashMap<>();
3478 if (artifactId != null && !artifactId.isEmpty()) {
3479 json.put(Constants.ARTIFACT_ID, artifactId);
3482 json.put(Constants.ARTIFACT_NAME, artifactName);
3483 json.put(Constants.ARTIFACT_TYPE, artifactType);
3484 json.put(Constants.ARTIFACT_DESCRIPTION, description);
3486 if (artifactContent != null) {
3487 log.debug("payload is encoded. perform decode");
3488 String encodedPayload = Base64.encodeBase64String(artifactContent);
3489 json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3491 json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3492 json.put(Constants.ARTIFACT_LABEL, label);
3493 json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3494 json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3495 : updatedRequiredArtifacts.stream()
3496 .filter(e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e
3498 .equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3499 .map(ArtifactTemplateInfo::getFileName)
3500 .collect(Collectors.toList()));
3501 json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>()
3506 public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user, Map<String, Object> json, ArtifactOperationInfo operation, ArtifactDefinition artifactInfo) {
3508 String jsonStr = gson.toJson(json);
3509 ArtifactDefinition artifactDefinitionFromJson = artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3510 String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3511 Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactUniqueId,
3512 artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3514 return Either.left(uploadArtifactToService.left().value());
3517 private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType,
3518 Component parent, String originData, String origMd5, ArtifactOperationInfo operation) {
3519 if (origMd5 != null) {
3520 validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3521 if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3522 validateDeploymentArtifact(artifactInfo, parent);
3523 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3524 } else { // duplicate
3525 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3528 return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3531 private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId, ArtifactDefinition artifactInfo, User user, AuditingActionEnum auditingAction, Component parent,
3532 ComponentTypeEnum componentType, String origMd5) {
3533 Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3534 if (getRI.isRight()) {
3535 throw new ByResponseFormatComponentException(getRI.right().value());
3537 ComponentInstance ri = getRI.left().value();
3538 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3539 if (getArtifactRes.isRight()) {
3540 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3542 ArtifactDefinition currArtifact = getArtifactRes.left().value();
3544 if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) ||
3545 currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_VOL.getType()) ||
3546 currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3547 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3549 List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3550 List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3553 if (origMd5 != null) {
3554 Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction, parent, user, artifactInfo,
3555 artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams, currArtifact.getArtifactName());
3556 if (uploadParamsValidationResult.isRight()) {
3557 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3559 artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3562 Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo, ArtifactTypeEnum.HEAT_ENV.getType());
3563 if (validateAndConvertHeatParamers.isRight()) {
3564 throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3567 if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3568 // fill reduced heat env parameters List for updating
3569 boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3570 if (updateRequired) {
3571 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3572 currArtifact.setListHeatParameters(currentHeatEnvParams);
3573 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation.updateArtifactOnResource(
3574 currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3575 if (updateArtifactRes.isRight()) {
3576 log.debug("Failed to update artifact on graph - {}", artifactId);
3577 throw new StorageException(updateArtifactRes.right().value());
3579 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(), parent.getUniqueId());
3580 if (error != StorageOperationStatus.OK) {
3581 throw new StorageException(error);
3585 updateHeatMetaDataIfNeeded(componentId,user,auditingAction,componentType, parent,ri,artifactInfo);
3586 StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3587 if (error != StorageOperationStatus.OK) {
3588 throw new StorageException(error);
3591 return Either.left(currArtifact);
3595 updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType, Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3596 String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3597 Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId, auditingAction, user);
3598 if (getArtifactRes.isRight()) {
3599 throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3601 ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3602 if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3603 validateHeatMetaData(updatedHeatEnvArtifact);
3604 updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3605 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation.updateArtifactOnResource(heatArtifactToUpdate, parent,
3606 heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId, false);
3608 if (updateArtifactRes.isRight()) {
3609 log.debug("Failed to update artifact on graph - {}", heatArtifactId);
3610 throw new StorageException(updateArtifactRes.right().value());
3612 ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3613 updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition, componentType.getNodeType());
3614 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(), parent.getUniqueId());
3615 if (error != StorageOperationStatus.OK) {
3616 throw new StorageException(error);
3621 private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3622 Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3623 Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3624 Integer updateTimeout = updatedHeatEnv.getTimeout();
3625 if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3626 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3630 private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3631 // currently only timeout metadata can be updated
3632 return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3635 private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3636 // currently only timeout metadata can be updated
3637 origHeat.setTimeout(updatedHeatEnv.getTimeout());
3640 private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams, List<HeatParameterDefinition> updatedHeatEnvParams) {
3641 boolean isUpdate = false;
3642 List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3643 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3644 String paramName = heatEnvParam.getName();
3645 validateParamName(paramName, currentParamsNames);
3646 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3647 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3648 String updatedParamValue = heatEnvParam.getCurrentValue();
3649 if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3650 currHeatParam.setCurrentValue(updatedParamValue);
3659 private void validateParamName(String paramName, List<String> heatParamsNames) {
3660 if (!heatParamsNames.contains(paramName)) {
3661 throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3665 private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo, AuditingActionEnum auditingAction, Component parent,
3666 ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact, boolean needToUpdateGroup) {
3667 Either<ArtifactDefinition, Operation> insideEither = null;
3668 String currentHeatId = currHeatArtifact.getUniqueId();
3670 String esArtifactId = currHeatArtifact.getEsId();
3671 Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3672 if (artifactFromES.isRight()) {
3673 StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3674 throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3677 DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3678 ArtifactDefinition updatedHeatArt = currHeatArtifact;
3679 List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3680 List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3681 List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3683 if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3684 //TODO: improve complexity - currently N^2
3686 for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3687 paramName = heatEnvParam.getName();
3688 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3689 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3690 String updatedParamValue = heatEnvParam.getCurrentValue();
3691 if (updatedParamValue == null) {
3692 updatedParamValue = heatEnvParam.getDefaultValue();
3694 HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3695 if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3696 throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE,
3697 ArtifactTypeEnum.HEAT_ENV.getType(), paramType.getType(), paramName);
3699 currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3700 newHeatEnvParams.add(currHeatParam);
3705 if (!newHeatEnvParams.isEmpty()) {
3706 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3707 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation.updateArtifactOnResource(
3708 currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3710 if (operationStatus.isRight()) {
3711 log.debug("Failed to update artifact on graph - {}", currHeatArtifact.getUniqueId());
3712 throw new StorageException(operationStatus.right().value());
3714 updatedHeatArt = operationStatus.left().value();
3715 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3716 DAOArtifactData.setId(updatedHeatArt.getEsId());
3718 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt
3719 .getUniqueId(), auditingAction, componentType);
3720 insideEither = Either.left(updatedHeatArt);
3723 Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3724 if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3725 artifactEnvInfo.setArtifactChecksum(null);
3726 updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt
3727 .getUniqueId(), componentType.getNodeType(), componentId);
3730 //TODO Andrey check if componentId = parent.getUniqeId
3731 updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType
3735 if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3736 ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo,
3737 updateHeatEnvArtifact.left().value(), parent);
3738 if (result != ActionStatus.OK) {
3739 throw new ByActionStatusComponentException(result);
3742 if (updatedHeatEnvParams.isEmpty()) {
3743 throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3745 return insideEither;
3749 private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3750 StorageOperationStatus error = StorageOperationStatus.OK;
3751 log.debug("Need to re-generate customization UUID for group instance on component instance {}", ri.getUniqueId());
3752 List<GroupInstance> groupsInstances = ri.getGroupInstances();
3753 List<String> groupInstancesId = null;
3754 if (groupsInstances != null && !groupsInstances.isEmpty()) {
3755 groupInstancesId = groupsInstances.stream()
3756 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts()
3757 .contains(artifactId))
3758 .map(GroupInstanceDataDefinition::getUniqueId)
3759 .collect(Collectors.toList());
3761 if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3762 toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3768 public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent, User user, ArtifactDefinition artifactInfo, String artifactId, ComponentTypeEnum componentType,
3769 String riName, List<HeatParameterDefinition> currentHeatEnvParams, List<HeatParameterDefinition> updatedHeatEnvParams, String currArtifactName) {
3771 if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3772 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo
3773 .getArtifactName(), currArtifactName);
3774 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3775 return Either.right(responseFormat);
3778 for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3779 String paramName = uploadedHeatParam.getName();
3780 boolean isExistsInHeat = false;
3781 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3782 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3784 isExistsInHeat = true;
3785 uploadedHeatParam.setType(currHeatParam.getType());
3786 uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3787 uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3788 uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3792 if (!isExistsInHeat) {
3793 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3794 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3795 return Either.right(responseFormat);
3798 return Either.left(updatedHeatEnvParams);
3801 private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId, AuditingActionEnum auditingAction, User user) {
3802 ResponseFormat responseFormat = null;
3803 List<ComponentInstance> ris = component.getComponentInstances();
3804 for (ComponentInstance ri : ris) {
3805 if (riID.equals(ri.getUniqueId())) {
3806 return Either.left(ri);
3809 responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3810 log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3811 handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3812 return Either.right(responseFormat);
3815 private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId, AuditingActionEnum auditingAction, User user) {
3816 ResponseFormat responseFormat = null;
3817 Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3818 for (ArtifactDefinition artifact : rtifactsMap.values()) {
3819 if (artifactId.equals(artifact.getUniqueId())) {
3820 return Either.left(artifact);
3823 responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3824 handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, ri
3826 return Either.right(responseFormat);
3829 public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3830 ArtifactDefinition ret;
3831 if (eitherArtifact.isLeft()) {
3832 ret = eitherArtifact.left().value();
3835 ret = eitherArtifact.right().value().getImplementationArtifact();
3840 public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo) {
3841 Component component = getComponentByUuid(componentType, componentUuid);
3842 resourceCommonInfo.setResourceName(component.getName());
3843 return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3847 * downloads an artifact of resource instance of component by UUIDs
3849 * @param componentType
3850 * @param componentUuid
3851 * @param resourceInstanceName
3852 * @param artifactUUID
3855 public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid,
3856 String resourceInstanceName, String artifactUUID) {
3857 ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3859 if (resourceInstance != null) {
3860 return downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, resourceInstance.getName());
3862 return downloadArtifact(null, artifactUUID, null);
3867 * uploads an artifact to a component by UUID
3871 * @param componentType
3872 * @param componentUuid
3873 * @param resourceCommonInfo
3877 public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3878 String componentUuid, ResourceCommonInfo resourceCommonInfo, ArtifactOperationInfo operation) {
3879 Either<ArtifactDefinition, Operation> actionResult;
3880 Component component;
3882 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3883 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3884 String userId = request.getHeader(Constants.USER_ID_HEADER);
3886 Either<ComponentMetadataData, ActionStatus> getComponentRes =
3887 fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3889 ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3890 componentId = componentMetadataDataDefinition.getUniqueId();
3891 String componentName = componentMetadataDataDefinition.getName();
3893 if (!componentMetadataDataDefinition
3895 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3896 component = checkoutParentComponent(componentType, componentId, userId);
3897 if (component != null) {
3898 componentId = component.getUniqueId();
3899 componentName = component.getName();
3902 resourceCommonInfo.setResourceName(componentName);
3904 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo,
3905 origMd5, data, null, null, null, null);
3906 return actionResult.left().value();
3910 * upload an artifact to a resource instance by UUID
3914 * @param componentType
3915 * @param componentUuid
3916 * @param resourceInstanceName
3920 public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
3921 ArtifactOperationInfo operation) {
3922 Either<ArtifactDefinition, Operation> actionResult;
3923 Component component = null;
3924 String componentInstanceId;
3926 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3927 String userId = request.getHeader(Constants.USER_ID_HEADER);
3929 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3931 Either<ComponentMetadataData, ActionStatus> getComponentRes =
3932 fetchLatestComponentMetadataOrThrow(componentType, componentUuid, resourceInstanceName);
3933 if (!getComponentRes.left()
3935 .getMetadataDataDefinition()
3937 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3938 component = checkoutParentComponent(componentType, getComponentRes.left()
3940 .getMetadataDataDefinition()
3941 .getUniqueId(), userId);
3943 if (component == null) {
3944 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3947 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3949 componentInstanceId = componentRiPair.getRight().getUniqueId();
3950 componentId = componentRiPair.getLeft().getUniqueId();
3951 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3953 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE,
3954 operation, null, artifactInfo, origMd5, data, null, null,
3955 componentId, ComponentTypeEnum.findParamByType(componentType));
3957 return actionResult.left().value();
3961 * updates an artifact on a component by UUID
3965 * @param componentType
3966 * @param componentUuid
3967 * @param artifactUUID
3968 * @param resourceCommonInfo
3969 * @param operation TODO
3972 public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
3973 ResourceCommonInfo resourceCommonInfo, ArtifactOperationInfo operation) {
3974 Either<ArtifactDefinition, Operation> actionResult;
3975 Component component;
3978 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3979 String origMd5 = request.getHeader(Constants.MD5_HEADER);
3980 String userId = request.getHeader(Constants.USER_ID_HEADER);
3982 Either<ComponentMetadataData, ActionStatus> getComponentRes =
3983 fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3984 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3985 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3987 if (!getComponentRes.left()
3989 .getMetadataDataDefinition()
3991 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3992 component = checkoutParentComponent(componentType, componentId, userId);
3993 if (component != null) {
3994 componentId = component.getUniqueId();
3995 componentName = component.getName();
3998 resourceCommonInfo.setResourceName(componentName);
3999 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
4000 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo,
4001 origMd5, data, null, null, null, null);
4002 if (actionResult.isRight()) {
4003 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult
4008 return actionResult.left().value();
4012 * updates an artifact on a resource instance by UUID
4016 * @param componentType
4017 * @param componentUuid
4018 * @param resourceInstanceName
4019 * @param artifactUUID
4020 * @param operation TODO
4023 public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, String artifactUUID,
4024 ArtifactOperationInfo operation) {
4026 Either<ArtifactDefinition, Operation> actionResult;
4027 Component component = null;
4028 String componentInstanceId;
4031 String origMd5 = request.getHeader(Constants.MD5_HEADER);
4032 String userId = request.getHeader(Constants.USER_ID_HEADER);
4034 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
4035 Either<ComponentMetadataData, ActionStatus> getComponentRes =
4036 fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
4037 if (!getComponentRes.left()
4039 .getMetadataDataDefinition()
4041 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4042 component = checkoutParentComponent(componentType, getComponentRes.left()
4044 .getMetadataDataDefinition()
4045 .getUniqueId(), userId);
4047 if (component == null) {
4048 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
4051 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
4053 componentInstanceId = componentRiPair.getRight().getUniqueId();
4054 componentId = componentRiPair.getLeft().getUniqueId();
4055 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
4056 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
4058 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo, origMd5, data, null, null, componentId, ComponentTypeEnum
4059 .findParamByType(componentType));
4060 return actionResult.left().value();
4063 private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid, ArtifactDefinition artifactInfo){
4064 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
4065 if (componentStorageOperationStatusEither.isRight()) {
4066 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
4067 log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
4068 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
4070 Component storedComponent = componentStorageOperationStatusEither.left().value();
4072 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
4073 if(!optionalInterface.isPresent()) {
4074 log.debug("Failed to get resource interface for resource Id {}", componentId);
4075 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
4078 //fetch the operation from storage
4079 InterfaceDefinition gotInterface = optionalInterface.get();
4080 Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
4081 Optional<Operation> optionalOperation = operationsMap.values()
4083 .filter(o -> o.getUniqueId().equals(operationUuid))
4085 if (!optionalOperation.isPresent()) {
4086 log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
4087 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
4088 return Either.right(responseFormat);
4091 Operation operation = optionalOperation.get();
4092 ArtifactDefinition implementationArtifact = operation.getImplementationArtifact();
4093 implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
4094 implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
4095 implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
4096 implementationArtifact.setDescription(artifactInfo.getDescription());
4097 implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
4098 implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
4099 implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
4100 implementationArtifact.setEsId(artifactInfo.getEsId());
4101 operation.setImplementation(implementationArtifact);
4102 gotInterface.setOperationsMap(operationsMap);
4103 Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither =
4104 interfaceOperation.updateInterfaces(storedComponent.getUniqueId(), Collections.singletonList(gotInterface));
4105 if (interfaceDefinitionStorageOperationStatusEither.isRight()){
4106 StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
4107 ActionStatus actionStatus =
4108 componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
4109 return Either.right(componentsUtils.getResponseFormat(actionStatus));
4112 return Either.left(artifactInfo);
4116 * updates an artifact on a component by UUID
4120 * @param componentType
4121 * @param componentUuid
4122 * @param artifactUUID
4126 public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(
4127 String data, HttpServletRequest request, ComponentTypeEnum componentType,
4128 String componentUuid, String interfaceUUID, String operationUUID, String artifactUUID,
4129 ResourceCommonInfo resourceCommonInfo,ArtifactOperationInfo operation) {
4130 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4131 Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
4132 String componentId = null;
4133 ArtifactDefinition existingArtifactInfo = null;
4134 String interfaceName = null;
4136 ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
4137 String origMd5 = request.getHeader(Constants.MD5_HEADER);
4138 String userId = request.getHeader(Constants.USER_ID_HEADER);
4140 Either<ComponentMetadataData, ActionStatus> getComponentRes =
4141 fetchLatestComponentMetadata(componentType, componentUuid)
4142 .right().map(as -> {
4143 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(as));
4147 if (errorWrapper.isEmpty()) {
4148 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
4149 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
4150 if (!getComponentRes.left()
4152 .getMetadataDataDefinition()
4154 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4155 Component component = checkoutParentComponent(componentType, componentId, userId);
4156 if (component != null) {
4157 componentId = component.getUniqueId();
4158 componentName = component.getName();
4162 resourceCommonInfo.setResourceName(componentName);
4165 if(errorWrapper.isEmpty()){
4166 Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
4167 if (interfaceNameEither.isRight()) {
4168 errorWrapper.setInnerElement(interfaceNameEither.right().value());
4171 interfaceName = interfaceNameEither.left().value();
4174 if(errorWrapper.isEmpty()){
4175 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
4176 if (toscaComponentEither.isRight()) {
4177 StorageOperationStatus status = toscaComponentEither.right().value();
4178 log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
4179 errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
4182 if (errorWrapper.isEmpty()) {
4183 NodeTypeEnum parentType = convertParentType(componentType);
4184 final List<ArtifactDefinition> existingDeploymentArtifacts =
4185 getDeploymentArtifacts(toscaComponentEither.left().value(),null);
4186 for (ArtifactDefinition artifactDefinition: existingDeploymentArtifacts){
4187 if(artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())){
4188 existingArtifactInfo = artifactDefinition;
4192 if(existingArtifactInfo != null){
4193 return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
4199 if (errorWrapper.isEmpty()) {
4200 updateArtifactResult = handleArtifactRequestAndFlatten(componentId, userId, componentType, operation,
4201 artifactUUID, artifactInfo, origMd5, data, interfaceName, operationUUID);
4203 updateArtifactResult = Either.right(errorWrapper.getInnerElement());
4206 return updateArtifactResult;
4209 private Either<ArtifactDefinition, ResponseFormat> handleArtifactRequestAndFlatten(
4210 String componentId, String userId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
4211 String artifactId, ArtifactDefinition artifactInfo, String origMd5, String originData, String interfaceName,
4212 String operationName) {
4214 return handleArtifactRequest(componentId, userId, componentType, operation,
4215 artifactId, artifactInfo, origMd5, originData, interfaceName,
4216 operationName, null, null)
4217 .right().map(op -> {
4218 log.debug("Unexpected value returned while calling handleArtifactRequest: {}", op);
4219 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
4221 } catch (ComponentException e) {
4222 return Either.right(e.getResponseFormat());
4226 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(
4227 ComponentTypeEnum componentType, String componentUuid
4229 return fetchLatestComponentMetadataOrThrow(componentType, componentUuid, componentUuid);
4232 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(
4233 ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName
4235 return fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
4236 throw new ByActionStatusComponentException(as, resourceInstanceName);
4240 private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadata(
4241 ComponentTypeEnum componentType, String componentUuid
4243 return toscaOperationFacade
4244 .getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true)
4245 .right().map(sos -> {
4246 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, sos);
4247 return componentsUtils.convertFromStorageResponse(sos, componentType);
4251 private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
4252 Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
4253 if (componentStorageOperationStatusEither.isRight()) {
4254 StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
4255 log.debug("Failed to fetch component information by component id, error {}", errorStatus);
4256 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
4258 Component storedComponent = componentStorageOperationStatusEither.left().value();
4260 Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
4261 .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
4262 if(!optionalInterface.isPresent()) {
4263 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
4265 return Either.left(optionalInterface.get().getType());
4269 * deletes an artifact on a component by UUID
4272 * @param componentType
4273 * @param componentUuid
4274 * @param artifactUUID
4275 * @param resourceCommonInfo
4276 * @param operation TODO
4279 public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
4280 ArtifactOperationInfo operation) {
4282 Either<ArtifactDefinition, Operation> actionResult;
4283 Component component;
4284 String componentId ;
4286 String origMd5 = request.getHeader(Constants.MD5_HEADER);
4287 String userId = request.getHeader(Constants.USER_ID_HEADER);
4289 Either<ComponentMetadataData, ActionStatus> getComponentRes =
4290 fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
4291 componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
4292 String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
4293 if (!getComponentRes.left()
4295 .getMetadataDataDefinition()
4297 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4298 component = checkoutParentComponent(componentType, componentId, userId);
4299 if (component != null) {
4300 componentId = component.getUniqueId();
4301 componentName = component.getName();
4304 resourceCommonInfo.setResourceName(componentName);
4305 artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
4306 actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
4307 return actionResult.left().value();
4311 * deletes an artifact from a resource instance by UUID
4314 * @param componentType
4315 * @param componentUuid
4316 * @param resourceInstanceName
4317 * @param artifactUUID
4318 * @param operation TODO
4321 public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType,
4322 String componentUuid, String resourceInstanceName,
4323 String artifactUUID, ArtifactOperationInfo operation) {
4325 Either<ArtifactDefinition, Operation> actionResult;
4326 Component component = null;
4327 String componentInstanceId;
4330 String origMd5 = request.getHeader(Constants.MD5_HEADER);
4331 String userId = request.getHeader(Constants.USER_ID_HEADER);
4332 ImmutablePair<Component, ComponentInstance> componentRiPair = null;
4333 Either<ComponentMetadataData, ActionStatus> getComponentRes =
4334 fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
4335 if (!getComponentRes.left()
4337 .getMetadataDataDefinition()
4339 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4340 component = checkoutParentComponent(componentType, getComponentRes.left()
4342 .getMetadataDataDefinition()
4343 .getUniqueId(), userId);
4345 if (component == null) {
4346 componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
4349 componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
4351 componentInstanceId = componentRiPair.getRight().getUniqueId();
4352 componentId = componentRiPair.getLeft().getUniqueId();
4353 artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
4355 actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5, null, null, null, componentId, ComponentTypeEnum
4356 .findParamByType(componentType));
4357 return actionResult.left().value();
4360 private String findArtifactId(ComponentInstance instance, String artifactUUID) {
4361 String artifactId = null;
4362 ArtifactDefinition foundArtifact = null;
4363 if (instance.getDeploymentArtifacts() != null) {
4364 foundArtifact = instance.getDeploymentArtifacts()
4367 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID()
4368 .equals(artifactUUID))
4372 if (foundArtifact == null && instance.getArtifacts() != null) {
4373 foundArtifact = instance.getArtifacts()
4376 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID()
4377 .equals(artifactUUID))
4381 if (foundArtifact == null) {
4382 log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
4383 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4386 artifactId = foundArtifact.getUniqueId();
4391 @SuppressWarnings("unchecked")
4392 public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact,
4393 String envType, String parentId, NodeTypeEnum parentType,
4394 String parentName, User user, Component component,
4395 Map<String, String> existingEnvVersions) {
4396 Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager()
4398 .getDeploymentResourceInstanceArtifacts();
4399 if (deploymentResourceArtifacts == null) {
4400 log.debug("no deployment artifacts are configured for generated artifacts");
4401 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
4403 Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
4404 if (placeHolderData == null) {
4405 log.debug("no env type {} are configured for generated artifacts", envType);
4406 throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
4409 String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
4410 ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user
4411 .getUserId(), ArtifactGroupTypeEnum.DEPLOYMENT, true);
4412 ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
4413 artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
4414 artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
4415 artifactHeatEnv.setTimeout(0);
4416 artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
4417 buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
4418 // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
4419 handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
4420 ArtifactDefinition heatEnvPlaceholder;
4421 // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
4422 if (parentType != NodeTypeEnum.ResourceInstance) {
4423 String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
4424 artifactHeatEnv.setArtifactChecksum(checkSum);
4425 Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component, parentType, parentId);
4426 if (addHeatEnvArtifact.isRight()) {
4427 log.debug("failed to create heat env artifact on resource instance");
4428 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact
4430 .value(), false), "", null));
4432 heatEnvPlaceholder = createArtifactPlaceHolder;
4435 heatEnvPlaceholder = artifactHeatEnv;
4436 artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
4437 setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
4439 ComponentTypeEnum componentType = component.getComponentType();
4440 if (parentType == NodeTypeEnum.ResourceInstance) {
4441 componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
4443 createdArtifacts.add(heatEnvPlaceholder);
4444 componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
4445 new ResourceCommonInfo(parentName, componentType.getValue()),
4446 ResourceVersionInfo.newBuilder().build(),
4447 ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(),
4448 null, heatEnvPlaceholder, null);
4449 return heatEnvPlaceholder;
4452 private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
4453 if (artifact.getListHeatParameters() == null) {
4456 List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
4457 for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
4458 HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
4459 heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
4460 heatEnvParameter.setCurrentValue(null);
4461 heatEnvParameters.add(heatEnvParameter);
4463 artifactDefinition.setListHeatParameters(heatEnvParameters);
4466 private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
4467 String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
4468 String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
4469 String name = heatArtifact.getArtifactName();
4472 name = heatArtifact.getArtifactLabel();
4473 fileName = name + "." + envExtension;
4476 fileName = name.replaceAll("." + heatExtension, "." + envExtension);
4478 heatEnvArtifact.setArtifactName(fileName);
4481 private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
4482 if (null != existingEnvVersions) {
4483 String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
4484 if (null != prevVersion) {
4485 heatEnvArtifact.setArtifactVersion(prevVersion);
4490 public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4491 ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4492 ComponentTypeEnum componentType = component.getComponentType();
4493 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4494 Either<ArtifactDefinition, Operation> result;
4496 for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4497 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4498 uploadedArtifacts.add(result.left().value());
4500 } catch (ComponentException e) {
4501 log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component
4502 .getName(), e.getResponseFormat());
4503 if (operation.isCreateOrLink()) {
4504 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4508 return uploadedArtifacts;
4511 public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Component component, User user, ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction,
4512 ComponentTypeEnum componentType, ArtifactDefinition artifactDefinition) {
4513 AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4514 String componentId = component.getUniqueId();
4515 String artifactId = artifactDefinition.getUniqueId();
4516 Either<ArtifactDefinition, Operation> result;
4517 Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4518 //artifact validation
4519 artifactDefinition = validateArtifact(componentId, componentType, operation,
4520 artifactId, artifactDefinition, auditingAction, user,
4521 component, shouldLock, inTransaction);
4522 switch (operation.getArtifactOperationEnum()) {
4524 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component, null, null);
4525 result = createArtifact(component, componentId, artifactDefinition, validPayload,
4526 componentType, auditingAction, null, null);
4529 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component, null, null);
4530 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4531 auditingAction, user, component, true);
4534 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4537 if (artifactGenerationRequired(component, artifactDefinition)) {
4538 result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4540 result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4544 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4547 throw new UnsupportedOperationException("In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4552 public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4553 ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4555 List<ArtifactDefinition> handleArtifactsResult;
4556 ComponentTypeEnum componentType = component.getComponentType();
4557 List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4558 Either<ArtifactDefinition, Operation> actionResult;
4562 for (ArtifactDefinition artifact : artifactsToHandle) {
4563 originData = ArtifactUtils.buildJsonStringForCsarVfcArtifact(artifact);
4564 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4565 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact
4566 .getUniqueId(), artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4567 uploadedArtifacts.add(actionResult.left().value());
4569 handleArtifactsResult = uploadedArtifacts;
4570 }catch (ComponentException e){
4571 if (operation.isCreateOrLink()) {
4572 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4576 return handleArtifactsResult;
4579 private ComponentInstance getRelatedComponentInstance(
4580 ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName
4582 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4583 Option<Component> oComponent = Option.of(getComponentByUuid(componentType, componentUuid));
4585 .toTry(componentNotFound(componentType, componentUuid))
4586 .flatMap(component -> findFirstMatching(component,
4587 ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName)
4588 ).toTry(componentInstanceNotFound(componentType, resourceInstanceName, component))
4592 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(
4593 Component component, String resourceInstanceName
4595 String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4596 ComponentInstance componentInstance = findFirstMatching(component,
4597 ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName)
4598 ).toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4599 return new ImmutablePair<>(component, componentInstance);
4602 private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(
4603 ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName
4605 Component component = getLatestComponentByUuid(componentType, componentUuid);
4606 ComponentInstance componentInstance = findFirstMatching(component,
4607 ci -> ci.getNormalizedName().equals(resourceInstanceName)
4608 ).toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4609 return new ImmutablePair<>(component, componentInstance);
4612 private Supplier<Throwable> componentNotFound(ComponentTypeEnum componentType, String componentUuid) {
4614 log.debug(FAILED_FETCH_COMPONENT, componentType.getValue(), componentUuid);
4615 return new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentUuid);
4619 private Supplier<Throwable> componentInstanceNotFound(
4620 ComponentTypeEnum componentType, String resourceInstanceName, Component component
4623 log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4624 return new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
4625 resourceInstanceName,
4626 RESOURCE_INSTANCE, componentType.getValue(), component.getName());
4630 private static Option<ComponentInstance> findFirstMatching(Component component, Predicate<ComponentInstance> filter) {
4631 return Option.ofOptional(component.getComponentInstances()
4637 private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4639 ImmutablePair<String, byte[]> downloadArtifact;
4640 List<ArtifactDefinition> artifactsList = null;
4641 ArtifactDefinition deploymentArtifact;
4642 if (artifacts != null && !artifacts.isEmpty()) {
4643 artifactsList = artifacts.values()
4645 .filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID()
4646 .equals(artifactUUID))
4647 .collect(Collectors.toList());
4649 if (artifactsList == null || artifactsList.isEmpty()) {
4650 log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4651 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4653 deploymentArtifact = artifactsList.get(0);
4654 downloadArtifact = downloadArtifact(deploymentArtifact);
4655 log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4656 return downloadArtifact.getRight();
4659 private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4660 Component component;
4661 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4662 if (getComponentRes.isRight()) {
4663 StorageOperationStatus status = getComponentRes.right().value();
4664 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4665 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4668 component = getComponentRes.left().value();
4673 private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4674 Component component;
4675 Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4676 if (getComponentRes.isRight()) {
4677 StorageOperationStatus status = getComponentRes.right().value();
4678 log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4679 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4682 List<Component> value = getComponentRes.left().value();
4683 if (value.isEmpty()) {
4684 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4685 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4686 throw new ByActionStatusComponentException(status);
4689 component = value.get(0);
4695 private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4696 ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4697 StorageOperationStatus storageStatus;
4698 ArtifactDefinition latestArtifact;
4699 List<ArtifactDefinition> artifacts;
4700 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4701 if (getArtifactsRes.isRight()) {
4702 storageStatus = getArtifactsRes.right().value();
4703 log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4704 if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4705 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4707 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4709 artifacts = getArtifactsRes.left()
4713 .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID()
4714 .equals(artifactUUID))
4715 .collect(Collectors.toList());
4716 if (artifacts == null || artifacts.isEmpty()) {
4717 log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType, parentId, actionStatus);
4718 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4720 latestArtifact = artifacts.stream().max((a1, a2) -> {
4721 int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4722 if (compareRes == 0) {
4723 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(), a2.getLastUpdateDate() == null ? 0 : a2
4724 .getLastUpdateDate());
4728 if (latestArtifact == null) {
4729 log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType, parentId, actionStatus);
4730 throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4732 return latestArtifact.getUniqueId();
4735 private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4737 Component component = null;
4738 User modifier = userBusinessLogic.getUser(userId, false);
4739 LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout", LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4740 Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic.changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4741 if (checkoutRes.isRight()) {
4742 log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType
4743 .getNodeType(), parentId, checkoutRes.right().value().getStatus());
4744 throw new ByResponseFormatComponentException(checkoutRes.right().value());
4746 return checkoutRes.left().value();
4750 void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4751 this.nodeTemplateOperation = nodeTemplateOperation;
4754 public List<ArtifactConfiguration> getConfiguration() {
4755 return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();