Interface is formatted using extended notation when no implementation added at VFC...
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ArtifactsBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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  * ================================================================================
21  */
22 package org.openecomp.sdc.be.components.impl;
23
24 import static org.openecomp.sdc.be.dao.api.ActionStatus.MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE;
25
26 import com.google.common.annotations.VisibleForTesting;
27 import com.google.gson.Gson;
28 import com.google.gson.GsonBuilder;
29 import fj.data.Either;
30 import io.vavr.control.Option;
31 import java.math.BigDecimal;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.Comparator;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Map.Entry;
40 import java.util.Objects;
41 import java.util.Optional;
42 import java.util.Set;
43 import java.util.function.Consumer;
44 import java.util.function.Function;
45 import java.util.function.Predicate;
46 import java.util.function.Supplier;
47 import java.util.stream.Collectors;
48 import javax.servlet.http.HttpServletRequest;
49 import org.apache.commons.codec.binary.Base64;
50 import org.apache.commons.collections.CollectionUtils;
51 import org.apache.commons.collections.MapUtils;
52 import org.apache.commons.io.FilenameUtils;
53 import org.apache.commons.lang3.ArrayUtils;
54 import org.apache.commons.lang3.StringUtils;
55 import org.apache.commons.lang3.tuple.ImmutablePair;
56 import org.openecomp.sdc.be.components.ArtifactsResolver;
57 import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum;
58 import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo;
59 import org.openecomp.sdc.be.components.impl.artifact.ArtifactTypeToPayloadTypeSelector;
60 import org.openecomp.sdc.be.components.impl.artifact.PayloadTypeEnum;
61 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
62 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
63 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
64 import org.openecomp.sdc.be.components.impl.utils.ComponentUtils;
65 import org.openecomp.sdc.be.components.impl.validation.PMDictionaryValidator;
66 import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
67 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
68 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum;
69 import org.openecomp.sdc.be.components.utils.ArtifactUtils;
70 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
71 import org.openecomp.sdc.be.config.ArtifactConfiguration;
72 import org.openecomp.sdc.be.config.BeEcompErrorManager;
73 import org.openecomp.sdc.be.config.Configuration;
74 import org.openecomp.sdc.be.config.Configuration.ArtifactTypeConfig;
75 import org.openecomp.sdc.be.config.ConfigurationManager;
76 import org.openecomp.sdc.be.dao.api.ActionStatus;
77 import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao;
78 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
79 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
80 import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition;
81 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
82 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
83 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
84 import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition;
85 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
86 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
87 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
88 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
89 import org.openecomp.sdc.be.info.ArtifactTemplateInfo;
90 import org.openecomp.sdc.be.model.ArtifactDefinition;
91 import org.openecomp.sdc.be.model.ArtifactTypeDefinition;
92 import org.openecomp.sdc.be.model.Component;
93 import org.openecomp.sdc.be.model.ComponentInstance;
94 import org.openecomp.sdc.be.model.ComponentParametersView;
95 import org.openecomp.sdc.be.model.GroupDefinition;
96 import org.openecomp.sdc.be.model.GroupInstance;
97 import org.openecomp.sdc.be.model.HeatParameterDefinition;
98 import org.openecomp.sdc.be.model.InterfaceDefinition;
99 import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
100 import org.openecomp.sdc.be.model.LifecycleStateEnum;
101 import org.openecomp.sdc.be.model.Operation;
102 import org.openecomp.sdc.be.model.Resource;
103 import org.openecomp.sdc.be.model.Service;
104 import org.openecomp.sdc.be.model.User;
105 import org.openecomp.sdc.be.model.heat.HeatParameterType;
106 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
107 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
108 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeTemplateOperation;
109 import org.openecomp.sdc.be.model.operations.StorageException;
110 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
111 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
112 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
113 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
114 import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation;
115 import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation;
116 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
117 import org.openecomp.sdc.be.model.operations.impl.ArtifactTypeOperation;
118 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
119 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
120 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
121 import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation;
122 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
123 import org.openecomp.sdc.be.resources.data.DAOArtifactData;
124 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
125 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
126 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
127 import org.openecomp.sdc.be.servlets.RepresentationUtils;
128 import org.openecomp.sdc.be.tosca.CsarUtils;
129 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
130 import org.openecomp.sdc.be.user.Role;
131 import org.openecomp.sdc.be.user.UserBusinessLogic;
132 import org.openecomp.sdc.be.utils.TypeUtils;
133 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
134 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
135 import org.openecomp.sdc.common.api.Constants;
136 import org.openecomp.sdc.common.datastructure.Wrapper;
137 import org.openecomp.sdc.common.log.wrappers.Logger;
138 import org.openecomp.sdc.common.util.GeneralUtility;
139 import org.openecomp.sdc.common.util.ValidationUtils;
140 import org.openecomp.sdc.common.util.YamlToObjectConverter;
141 import org.openecomp.sdc.exception.ResponseFormat;
142 import org.springframework.beans.factory.annotation.Autowired;
143 import org.yaml.snakeyaml.Yaml;
144
145 @org.springframework.stereotype.Component("artifactBusinessLogic")
146 public class ArtifactsBusinessLogic extends BaseBusinessLogic {
147
148     public static final String HEAT_ENV_NAME = "heatEnv";
149     public static final String HEAT_VF_ENV_NAME = "VfHeatEnv";
150     public static final String HEAT_ENV_SUFFIX = "env";
151     public static final String ARTIFACT_ACTION_LOCK = "Artifact action - lock ";
152     public static final String FAILED_UPLOAD_ARTIFACT_TO_COMPONENT = "Failed to upload artifact to component with type {} and uuid {}. Status is {}. ";
153     public static final String COMPONENT_INSTANCE_NOT_FOUND = "Component instance {} was not found for component {}";
154     private static final String RESOURCE_INSTANCE = "resource instance";
155     private static final String ARTIFACT_TYPE_OTHER = "OTHER";
156     private static final String ARTIFACT_DESCRIPTION = "artifact description";
157     private static final String ARTIFACT_LABEL = "artifact label";
158     private static final String ARTIFACT_URL = "artifact url";
159     private static final String ARTIFACT_NAME = "artifact name";
160     private static final String ARTIFACT_PAYLOAD = "artifact payload";
161     private static final String ARTIFACT_PLACEHOLDER_TYPE = "type";
162     private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName";
163     private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description";
164     private static final String ARTIFACT_PLACEHOLDER_FILE_EXTENSION = "fileExtension";
165     private static final Logger log = Logger.getLogger(ArtifactsBusinessLogic.class.getName());
166     private static final String FAILED_UPDATE_GROUPS = "Failed to update groups of the component {}. ";
167     private static final String FAILED_SAVE_ARTIFACT = "Failed to save the artifact.";
168     private static final String FAILED_FETCH_COMPONENT = "Could not fetch component with type {} and uuid {}. Status is {}. ";
169     private static final String NULL_PARAMETER = "One of the function parameteres is null";
170     private static final String ROLLBACK = "all changes rollback";
171     private static final String COMMIT = "all changes committed";
172     private static final String UPDATE_ARTIFACT = "Update Artifact";
173     private static final String FOUND_DEPLOYMENT_ARTIFACT = "Found deployment artifact {}";
174     private static final String VALID_ARTIFACT_LABEL_NAME = "'A-Z', 'a-z', '0-9', '-', '@', '+' and space.";
175     private final ArtifactTypeOperation artifactTypeOperation;
176     private Gson gson = new GsonBuilder().setPrettyPrinting().create();
177     @javax.annotation.Resource
178     private IInterfaceLifecycleOperation interfaceLifecycleOperation;
179     @javax.annotation.Resource
180     private UserAdminOperation userOperaton;
181     @javax.annotation.Resource
182     private IElementOperation elementOperation;
183     @javax.annotation.Resource
184     private IHeatParametersOperation heatParametersOperation;
185     private ArtifactCassandraDao artifactCassandraDao;
186     private ToscaExportHandler toscaExportUtils;
187     private CsarUtils csarUtils;
188     private LifecycleBusinessLogic lifecycleBusinessLogic;
189     private UserBusinessLogic userBusinessLogic;
190     private ArtifactsResolver artifactsResolver;
191     private NodeTemplateOperation nodeTemplateOperation;
192
193     @Autowired
194     public ArtifactsBusinessLogic(ArtifactCassandraDao artifactCassandraDao, ToscaExportHandler toscaExportUtils, CsarUtils csarUtils,
195                                   LifecycleBusinessLogic lifecycleBusinessLogic, UserBusinessLogic userBusinessLogic,
196                                   ArtifactsResolver artifactsResolver, IElementOperation elementDao, IGroupOperation groupOperation,
197                                   IGroupInstanceOperation groupInstanceOperation, IGroupTypeOperation groupTypeOperation,
198                                   InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation,
199                                   ArtifactsOperations artifactToscaOperation,
200                                   ArtifactTypeOperation artifactTypeOperation) {
201         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation,
202             artifactToscaOperation);
203         this.artifactCassandraDao = artifactCassandraDao;
204         this.toscaExportUtils = toscaExportUtils;
205         this.csarUtils = csarUtils;
206         this.lifecycleBusinessLogic = lifecycleBusinessLogic;
207         this.userBusinessLogic = userBusinessLogic;
208         this.artifactsResolver = artifactsResolver;
209         this.artifactTypeOperation = artifactTypeOperation;
210     }
211
212     public static <R> Either<Boolean, R> ifTrue(boolean predicate, Supplier<Either<Boolean, R>> ifTrue) {
213         return predicate ? ifTrue.get() : Either.left(false);
214     }
215
216     public static <L, R> Either<L, R> forEach(Either<L, R> e, Consumer<L> c) {
217         return e.left().map(l -> {
218             c.accept(l);
219             return l;
220         });
221     }
222
223     private static Option<ComponentInstance> findFirstMatching(Component component, Predicate<ComponentInstance> filter) {
224         return Option.ofOptional(component.getComponentInstances().stream().filter(filter).findFirst());
225     }
226
227     // new flow US556184
228     public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
229                                                                        ArtifactOperationInfo operation, String artifactId,
230                                                                        ArtifactDefinition artifactInfo, String origMd5, String originData,
231                                                                        String interfaceName, String operationName, String parentId,
232                                                                        String containerComponentType, boolean shouldLock, boolean inTransaction) {
233         // step 1 - detect auditing type
234         AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
235         // step 2 - check header
236         if (userId == null) {
237             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION);
238             log.debug("handleArtifactRequest - no HTTP_CSP_HEADER , component id {}", componentId);
239             handleAuditing(auditingAction, null, componentId, null, null, null, artifactId, responseFormat, componentType, null);
240             throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
241         }
242         // step 3 - check user existence
243
244         // step 4 - check user's role
245         User user = validateUserExists(userId, auditingAction, componentId, artifactId, componentType, inTransaction);
246         validateUserRole(user, auditingAction, componentId, artifactId, componentType, operation);
247         // steps 5 - 6 - 7
248
249         // 5. check service/resource existence
250
251         // 6. check service/resource check out
252
253         // 7. user is owner of checkout state
254         Component component = null;
255         String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
256         component = validateComponentExists(realComponentId, auditingAction, user, artifactId, componentType, containerComponentType);
257         validateWorkOnComponent(component, userId, auditingAction, user, artifactId, operation);
258         if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
259             validateResourceInstanceById(component, componentId);
260         }
261         // step 8
262         return validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
263             operationName, user, component, shouldLock, inTransaction, true);
264     }
265
266     public Either<ArtifactDefinition, Operation> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType,
267                                                                        ArtifactOperationInfo operation, String artifactId,
268                                                                        ArtifactDefinition artifactInfo, String origMd5, String originData,
269                                                                        String interfaceName, String operationName, String parentId,
270                                                                        String containerComponentType) {
271         return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
272             operationName, parentId, containerComponentType, true, false);
273     }
274
275     /**
276      * This Method validates only the Artifact and does not validate user / role / component ect...<br> For regular usage use <br> {@link
277      * #handleArtifactRequest(String, String, ComponentTypeEnum, ArtifactOperationInfo, String, ArtifactDefinition, String, String, String, String,
278      * String, String)}
279      *
280      * @return
281      */
282     public Either<ArtifactDefinition, Operation> validateAndHandleArtifact(String componentUniqueId, ComponentTypeEnum componentType,
283                                                                            ArtifactOperationInfo operation, String artifactUniqueId,
284                                                                            ArtifactDefinition artifactDefinition, String origMd5, String originData,
285                                                                            String interfaceName, String operationName, User user, Component component,
286                                                                            boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
287         AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5);
288         artifactDefinition = validateArtifact(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, auditingAction, user,
289             component, shouldLock, inTransaction);
290         // step 10
291         Either<ArtifactDefinition, Operation> result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition,
292             origMd5, originData, interfaceName, operationName, auditingAction, user, component, shouldLock, inTransaction, needUpdateGroup);
293         //TODO: audit positive action
294         return result;
295     }
296
297     @VisibleForTesting
298     ArtifactDefinition validateArtifact(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation, String artifactId,
299                                         ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, User user, Component component,
300                                         boolean shouldLock, boolean inTransaction) {
301         ArtifactDefinition artifactInfoToReturn = artifactInfo;
302         ArtifactOperationEnum operationEnum = operation.getArtifactOperationEnum();
303         if (operationEnum == ArtifactOperationEnum.UPDATE || operationEnum == ArtifactOperationEnum.DELETE
304             || operationEnum == ArtifactOperationEnum.DOWNLOAD) {
305             ArtifactDefinition dbArtifact = getArtifactIfBelongsToComponent(componentId, componentType, artifactId, component);
306             if (operation.isDownload()) {
307                 artifactInfoToReturn = dbArtifact;
308                 handleHeatEnvDownload(componentId, componentType, user, component, dbArtifact, shouldLock, inTransaction);
309             }
310         }
311         return artifactInfoToReturn;
312     }
313
314     @VisibleForTesting
315     void handleHeatEnvDownload(String componentId, ComponentTypeEnum componentType, User user, Component component,
316                                ArtifactDefinition artifactDefinition, boolean shouldLock, boolean inTransaction) {
317         if (artifactDefinition.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType()) && ComponentTypeEnum.SERVICE == component
318             .getComponentType()) {
319             ComponentInstance componentInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId))
320                 .findAny().orElse(null);
321             if (componentInstance == null) {
322                 throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentId, "instance", "Service",
323                     component.getName());
324             }
325             Map<String, ArtifactDefinition> deploymentArtifacts = componentInstance.getDeploymentArtifacts();
326             ArtifactDefinition heatEnvWithHeatParams = deploymentArtifacts.values().stream()
327                 .filter(p -> p.getUniqueId().equals(artifactDefinition.getUniqueId())).findAny().orElse(null);
328             Either<ArtifactDefinition, ResponseFormat> eitherGenerated = generateHeatEnvArtifact(heatEnvWithHeatParams, componentType, component,
329                 componentInstance.getName(), user, componentId, shouldLock, inTransaction);
330             if (eitherGenerated.isRight()) {
331                 throw new ByResponseFormatComponentException((eitherGenerated.right().value()));
332             }
333         }
334     }
335
336     private boolean artifactGenerationRequired(Component component, ArtifactDefinition artifactInfo) {
337         boolean needGenerate;
338         needGenerate = artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && (
339             component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN
340                 || component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
341         needGenerate = needGenerate || (ComponentTypeEnum.RESOURCE == component.getComponentType() && (
342             artifactInfo.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType()) || isAbstractVfcEmptyCsar((Resource) component,
343                 artifactInfo)));
344         return needGenerate;
345     }
346
347     private boolean isAbstractVfcEmptyCsar(Resource resource, ArtifactDefinition artifactInfo) {
348         return resource.isAbstract() && artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && artifactInfo.getArtifactType()
349             .equals(ArtifactTypeEnum.TOSCA_CSAR.getType()) && StringUtils.isEmpty(artifactInfo.getArtifactChecksum());
350     }
351
352     public Either<ArtifactDefinition, Operation> generateAndSaveToscaArtifact(ArtifactDefinition artifactDefinition, Component component, User user,
353                                                                               boolean isInCertificationRequest, boolean shouldLock,
354                                                                               boolean inTransaction, boolean fetchTemplatesFromDB) {
355         return decodeToscaArtifactPayload(component, isInCertificationRequest, fetchTemplatesFromDB, artifactDefinition.getArtifactType()).left()
356             .bind(payload -> {
357                 // TODO: Avoid output argument
358                 artifactDefinition.setPayload(payload);
359                 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
360                 artifactDefinition.setArtifactChecksum(GeneralUtility.calculateMD5Base64EncodedByByteArray(payload));
361                 return lockComponentAndUpdateArtifact(component.getUniqueId(), artifactDefinition, AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE,
362                     artifactDefinition.getUniqueId(), user, component.getComponentType(), component, payload, shouldLock, inTransaction);
363             }).right().map(ex -> {
364                 // TODO: This should not be done but in order to keep this refactoring small enough, we stop here.
365
366                 // Bubble up this exception
367                 throw ex;
368             });
369     }
370
371     private Either<byte[], ComponentException> decodeToscaArtifactPayload(Component parent, boolean isInCertificationRequest,
372                                                                           boolean fetchTemplatesFromDB, String artifactType) {
373         log.debug("tosca artifact generation");
374         if (ArtifactTypeEnum.TOSCA_CSAR.getType().equals(artifactType)) {
375             return csarUtils.createCsar(parent, fetchTemplatesFromDB, isInCertificationRequest).right().map(error -> {
376                 log.debug("Failed to generate tosca csar for component {} error {}", parent.getUniqueId(), error);
377                 return new ByResponseFormatComponentException(error);
378             });
379         } else {
380             return toscaExportUtils.exportComponent(parent).left().map(toscaRepresentation -> {
381                 log.debug("Tosca yaml exported for component {} ", parent.getUniqueId());
382                 return toscaRepresentation.getMainYaml();
383             }).right().map(toscaError -> {
384                 log.debug("Failed export tosca yaml for component {} error {}", parent.getUniqueId(), toscaError);
385                 return new ByActionStatusComponentException(componentsUtils.convertFromToscaError(toscaError));
386             });
387         }
388     }
389
390     private Either<ArtifactDefinition, Operation> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
391                                                            String artifactId, ArtifactDefinition artifactInfo, String origMd5, String originData,
392                                                            String interfaceName, String operationName, AuditingActionEnum auditingAction, User user,
393                                                            Component parent, boolean shouldLock, boolean inTransaction, boolean needUpdateGroup) {
394         if (interfaceName != null && operationName != null) {
395             interfaceName = interfaceName.toLowerCase();
396             operationName = operationName.toLowerCase();
397         }
398         if (shouldLock) {
399             lockComponent(componentType, artifactId, auditingAction, user, parent);
400         }
401         Either<ArtifactDefinition, Operation> result;
402         boolean operationSucceeded = false;
403         try {
404             switch (operation.getArtifactOperationEnum()) {
405                 case DOWNLOAD:
406                     if (artifactGenerationRequired(parent, artifactInfo)) {
407                         result = Either.left(generateNotSavedArtifact(parent, artifactInfo));
408                     } else {
409                         result = Either.left(handleDownload(componentId, artifactId, componentType, parent));
410                     }
411                     break;
412                 case DELETE:
413                     result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, parent));
414                     break;
415                 case UPDATE:
416                     result = handleUpdate(componentId, componentType, operation, artifactId, artifactInfo, null, origMd5, originData, interfaceName,
417                         operationName, auditingAction, user, parent, needUpdateGroup);
418                     break;
419                 case CREATE:
420                     result = handleCreate(componentId, artifactInfo, operation, auditingAction, user, componentType, parent, origMd5, originData,
421                         interfaceName, operationName);
422                     break;
423                 case LINK:
424                     result = Either.left(handleLink(componentId, artifactInfo, componentType, parent));
425                     break;
426                 default:
427                     throw new UnsupportedOperationException(
428                         "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
429             }
430             operationSucceeded = true;
431             return result;
432         } finally {
433             handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
434         }
435     }
436
437     private void lockComponent(ComponentTypeEnum componentType, String artifactId, AuditingActionEnum auditingAction, User user, Component parent) {
438         try {
439             lockComponent(parent, ARTIFACT_ACTION_LOCK);
440         } catch (ComponentException e) {
441             handleAuditing(auditingAction, parent, parent.getUniqueId(), user, null, null, artifactId, e.getResponseFormat(), componentType, null);
442             throw e;
443         }
444     }
445
446     @VisibleForTesting
447     public Either<ArtifactDefinition, Operation> handleUpdate(String componentId, ComponentTypeEnum componentType, ArtifactOperationInfo operation,
448                                                               String artifactId, ArtifactDefinition artifactInfo, byte[] decodedPayload,
449                                                               String origMd5, String originData, String interfaceName, String operationName,
450                                                               AuditingActionEnum auditingAction, User user, Component parent,
451                                                               boolean needUpdateGroup) {
452         Either<ArtifactDefinition, Operation> result;
453         validateArtifactType(artifactInfo);
454         final String artifactType = artifactInfo.getArtifactType();
455         if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && (ArtifactTypeEnum.HEAT.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_VOL
456             .getType().equals(artifactType) || ArtifactTypeEnum.HEAT_NET.getType().equals(artifactType) || ArtifactTypeEnum.HEAT_ENV.getType()
457             .equals(artifactType))) {
458             result = handleUpdateHeatEnvAndHeatMeta(componentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, originData,
459                 origMd5, operation);
460             if (needUpdateGroup) {
461                 ActionStatus error = updateGroupInstance(artifactInfo, result.left().value(), parent, componentId);
462                 if (error != ActionStatus.OK) {
463                     throw new ByActionStatusComponentException(error);
464                 }
465             }
466         } else if (componentType == ComponentTypeEnum.RESOURCE && ArtifactTypeEnum.HEAT_ENV.getType().equals(artifactType)) {
467             result = handleUpdateHeatWithHeatEnvParams(componentId, artifactInfo, auditingAction, componentType, parent, originData, origMd5,
468                 operation, needUpdateGroup);
469         } else {
470             if (decodedPayload == null) {
471                 decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5,
472                     originData, interfaceName, operationName);
473             }
474             result = updateArtifactFlow(parent, componentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
475             if (needUpdateGroup && result.isLeft()) {
476                 ArtifactDefinition updatedArtifact = result.left().value();
477                 updateGroupForHeat(artifactInfo, updatedArtifact, parent);
478             }
479         }
480         return result;
481     }
482
483     private void validateArtifactType(final ArtifactDefinition artifactInfo) {
484         if (!isArtifactSupported(artifactInfo.getArtifactType())) {
485             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
486         }
487     }
488
489     private void validateArtifactType(final ArtifactDefinition artifactInfo, final ComponentTypeEnum componentType) {
490         final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactInfo.getArtifactType()).orElse(null);
491         if (artifactConfiguration == null) {
492             BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
493             log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName());
494             final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE);
495             throw new ByResponseFormatComponentException(responseFormat);
496         }
497         final ArtifactGroupTypeEnum artifactGroupType = artifactInfo.getArtifactGroupType();
498         try {
499             validateArtifactType(componentType, artifactGroupType, artifactConfiguration);
500         } catch (final ComponentException e) {
501             log.debug("Artifact is invalid", e);
502             BeEcompErrorManager.getInstance()
503                 .logBeInvalidTypeError("Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(),
504                     "Artifact " + artifactInfo.getArtifactName());
505             log.debug("Not supported artifact type = {}", artifactInfo.getArtifactType());
506             final ResponseFormat responseFormat = componentsUtils
507                 .getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
508             throw new ByResponseFormatComponentException(responseFormat);
509         }
510     }
511
512     private void validateArtifactType(final ComponentTypeEnum componentType, final ArtifactGroupTypeEnum groupType,
513                                       final ArtifactConfiguration artifactConfiguration) {
514         final boolean supportComponentType =
515             CollectionUtils.isNotEmpty(artifactConfiguration.getComponentTypes()) && artifactConfiguration.getComponentTypes().stream()
516                 .anyMatch(componentType1 -> componentType1.getValue().equalsIgnoreCase(componentType.getValue()));
517         if (!supportComponentType) {
518             log.debug("Artifact Type '{}' not supported for Component Type '{}'", artifactConfiguration.getType(), componentType.getValue());
519             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
520         }
521         final boolean supportResourceType = artifactConfiguration.hasSupport(groupType);
522         if (!supportResourceType) {
523             log.debug("Artifact Type '{}' not supported for Component Type '{}' and Category '{}'", artifactConfiguration.getType(),
524                 componentType.getValue(), groupType.getType());
525             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactConfiguration.getType());
526         }
527     }
528
529     private boolean isArtifactSupported(final String artifactType) {
530         final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
531         final List<ArtifactConfiguration> artifactConfigurationList = configuration.getArtifacts();
532         if (CollectionUtils.isEmpty(artifactConfigurationList)) {
533             return false;
534         }
535         return artifactConfigurationList.stream().anyMatch(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType));
536     }
537
538     @VisibleForTesting
539     public ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent) {
540         List<GroupDefinition> groups = parent.getGroups();
541         if (groups != null && !groups.isEmpty()) {
542             List<GroupDataDefinition> groupToUpdate = groups.stream()
543                 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfo.getUniqueId())).collect(Collectors.toList());
544             if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
545                 groupToUpdate.forEach(g -> {
546                     g.getArtifacts().remove(artifactInfo.getUniqueId());
547                     g.getArtifactsUuid().remove(artifactInfo.getArtifactUUID());
548                     g.getArtifacts().add(artAfterUpdate.getUniqueId());
549                     g.getArtifactsUuid().add(artAfterUpdate.getArtifactUUID());
550                     if (!artifactInfo.getArtifactUUID().equals(artAfterUpdate.getArtifactUUID())) {
551                         g.setGroupUUID(UniqueIdBuilder.generateUUID());
552                     }
553                 });
554                 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
555                 if (status.isRight()) {
556                     log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
557                     throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status.right().value()));
558                 }
559             }
560         }
561         return ActionStatus.OK;
562     }
563
564     @VisibleForTesting
565     ActionStatus updateGroupForHeat(ArtifactDefinition artifactInfoHeat, ArtifactDefinition artHeatAfterUpdate, ArtifactDefinition artifactInfoHeatE,
566                                     ArtifactDefinition artHEAfterUpdate, Component parent) {
567         List<GroupDefinition> groups = parent.getGroups();
568         if (groups != null && !groups.isEmpty()) {
569             List<GroupDataDefinition> groupToUpdate = groups.stream()
570                 .filter(g -> g.getArtifacts() != null && g.getArtifacts().contains(artifactInfoHeat.getUniqueId())).collect(Collectors.toList());
571             if (groupToUpdate != null && !groupToUpdate.isEmpty()) {
572                 groupToUpdate.forEach(g -> {
573                     g.getArtifacts().remove(artifactInfoHeat.getUniqueId());
574                     g.getArtifactsUuid().remove(artifactInfoHeat.getArtifactUUID());
575                     g.getArtifacts().remove(artifactInfoHeatE.getUniqueId());
576                     g.getArtifacts().add(artHeatAfterUpdate.getUniqueId());
577                     g.getArtifactsUuid().add(artHeatAfterUpdate.getArtifactUUID());
578                     g.getArtifacts().add(artHEAfterUpdate.getUniqueId());
579                 });
580                 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, groupToUpdate);
581                 if (status.isRight()) {
582                     log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
583                     return componentsUtils.convertFromStorageResponse(status.right().value());
584                 }
585             }
586         }
587         return ActionStatus.OK;
588     }
589
590     private ActionStatus updateGroupInstance(ArtifactDefinition artifactInfo, ArtifactDefinition artAfterUpdate, Component parent, String parentId) {
591         List<GroupInstance> updatedGroupInstances = new ArrayList<>();
592         List<GroupInstance> groupInstances = null;
593         Optional<ComponentInstance> componentInstOp = parent.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(parentId))
594             .findFirst();
595         if (componentInstOp.isPresent()) {
596             groupInstances = componentInstOp.get().getGroupInstances();
597         }
598         if (CollectionUtils.isNotEmpty(groupInstances)) {
599             boolean isUpdated = false;
600             for (GroupInstance groupInstance : groupInstances) {
601                 isUpdated = false;
602                 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifacts()) && groupInstance.getGroupInstanceArtifacts()
603                     .contains(artifactInfo.getUniqueId())) {
604                     groupInstance.getGroupInstanceArtifacts().remove(artifactInfo.getUniqueId());
605                     groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getUniqueId());
606                     isUpdated = true;
607                 }
608                 if (CollectionUtils.isNotEmpty(groupInstance.getGroupInstanceArtifactsUuid()) && groupInstance.getGroupInstanceArtifactsUuid()
609                     .contains(artifactInfo.getArtifactUUID())) {
610                     groupInstance.getGroupInstanceArtifactsUuid().remove(artifactInfo.getArtifactUUID());
611                     groupInstance.getGroupInstanceArtifacts().add(artAfterUpdate.getArtifactUUID());
612                     isUpdated = true;
613                 }
614                 if (isUpdated) {
615                     updatedGroupInstances.add(groupInstance);
616                 }
617             }
618         }
619         Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
620             .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
621         if (status.isRight()) {
622             log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
623             return componentsUtils.convertFromStorageResponse(status.right().value());
624         }
625         return ActionStatus.OK;
626     }
627
628     ArtifactDefinition generateNotSavedArtifact(Component parent, ArtifactDefinition artifactDefinition) {
629         if (artifactDefinition.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA) {
630             Either<byte[], ComponentException> decodedPayload = decodeToscaArtifactPayload(parent, false, false,
631                 artifactDefinition.getArtifactType());
632             // TODO: This should not be done, but in order to keep this refactoring relatively small, we stop here
633             if (decodedPayload.isRight()) {
634                 throw decodedPayload.right().value();
635             } else {
636                 artifactDefinition.setPayload(decodedPayload.left().value());
637                 return artifactDefinition;
638             }
639         } else {
640             String heatArtifactId = artifactDefinition.getGeneratedFromId();
641             Either<ArtifactDefinition, StorageOperationStatus> heatRes = artifactToscaOperation.getArtifactById(parent.getUniqueId(), heatArtifactId);
642             if (heatRes.isRight()) {
643                 log.debug("Failed to fetch heat artifact by generated id {} for heat env {}", heatArtifactId, artifactDefinition.getUniqueId());
644                 throw new StorageException(heatRes.right().value());
645             }
646             String generatedPayload = generateHeatEnvPayload(heatRes.left().value());
647             artifactDefinition.setPayloadData(generatedPayload);
648             return artifactDefinition;
649         }
650     }
651
652     private Either<ArtifactDefinition, Operation> handleUpdateHeatWithHeatEnvParams(String componentId, ArtifactDefinition artifactInfo,
653                                                                                     AuditingActionEnum auditingAction,
654                                                                                     ComponentTypeEnum componentType, Component parent,
655                                                                                     String originData, String origMd5,
656                                                                                     ArtifactOperationInfo operation, boolean needToUpdateGroup) {
657         Either<ArtifactDefinition, StorageOperationStatus> artifactHeatRes = artifactToscaOperation
658             .getArtifactById(componentId, artifactInfo.getGeneratedFromId());
659         ArtifactDefinition currHeatArtifact = artifactHeatRes.left().value();
660         if (origMd5 != null) {
661             validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
662             if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
663                 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
664             } else { // duplicate
665                 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
666             }
667         }
668         return updateHeatParams(componentId, artifactInfo, auditingAction, parent, componentType, currHeatArtifact, needToUpdateGroup);
669     }
670
671     private void handleLockingAndCommit(Component parent, boolean shouldLock, boolean inTransaction, boolean actionSucceeded) {
672         if (actionSucceeded) {
673             log.debug(COMMIT);
674             if (!inTransaction) {
675                 janusGraphDao.commit();
676             }
677         } else {
678             log.debug(ROLLBACK);
679             if (!inTransaction) {
680                 janusGraphDao.rollback();
681             }
682         }
683         if (shouldLock) {
684             graphLockOperation.unlockComponent(parent.getUniqueId(), parent.getComponentType().getNodeType());
685         }
686     }
687
688     public ImmutablePair<String, byte[]> handleDownloadToscaModelRequest(Component component, ArtifactDefinition csarArtifact) {
689         if (artifactGenerationRequired(component, csarArtifact)) {
690             Either<byte[], ResponseFormat> generated = csarUtils.createCsar(component, false, false);
691             if (generated.isRight()) {
692                 log.debug("Failed to export tosca csar for component {} error {}", component.getUniqueId(), generated.right().value());
693                 throw new ByResponseFormatComponentException(generated.right().value());
694             }
695             return new ImmutablePair<>(csarArtifact.getArtifactName(), generated.left().value());
696         }
697         return downloadArtifact(csarArtifact);
698     }
699
700     public ImmutablePair<String, byte[]> handleDownloadRequestById(String componentId, String artifactId, String userId,
701                                                                    ComponentTypeEnum componentType, String parentId, String containerComponentType) {
702         // perform all validation in common flow
703         Either<ArtifactDefinition, Operation> result = handleArtifactRequest(componentId, userId, componentType,
704             new ArtifactOperationInfo(false, false, ArtifactOperationEnum.DOWNLOAD), artifactId, null, null, null, null, null, parentId,
705             containerComponentType);
706         ArtifactDefinition artifactDefinition;
707         if (result.isLeft()) {
708             artifactDefinition = result.left().value();
709         } else {
710             artifactDefinition = result.right().value().getImplementationArtifact();
711         }
712         // for tosca artifacts and heat env on VF level generated on download without saving
713         if (artifactDefinition.getPayloadData() != null) {
714             return (new ImmutablePair<>(artifactDefinition.getArtifactName(), artifactDefinition.getPayloadData()));
715         }
716         return downloadArtifact(artifactDefinition);
717     }
718
719     public Map<String, ArtifactDefinition> handleGetArtifactsByType(String containerComponentType, String parentId, ComponentTypeEnum componentType,
720                                                                     String componentId, String artifactGroupType, String userId) {
721         // step 1
722
723         // detect auditing type
724         Map<String, ArtifactDefinition> resMap = null;
725         new Wrapper<>();
726         // step 2
727
728         // check header
729         if (userId == null) {
730             log.debug("handleGetArtifactsByType - no HTTP_CSP_HEADER , component id {}", componentId);
731             throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
732         }
733         // step 3
734
735         // check user existence
736
737         // step 4
738
739         // check user's role
740         validateUserExists(userId);
741         // steps 5 - 6 - 7
742
743         // 5. check service/resource existence
744
745         // 6. check service/resource check out
746
747         // 7. user is owner of checkout state
748         String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId;
749         ComponentParametersView componentFilter = new ComponentParametersView();
750         componentFilter.disableAll();
751         componentFilter.setIgnoreArtifacts(false);
752         if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
753             componentFilter.setIgnoreComponentInstances(false);
754         }
755         Component component = validateComponentExistsByFilter(realComponentId, ComponentTypeEnum.findByParamName(containerComponentType),
756             componentFilter);
757         lockComponent(component, ARTIFACT_ACTION_LOCK);
758         boolean failed = false;
759         try {
760             ArtifactGroupTypeEnum groupType = ArtifactGroupTypeEnum.findType(artifactGroupType);
761             if (groupType == null) {
762                 log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
763                 throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
764             }
765             if (parentId == null && groupType == ArtifactGroupTypeEnum.DEPLOYMENT) {
766                 List<ArtifactDefinition> list = getDeploymentArtifacts(component, componentId);
767                 if (list != null && !list.isEmpty()) {
768                     resMap = list.stream().collect(Collectors.toMap(ArtifactDataDefinition::getArtifactLabel, Function.identity()));
769                 } else {
770                     resMap = new HashMap<>();
771                 }
772                 return resMap;
773             } else {
774                 Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsMapStatus = getArtifacts(realComponentId,
775                     componentType.getNodeType(), groupType, componentId);
776                 if (artifactsMapStatus.isRight()) {
777                     if (artifactsMapStatus.right().value() != StorageOperationStatus.NOT_FOUND) {
778                         log.debug("handleGetArtifactsByType - not failed groupType {} , component id {}", artifactGroupType, componentId);
779                         throw new ByActionStatusComponentException(ActionStatus.MISSING_INFORMATION);
780                     } else {
781                         resMap = new HashMap<>();
782                     }
783                 } else {
784                     resMap = artifactsMapStatus.left().value();
785                 }
786                 return resMap;
787             }
788         } catch (ComponentException e) {
789             failed = true;
790             throw e;
791         } finally {
792             // unlock resource
793             if (failed) {
794                 log.debug(ROLLBACK);
795                 janusGraphDao.rollback();
796             } else {
797                 log.debug(COMMIT);
798                 janusGraphDao.commit();
799             }
800             componentType = component.getComponentType();
801             NodeTypeEnum nodeType = componentType.getNodeType();
802             graphLockOperation.unlockComponent(component.getUniqueId(), nodeType);
803         }
804     }
805
806     private ArtifactDefinition getArtifactIfBelongsToComponent(String componentId, ComponentTypeEnum componentType, String artifactId,
807                                                                Component component) {
808         // check artifact existence
809         Either<ArtifactDefinition, StorageOperationStatus> artifactResult = artifactToscaOperation
810             .getArtifactById(componentId, artifactId, componentType, component.getUniqueId());
811         if (artifactResult.isRight()) {
812             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentId);
813         }
814         // verify artifact belongs to component
815         boolean found;
816         switch (componentType) {
817             case RESOURCE:
818             case SERVICE:
819                 found = ComponentUtils.checkArtifactInComponent(component, artifactId);
820                 break;
821             case RESOURCE_INSTANCE:
822                 found = ComponentUtils.checkArtifactInResourceInstance(component, componentId, artifactId);
823                 break;
824             default:
825                 found = false;
826         }
827         if (!found) {
828             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, artifactId, componentType.name().toLowerCase());
829         }
830         return artifactResult.left().value();
831     }
832
833     private Either<ArtifactDefinition, Operation> handleCreate(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
834                                                                AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType,
835                                                                Component parent, String origMd5, String originData, String interfaceType,
836                                                                String operationName) {
837         byte[] decodedPayload = validateInput(componentId, artifactInfo, operation, auditingAction, null, user, componentType, parent, origMd5,
838             originData, interfaceType, operationName);
839         return createArtifact(parent, componentId, artifactInfo, decodedPayload, componentType, auditingAction, interfaceType, operationName);
840     }
841
842     private ArtifactDefinition handleLink(String componentId, ArtifactDefinition artifactInfo, ComponentTypeEnum componentType, Component parent) {
843         ComponentInstance foundInstance = findComponentInstance(componentId, parent);
844         String instanceId = null;
845         if (foundInstance != null) {
846             instanceId = foundInstance.getUniqueId();
847         }
848         NodeTypeEnum nodeType = convertParentType(componentType);
849         Either<ArtifactDefinition, StorageOperationStatus> artifactDefinitionEither = artifactToscaOperation
850             .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
851         if (artifactDefinitionEither.isRight()) {
852             throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
853         }
854         if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), componentId, componentType) != StorageOperationStatus.OK) {
855             throw new StorageException(artifactDefinitionEither.right().value(), artifactInfo.getArtifactDisplayName());
856         }
857         return artifactDefinitionEither.left().value();
858     }
859
860     private <T> Either<ArtifactDefinition, T> lockComponentAndUpdateArtifact(String parentId, ArtifactDefinition artifactInfo,
861                                                                              AuditingActionEnum auditingAction, String artifactId, User user,
862                                                                              ComponentTypeEnum componentType, Component parent, byte[] decodedPayload,
863                                                                              boolean shouldLock, boolean inTransaction) {
864         boolean failed = false;
865         boolean writeAudit = true;
866         try {
867             lockComponent(parent, shouldLock, ARTIFACT_ACTION_LOCK);
868             writeAudit = false;
869             return updateArtifactFlow(parent, parentId, artifactId, artifactInfo, decodedPayload, componentType, auditingAction);
870         } catch (ComponentException ce) {
871             if (writeAudit) {
872                 handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, ce.getResponseFormat(), componentType, null);
873             }
874             failed = true;
875             throw ce;
876         } catch (StorageException se) {
877             //TODO: audit
878             failed = true;
879             throw se;
880         } finally {
881             if (shouldLock) {
882                 unlockComponent(failed, parent, inTransaction);
883             }
884         }
885     }
886
887     private byte[] validateInput(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
888                                  AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
889                                  String origMd5, String originData, String interfaceType, String operationName) {
890         validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
891         return getValidPayload(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, interfaceType,
892             operationName);
893     }
894
895     private byte[] getValidPayload(String componentId, ArtifactDefinition artifactInfo, ArtifactOperationInfo operation,
896                                    AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, Component parent,
897                                    String interfaceType, String operationName) {
898         // step 11
899         Either<ArtifactDefinition, ResponseFormat> validateResult = validateInput(componentId, artifactInfo, operation, artifactId, user,
900             interfaceType, operationName, componentType, parent);
901         if (validateResult.isRight()) {
902             ResponseFormat responseFormat = validateResult.right().value();
903             handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
904             throw new ByResponseFormatComponentException(responseFormat);
905         }
906         Either<byte[], ResponseFormat> payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
907         if (payloadEither.isRight()) {
908             ResponseFormat responseFormat = payloadEither.right().value();
909             handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null);
910             log.debug("Error during handle payload");
911             throw new ByResponseFormatComponentException(responseFormat);
912         }
913         // validate heat parameters. this part must be after the parameters are
914
915         // extracted in "handlePayload"
916         Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters = validateAndConvertHeatParameters(artifactInfo,
917             artifactInfo.getArtifactType());
918         if (validateAndConvertHeatParameters.isRight()) {
919             ResponseFormat responseFormat = validateAndConvertHeatParameters.right().value();
920             handleAuditing(auditingAction, parent, componentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null);
921             log.debug("Error during handle payload");
922             throw new ByResponseFormatComponentException(responseFormat);
923         }
924         return payloadEither.left().value();
925     }
926
927     public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
928                                ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
929                                ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
930         if (componentsUtils.isExternalApiEvent(auditingActionEnum)) {
931             return;
932         }
933         if (user == null) {
934             user = new User();
935             user.setUserId("UNKNOWN");
936         }
937         handleInternalAuditEvent(auditingActionEnum, component, componentId, user, artifactDefinition, prevArtifactUuid, currentArtifactUuid,
938             responseFormat, componentTypeEnum, resourceInstanceName);
939     }
940
941     private void handleInternalAuditEvent(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user,
942                                           ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid,
943                                           ResponseFormat responseFormat, ComponentTypeEnum componentTypeEnum, String resourceInstanceName) {
944         switch (componentTypeEnum) {
945             case RESOURCE:
946                 Resource resource = (Resource) component;
947                 if (resource == null) {
948                     // In that case, component ID should be instead of name
949                     resource = new Resource();
950                     resource.setName(componentId);
951                 }
952                 componentsUtils.auditResource(responseFormat, user, resource, resource.getName(), auditingActionEnum,
953                     ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(), currentArtifactUuid, artifactDefinition);
954                 break;
955             case SERVICE:
956                 Service service = (Service) component;
957                 if (service == null) {
958                     // In that case, component ID should be instead of name
959                     service = new Service();
960                     service.setName(componentId);
961                 }
962                 componentsUtils
963                     .auditComponent(responseFormat, user, service, auditingActionEnum, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
964                         ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
965                         ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
966                 break;
967             case RESOURCE_INSTANCE:
968                 if (resourceInstanceName == null) {
969                     resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId);
970                 }
971                 componentsUtils.auditComponent(responseFormat, user, component, auditingActionEnum,
972                     new ResourceCommonInfo(resourceInstanceName, ComponentTypeEnum.RESOURCE_INSTANCE.getValue()),
973                     ResourceVersionInfo.newBuilder().artifactUuid(prevArtifactUuid).build(),
974                     ResourceVersionInfo.newBuilder().artifactUuid(currentArtifactUuid).build(), null, artifactDefinition, null);
975                 break;
976             default:
977                 break;
978         }
979     }
980
981     private String getResourceInstanceNameFromComponent(Component component, String componentId) {
982         ComponentInstance resourceInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findFirst()
983             .orElse(null);
984         String resourceInstanceName = null;
985         if (resourceInstance != null) {
986             resourceInstanceName = resourceInstance.getName();
987         }
988         return resourceInstanceName;
989     }
990
991     private void validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperationInfo operation) {
992         if (origMd5 == null) {
993             if (operation.isCreateOrLink() && ArrayUtils.isNotEmpty(payload)) {
994                 log.debug("Missing md5 header during artifact create");
995                 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
996             }
997             // Update metadata
998             if (ArrayUtils.isNotEmpty(payload)) {
999                 log.debug("Cannot have payload while md5 header is missing");
1000                 throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
1001             }
1002         } else {
1003             String encodeBase64Str = GeneralUtility.calculateMD5Base64EncodedByString(originData);
1004             if (!encodeBase64Str.equals(origMd5)) {
1005                 log.debug("The calculated md5 is different then the received one");
1006                 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_MD5);
1007             }
1008         }
1009     }
1010
1011     private Either<ArtifactDefinition, ResponseFormat> validateInput(final String componentId, final ArtifactDefinition artifactInfo,
1012                                                                      final ArtifactOperationInfo operation, final String artifactId, final User user,
1013                                                                      String interfaceName, String operationName,
1014                                                                      final ComponentTypeEnum componentType, final Component parentComponent) {
1015         final ArtifactDefinition existingArtifactInfo = findArtifact(parentComponent, componentType, componentId, operation, artifactId);
1016         final boolean isCreateOrLinkOperation = ArtifactOperationEnum.isCreateOrLink(operation.getArtifactOperationEnum());
1017         if (!isCreateOrLinkOperation && existingArtifactInfo == null) {
1018             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1019         }
1020         final Component component;
1021         if (parentComponent.getUniqueId().equals(componentId)) {
1022             component = parentComponent;
1023         } else {
1024             final ComponentInstance componentInstance = findComponentInstance(componentId, parentComponent);
1025             component = findComponent(componentInstance.getComponentUid());
1026             component.setComponentType(componentType);
1027         }
1028         if (!isCreateOrLinkOperation) {
1029             ignoreUnupdateableFieldsInUpdate(operation, artifactInfo, existingArtifactInfo);
1030         }
1031         if (isInformationalArtifact(artifactInfo)) {
1032             validateInformationalArtifact(artifactInfo, component);
1033         }
1034         Either<Boolean, ResponseFormat> validateAndSetArtifactname = validateAndSetArtifactName(artifactInfo);
1035         if (validateAndSetArtifactname.isRight()) {
1036             return Either.right(validateAndSetArtifactname.right().value());
1037         }
1038         if (!validateArtifactNameUniqueness(componentId, parentComponent, artifactInfo, componentType)) {
1039             return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST));
1040         }
1041         if (operationName != null && interfaceName != null) {
1042             operationName = operationName.toLowerCase();
1043             interfaceName = interfaceName.toLowerCase();
1044         }
1045         Either<ActionStatus, ResponseFormat> logicalNameStatus = handleArtifactLabel(componentId, parentComponent, operation, artifactInfo,
1046             operationName, componentType);
1047         if (logicalNameStatus.isRight()) {
1048             return Either.right(logicalNameStatus.right().value());
1049         }
1050         // This is a patch to block possibility of updating service api fields
1051
1052         // through other artifacts flow
1053         final ArtifactGroupTypeEnum artifactGroupType =
1054             operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL;
1055         if (operation.isNotCreateOrLink()) {
1056             checkAndSetUnUpdatableFields(user, artifactInfo, existingArtifactInfo, artifactGroupType);
1057         } else {
1058             checkCreateFields(user, artifactInfo, artifactGroupType);
1059         }
1060         composeArtifactId(componentId, artifactId, artifactInfo, interfaceName, operationName);
1061         if (existingArtifactInfo != null) {
1062             artifactInfo.setMandatory(existingArtifactInfo.getMandatory());
1063             if (operation.isNotCreateOrLink()) {
1064                 validateArtifactTypeNotChanged(artifactInfo, existingArtifactInfo);
1065             }
1066         }
1067         // artifactGroupType is not allowed to be updated
1068         if (operation.isNotCreateOrLink()) {
1069             Either<ArtifactDefinition, ResponseFormat> validateGroupType = validateOrSetArtifactGroupType(artifactInfo, existingArtifactInfo);
1070             if (validateGroupType.isRight()) {
1071                 return Either.right(validateGroupType.right().value());
1072             }
1073         }
1074         setArtifactTimeout(artifactInfo, existingArtifactInfo);
1075         if (isHeatArtifact(artifactInfo)) {
1076             validateHeatArtifact(parentComponent, componentId, artifactInfo);
1077         }
1078         if (isDeploymentArtifact(artifactInfo)) {
1079             if (componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1080                 final String artifactName = artifactInfo.getArtifactName();
1081                 final String existingArtifactName = (existingArtifactInfo == null) ? null : existingArtifactInfo.getArtifactName();
1082                 if (operation.isCreateOrLink() || ((artifactName != null) && !artifactName.equalsIgnoreCase(existingArtifactName))) {
1083                     validateSingleDeploymentArtifactName(artifactName, parentComponent);
1084                 }
1085             }
1086             validateDeploymentArtifact(artifactInfo, component);
1087         }
1088         Either<Boolean, ResponseFormat> descriptionResult = validateAndCleanDescription(artifactInfo);
1089         if (descriptionResult.isRight()) {
1090             return Either.right(descriptionResult.right().value());
1091         }
1092         validateArtifactType(artifactInfo, component.getComponentType());
1093         artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase());
1094         if (existingArtifactInfo != null && existingArtifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.SERVICE_API) {
1095             // Change of type is not allowed and should be ignored
1096             artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER);
1097             Either<Boolean, ResponseFormat> validateUrl = validateAndServiceApiUrl(artifactInfo);
1098             if (validateUrl.isRight()) {
1099                 return Either.right(validateUrl.right().value());
1100             }
1101             Either<Boolean, ResponseFormat> validateUpdate = validateFirstUpdateHasPayload(artifactInfo, existingArtifactInfo);
1102             if (validateUpdate.isRight()) {
1103                 log.debug("serviceApi first update cnnot be without payload.");
1104                 return Either.right(validateUpdate.right().value());
1105             }
1106         } else {
1107             if (artifactInfo.getApiUrl() != null) {
1108                 artifactInfo.setApiUrl(null);
1109                 log.error("Artifact URL cannot be set through this API - ignoring");
1110             }
1111             if (Boolean.TRUE.equals(artifactInfo.getServiceApi())) {
1112                 artifactInfo.setServiceApi(false);
1113                 log.error("Artifact service API flag cannot be changed - ignoring");
1114             }
1115         }
1116         return Either.left(artifactInfo);
1117     }
1118
1119     private Component findComponent(final String componentId) {
1120         Either<? extends Component, StorageOperationStatus> component = toscaOperationFacade.getToscaFullElement(componentId);
1121         if (component.isRight()) {
1122             log.debug("Component '{}' not found ", componentId);
1123             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentId);
1124         }
1125         return component.left().value();
1126     }
1127
1128     private void ignoreUnupdateableFieldsInUpdate(final ArtifactOperationInfo operation, final ArtifactDefinition artifactInfo,
1129                                                   final ArtifactDefinition currentArtifactInfo) {
1130         if (operation.isUpdate()) {
1131             artifactInfo.setArtifactType(currentArtifactInfo.getArtifactType());
1132             artifactInfo.setArtifactGroupType(currentArtifactInfo.getArtifactGroupType());
1133             artifactInfo.setArtifactLabel(currentArtifactInfo.getArtifactLabel());
1134         }
1135     }
1136
1137     private ArtifactDefinition findArtifact(final Component parentComponent, final ComponentTypeEnum componentType, final String parentId,
1138                                             final ArtifactOperationInfo operation, final String artifactId) {
1139         ArtifactDefinition foundArtifact = null;
1140         if (StringUtils.isNotEmpty(artifactId)) {
1141             foundArtifact = findArtifact(parentComponent, componentType, parentId, artifactId);
1142         }
1143         if (foundArtifact != null && operation.isCreateOrLink()) {
1144             log.debug("Artifact {} already exist", artifactId);
1145             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, foundArtifact.getArtifactLabel());
1146         }
1147         if (foundArtifact == null && operation.isNotCreateOrLink()) {
1148             log.debug("The artifact {} was not found on parent component or instance {}. ", artifactId, parentId);
1149             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, "");
1150         }
1151         return foundArtifact;
1152     }
1153
1154     private ArtifactDefinition findArtifact(Component parentComponent, ComponentTypeEnum componentType, String parentId, String artifactId) {
1155         ArtifactDefinition foundArtifact;
1156         if (parentComponent.getUniqueId().equals(parentId)) {
1157             foundArtifact = artifactsResolver.findArtifactOnComponent(parentComponent, componentType, artifactId);
1158         } else {
1159             ComponentInstance instance = findComponentInstance(parentId, parentComponent);
1160             foundArtifact = artifactsResolver.findArtifactOnComponentInstance(instance, artifactId);
1161         }
1162         return foundArtifact;
1163     }
1164
1165     private void validateInformationalArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1166         final ArtifactGroupTypeEnum groupType = artifactInfo.getArtifactGroupType();
1167         if (groupType != ArtifactGroupTypeEnum.INFORMATIONAL) {
1168             return;
1169         }
1170         final ComponentTypeEnum parentComponentType = component.getComponentType();
1171         final String artifactType = artifactInfo.getArtifactType();
1172         final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1173         if (artifactConfiguration == null) {
1174             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1175         }
1176         validateArtifactType(parentComponentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1177         if (component.getComponentType() == ComponentTypeEnum.RESOURCE || component.getComponentType() == ComponentTypeEnum.RESOURCE_INSTANCE) {
1178             final ResourceTypeEnum resourceType = ((Resource) component).getResourceType();
1179             validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1180         }
1181         validateArtifactExtension(artifactConfiguration, artifactInfo);
1182     }
1183
1184     private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) {
1185         if (componentType == ComponentTypeEnum.RESOURCE) {
1186             return NodeTypeEnum.Resource;
1187         } else if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1188             return NodeTypeEnum.ResourceInstance;
1189         } else {
1190             return NodeTypeEnum.Service;
1191         }
1192     }
1193
1194     // This method is here for backward compatibility - when other parts of the code are cleaned can change to use the internal version
1195     public Either<ArtifactDefinition, ResponseFormat> handleDelete(String parentId, String artifactId, User user, Component parent,
1196                                                                    boolean shouldLock, boolean inTransaction) {
1197         ResponseFormat responseFormat;
1198         boolean operationSucceeded = false;
1199         if (shouldLock) {
1200             lockComponent(ComponentTypeEnum.RESOURCE, artifactId, AuditingActionEnum.ARTIFACT_DELETE, user, parent);
1201         }
1202         try {
1203             ArtifactDefinition artifactDefinition = handleDeleteInternal(parentId, artifactId, ComponentTypeEnum.RESOURCE, parent);
1204             operationSucceeded = true;
1205             return Either.left(artifactDefinition);
1206         } catch (ComponentException ce) {
1207             responseFormat = componentsUtils.getResponseFormat(ce);
1208             handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1209                 ComponentTypeEnum.RESOURCE, null);
1210             return Either.right(responseFormat);
1211         } catch (StorageException se) {
1212             responseFormat = componentsUtils.getResponseFormat(se);
1213             handleAuditing(AuditingActionEnum.ARTIFACT_DELETE, parent, parentId, user, null, null, artifactId, responseFormat,
1214                 ComponentTypeEnum.RESOURCE, null);
1215             return Either.right(responseFormat);
1216         } finally {
1217             handleLockingAndCommit(parent, shouldLock, inTransaction, operationSucceeded);
1218         }
1219     }
1220
1221     private ArtifactDefinition handleDeleteInternal(String parentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1222         NodeTypeEnum parentType = convertParentType(componentType);
1223         log.debug("Going to find the artifact {} on the component {}", artifactId, parent.getUniqueId());
1224         Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> getArtifactRes = findArtifact(artifactId, parent, parentId,
1225             componentType);
1226         if (getArtifactRes.isRight()) {
1227             log.debug("Failed to find the artifact {} belonging to {} on the component {}", artifactId, parentId, parent.getUniqueId());
1228             throw new ByActionStatusComponentException(getArtifactRes.right().value(), artifactId);
1229         }
1230         ArtifactDefinition foundArtifact = getArtifactRes.left().value().getLeft();
1231         ComponentInstance foundInstance = getArtifactRes.left().value().getRight();
1232         String esId = foundArtifact.getEsId();
1233         Either<Boolean, StorageOperationStatus> needClone = ifTrue(StringUtils.isNotEmpty(esId),
1234             () -> forEach(artifactToscaOperation.isCloneNeeded(parent.getUniqueId(), foundArtifact, parentType), b -> log
1235                 .debug("handleDelete: clone is needed for deleting {} held by {} in component {} {}? {}", foundArtifact.getArtifactName(), parentType,
1236                     parent.getUniqueId(), parent.getName(), b)));
1237         boolean needToClone = false;
1238         // TODO: This should not be done, but in order to keep this refactoring small, we stop here.
1239
1240         // Remove this block once the above refactoring is merged.
1241         if (needClone.isLeft()) {
1242             needToClone = needClone.left().value();
1243         } else {
1244             throw new StorageException(needClone.right().value(), foundArtifact.getArtifactDisplayName());
1245         }
1246         boolean isNeedToDeleteArtifactFromDB =
1247             componentType == ComponentTypeEnum.RESOURCE_INSTANCE && isArtifactOnlyResourceInstanceArtifact(foundArtifact, parent, parentId);
1248         boolean isDuplicated = false;
1249         ArtifactDataDefinition updatedArtifact = deleteOrUpdateArtifactOnGraph(parent, parentId, artifactId, parentType, foundArtifact, needToClone);
1250         isDuplicated = updatedArtifact.getDuplicated();
1251         if (!needToClone && !isDuplicated && isNeedToDeleteArtifactFromDB) {
1252             log.debug("Going to delete the artifact {} from the database. ", artifactId);
1253             CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(esId);
1254             if (cassandraStatus != CassandraOperationStatus.OK) {
1255                 log.debug("Failed to delete the artifact {} from the database. ", artifactId);
1256                 throw new StorageException(convertToStorageOperationStatus(cassandraStatus), foundArtifact.getArtifactDisplayName());
1257             }
1258         }
1259         if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1260             List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(artifactId, foundArtifact, foundInstance.getGroupInstances());
1261             if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
1262                 Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
1263                     .updateGroupInstancesOnComponent(parent, parentId, updatedGroupInstances);
1264                 if (status.isRight()) {
1265                     log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1266                     throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1267                 }
1268             }
1269             StorageOperationStatus status = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
1270             if (status != StorageOperationStatus.OK) {
1271                 log.debug("Failed to generate new customization UUID for the component instance {}. ", parentId);
1272                 throw new StorageException(status, foundArtifact.getArtifactDisplayName());
1273             }
1274         } else {
1275             List<GroupDataDefinition> updatedGroups = getUpdatedGroups(artifactId, foundArtifact, parent.getGroups());
1276             if (CollectionUtils.isNotEmpty(updatedGroups)) {
1277                 Either<List<GroupDefinition>, StorageOperationStatus> status = toscaOperationFacade.updateGroupsOnComponent(parent, updatedGroups);
1278                 if (status.isRight()) {
1279                     log.debug(FAILED_UPDATE_GROUPS, parent.getUniqueId());
1280                     throw new StorageException(status.right().value(), foundArtifact.getArtifactDisplayName());
1281                 }
1282             }
1283         }
1284         return foundArtifact;
1285     }
1286
1287     private boolean isArtifactOnlyResourceInstanceArtifact(ArtifactDefinition foundArtifact, Component parent, String instanceId) {
1288         Optional<ComponentInstance> componentInstanceOpt = parent.getComponentInstanceById(instanceId);
1289         if (!componentInstanceOpt.isPresent()) {
1290             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, instanceId, "", "", parent.getName());
1291         }
1292         ComponentInstance foundInstance = componentInstanceOpt.get();
1293         String componentUid = foundInstance.getComponentUid();
1294         Either<Component, StorageOperationStatus> getContainerRes = toscaOperationFacade.getToscaElement(componentUid);
1295         if (getContainerRes.isRight()) {
1296             log.debug("Failed to fetch the container component {}. ", componentUid);
1297             throw new StorageException(getContainerRes.right().value());
1298         }
1299         Component origComponent = getContainerRes.left().value();
1300         Map<String, ArtifactDefinition> deploymentArtifacts = origComponent.getDeploymentArtifacts();
1301         if (MapUtils.isNotEmpty(deploymentArtifacts)) {
1302             Optional<String> op = deploymentArtifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1303             if (op.isPresent()) {
1304                 return false;
1305             }
1306         }
1307         Map<String, ArtifactDefinition> artifacts = origComponent.getArtifacts();
1308         if (MapUtils.isNotEmpty(artifacts)) {
1309             Optional<String> op = artifacts.keySet().stream().filter(a -> a.equals(foundArtifact.getArtifactLabel())).findAny();
1310             if (op.isPresent()) {
1311                 return false;
1312             }
1313         }
1314         return true;
1315     }
1316
1317     private List<GroupDataDefinition> getUpdatedGroups(String artifactId, ArtifactDefinition foundArtifact, List<GroupDefinition> groups) {
1318         List<GroupDataDefinition> updatedGroups = new ArrayList<>();
1319         boolean isUpdated = false;
1320         if (groups != null) {
1321             for (GroupDefinition group : groups) {
1322                 isUpdated = false;
1323                 if (CollectionUtils.isNotEmpty(group.getArtifacts()) && group.getArtifacts().contains(artifactId)) {
1324                     group.getArtifacts().remove(artifactId);
1325                     isUpdated = true;
1326                 }
1327                 if (CollectionUtils.isNotEmpty(group.getArtifactsUuid()) && group.getArtifactsUuid().contains(foundArtifact.getArtifactUUID())) {
1328                     group.getArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1329                     isUpdated = true;
1330                 }
1331                 if (isUpdated) {
1332                     updatedGroups.add(group);
1333                 }
1334             }
1335         }
1336         return updatedGroups;
1337     }
1338
1339     private List<GroupInstance> getUpdatedGroupInstances(String artifactId, ArtifactDefinition foundArtifact, List<GroupInstance> groupInstances) {
1340         if (CollectionUtils.isEmpty(groupInstances)) {
1341             return new ArrayList<>();
1342         }
1343         // TODO: A defensive copy should be created here for groupInstances. Modifying
1344
1345         // arguments (aka output arguments) is overall a bad practice as explained in
1346
1347         // Clean Code by Robert Martin.
1348
1349         // A better approach would be to use Lenses.
1350         return groupInstances.stream().filter(gi -> {
1351             boolean groupInstanceArtifactRemoved = gi.getGroupInstanceArtifacts() != null && gi.getGroupInstanceArtifacts().remove(artifactId);
1352             boolean groupInstanceArtifactUUIDRemoved =
1353                 gi.getGroupInstanceArtifactsUuid() != null && gi.getGroupInstanceArtifactsUuid().remove(foundArtifact.getArtifactUUID());
1354             return groupInstanceArtifactRemoved || groupInstanceArtifactUUIDRemoved;
1355         }).collect(Collectors.toList());
1356     }
1357
1358     private ArtifactDataDefinition deleteOrUpdateArtifactOnGraph(Component component, String parentId, String artifactId, NodeTypeEnum parentType,
1359                                                                  ArtifactDefinition foundArtifact, Boolean cloneIsNeeded) {
1360         Either<ArtifactDataDefinition, StorageOperationStatus> result;
1361         boolean isMandatory = foundArtifact.getMandatory() || foundArtifact.getServiceApi();
1362         String componentId = component.getUniqueId();
1363         String instanceId = componentId.equals(parentId) ? null : parentId;
1364         if (isMandatory) {
1365             log.debug("Going to update mandatory artifact {} from the component {}", artifactId, parentId);
1366             resetMandatoryArtifactFields(foundArtifact);
1367             result = artifactToscaOperation.updateArtifactOnGraph(component, foundArtifact, parentType, artifactId, instanceId, true, true);
1368         } else if (cloneIsNeeded) {
1369             log.debug("Going to clone artifacts and to delete the artifact {} from the component {}", artifactId, parentId);
1370             result = artifactToscaOperation.deleteArtifactWithCloningOnGraph(componentId, foundArtifact, parentType, instanceId, false);
1371         } else {
1372             log.debug("Going to delete the artifact {} from the component {}", artifactId, parentId);
1373             result = artifactToscaOperation.removeArtifactOnGraph(foundArtifact, componentId, instanceId, parentType, false);
1374         }
1375         if (result.isRight()) {
1376             throw new StorageException(result.right().value(), foundArtifact.getArtifactDisplayName());
1377         }
1378         return result.left().value();
1379     }
1380
1381     private Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> findArtifact(String artifactId,
1382                                                                                                     Component fetchedContainerComponent,
1383                                                                                                     String parentId,
1384                                                                                                     ComponentTypeEnum componentType) {
1385         Either<ImmutablePair<ArtifactDefinition, ComponentInstance>, ActionStatus> result = null;
1386         Map<String, ArtifactDefinition> artifacts = new HashMap<>();
1387         ComponentInstance foundInstance = null;
1388         if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE && StringUtils.isNotEmpty(parentId)) {
1389             Optional<ComponentInstance> componentInstanceOpt = fetchedContainerComponent.getComponentInstances().stream()
1390                 .filter(i -> i.getUniqueId().equals(parentId)).findFirst();
1391             if (!componentInstanceOpt.isPresent()) {
1392                 result = Either.right(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER);
1393             } else {
1394                 foundInstance = componentInstanceOpt.get();
1395                 fetchArtifactsFromInstance(artifactId, artifacts, foundInstance);
1396             }
1397         } else {
1398             fetchArtifactsFromComponent(artifactId, fetchedContainerComponent, artifacts);
1399         }
1400         if (result == null) {
1401             if (artifacts.containsKey(artifactId)) {
1402                 result = Either.left(new ImmutablePair<>(artifacts.get(artifactId), foundInstance));
1403             } else {
1404                 result = Either.right(ActionStatus.ARTIFACT_NOT_FOUND);
1405             }
1406         }
1407         return result;
1408     }
1409
1410     private void fetchArtifactsFromComponent(String artifactId, Component component, Map<String, ArtifactDefinition> artifacts) {
1411         Map<String, ArtifactDefinition> currArtifacts;
1412         if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getDeploymentArtifacts())) {
1413             currArtifacts = component.getDeploymentArtifacts().values().stream()
1414                 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, i -> i));
1415             if (MapUtils.isNotEmpty(currArtifacts)) {
1416                 artifacts.putAll(currArtifacts);
1417             }
1418         }
1419         if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1420             currArtifacts = component.getArtifacts().values().stream()
1421                 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1422             if (MapUtils.isNotEmpty(currArtifacts)) {
1423                 artifacts.putAll(currArtifacts);
1424             }
1425         }
1426         if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(component.getArtifacts())) {
1427             currArtifacts = component.getToscaArtifacts().values().stream()
1428                 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1429             if (MapUtils.isNotEmpty(currArtifacts)) {
1430                 artifacts.putAll(currArtifacts);
1431             }
1432         }
1433     }
1434
1435     private void fetchArtifactsFromInstance(String artifactId, Map<String, ArtifactDefinition> artifacts, ComponentInstance instance) {
1436         Map<String, ArtifactDefinition> currArtifacts;
1437         if (MapUtils.isNotEmpty(instance.getDeploymentArtifacts())) {
1438             currArtifacts = instance.getDeploymentArtifacts().values().stream()
1439                 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1440             if (MapUtils.isNotEmpty(currArtifacts)) {
1441                 artifacts.putAll(currArtifacts);
1442             }
1443         }
1444         if (!artifacts.containsKey(artifactId) && MapUtils.isNotEmpty(instance.getArtifacts())) {
1445             currArtifacts = instance.getArtifacts().values().stream()
1446                 .collect(Collectors.toMap(ArtifactDataDefinition::getUniqueId, Function.identity()));
1447             if (MapUtils.isNotEmpty(currArtifacts)) {
1448                 artifacts.putAll(currArtifacts);
1449             }
1450         }
1451     }
1452
1453     private StorageOperationStatus convertToStorageOperationStatus(CassandraOperationStatus cassandraStatus) {
1454         StorageOperationStatus result;
1455         switch (cassandraStatus) {
1456             case OK:
1457                 result = StorageOperationStatus.OK;
1458                 break;
1459             case NOT_FOUND:
1460                 result = StorageOperationStatus.NOT_FOUND;
1461                 break;
1462             case CLUSTER_NOT_CONNECTED:
1463             case KEYSPACE_NOT_CONNECTED:
1464                 result = StorageOperationStatus.CONNECTION_FAILURE;
1465                 break;
1466             default:
1467                 result = StorageOperationStatus.GENERAL_ERROR;
1468                 break;
1469         }
1470         return result;
1471     }
1472
1473     private void resetMandatoryArtifactFields(ArtifactDefinition fetchedArtifact) {
1474         if (fetchedArtifact != null) {
1475             log.debug("Going to reset mandatory artifact {} fields. ", fetchedArtifact.getUniqueId());
1476             fetchedArtifact.setEsId(null);
1477             fetchedArtifact.setArtifactName(null);
1478             fetchedArtifact.setDescription(null);
1479             fetchedArtifact.setApiUrl(null);
1480             fetchedArtifact.setArtifactChecksum(null);
1481             nodeTemplateOperation.setDefaultArtifactTimeout(fetchedArtifact.getArtifactGroupType(), fetchedArtifact);
1482             fetchedArtifact.setArtifactUUID(null);
1483             long time = System.currentTimeMillis();
1484             fetchedArtifact.setPayloadUpdateDate(time);
1485             fetchedArtifact.setHeatParameters(null);
1486             fetchedArtifact.setHeatParamsUpdateDate(null);
1487         }
1488     }
1489
1490     private StorageOperationStatus generateCustomizationUUIDOnInstance(String componentId, String instanceId, ComponentTypeEnum componentType) {
1491         StorageOperationStatus error = StorageOperationStatus.OK;
1492         if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1493             log.debug("Need to re-generate  customization UUID for instance {}", instanceId);
1494             error = toscaOperationFacade.generateCustomizationUUIDOnInstance(componentId, instanceId);
1495         }
1496         return error;
1497     }
1498
1499     private ArtifactDefinition handleDownload(String componentId, String artifactId, ComponentTypeEnum componentType, Component parent) {
1500         Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation
1501             .getArtifactById(componentId, artifactId, componentType, parent.getUniqueId());
1502         if (artifactById.isRight()) {
1503             throw new StorageException(artifactById.right().value());
1504         }
1505         ArtifactDefinition artifactDefinition = artifactById.left().value();
1506         if (artifactDefinition == null) {
1507             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactId);
1508         }
1509         return artifactDefinition;
1510     }
1511
1512     private Either<ActionStatus, ResponseFormat> handleArtifactLabel(String componentId, Component parentComponent, ArtifactOperationInfo operation,
1513                                                                      ArtifactDefinition artifactInfo, String operationName,
1514                                                                      ComponentTypeEnum componentType) {
1515         String artifactLabel = artifactInfo.getArtifactLabel();
1516         if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) {
1517             BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel");
1518             log.debug("missing artifact logical name for component {}", componentId);
1519             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1520         }
1521         if (operation.isCreateOrLink() && !artifactInfo.getMandatory()) {
1522             if (operationName != null) {
1523                 if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) {
1524                     log.debug("artifact label cannot be set {}", artifactLabel);
1525                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED));
1526                 } else {
1527                     artifactLabel = operationName;
1528                 }
1529             }
1530             String displayName = artifactInfo.getArtifactDisplayName();
1531             if (displayName == null || displayName.isEmpty()) {
1532                 displayName = artifactLabel;
1533             }
1534             displayName = ValidationUtils.cleanArtifactDisplayName(displayName);
1535             artifactInfo.setArtifactDisplayName(displayName);
1536             if (!ValidationUtils.validateArtifactLabel(artifactLabel)) {
1537                 log.debug("Invalid format form Artifact label : {}", artifactLabel);
1538                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_ARTIFACT_LABEL_NAME, VALID_ARTIFACT_LABEL_NAME));
1539             }
1540             artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel);
1541             if (artifactLabel.isEmpty()) {
1542                 log.debug("missing normalized artifact logical name for component {}", componentId);
1543                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL));
1544             }
1545             if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) {
1546                 log.debug("Invalid lenght form Artifact label : {}", artifactLabel);
1547                 return Either.right(componentsUtils
1548                     .getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH)));
1549             }
1550             if (!validateLabelUniqueness(componentId, parentComponent, artifactLabel, componentType)) {
1551                 log.debug("Non unique Artifact label : {}", artifactLabel);
1552                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel));
1553             }
1554         }
1555         artifactInfo.setArtifactLabel(artifactLabel);
1556         return Either.left(ActionStatus.OK);
1557     }
1558
1559     private boolean validateLabelUniqueness(String componentId, Component parentComponent, String artifactLabel, ComponentTypeEnum componentType) {
1560         boolean isUnique = true;
1561         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts;
1562         if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1563             artifacts = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1564         } else {
1565             artifacts = artifactToscaOperation.getArtifacts(componentId);
1566         }
1567         if (artifacts.isLeft()) {
1568             for (String label : artifacts.left().value().keySet()) {
1569                 if (label.equals(artifactLabel)) {
1570                     isUnique = false;
1571                     break;
1572                 }
1573             }
1574         }
1575         if (componentType == ComponentTypeEnum.RESOURCE && isUnique) {
1576             isUnique = isUniqueLabelInResourceInterfaces(componentId, artifactLabel);
1577         }
1578         return isUnique;
1579     }
1580
1581     boolean validateArtifactNameUniqueness(String componentId, Component parentComponent, ArtifactDefinition artifactInfo,
1582                                            ComponentTypeEnum componentType) {
1583         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = getArtifacts(componentType, parentComponent, componentId,
1584             artifactInfo.getArtifactGroupType());
1585         String artifactName = artifactInfo.getArtifactName();
1586         if (artifacts.isLeft() && Objects.nonNull(artifacts.left().value())) {
1587             if (artifacts.left().value().values().stream().anyMatch(ad -> artifactName.equals(ad.getArtifactName())
1588                 //check whether it is the same artifact we hold (by label)
1589                 && !artifactInfo.getArtifactLabel().equals(ad.getArtifactLabel()))) {
1590                 return false;
1591             }
1592         }
1593         if (ComponentTypeEnum.RESOURCE == componentType) {
1594             return isUniqueArtifactNameInResourceInterfaces(componentId, artifactName, artifactInfo.getArtifactLabel());
1595         }
1596         return true;
1597     }
1598
1599     private boolean isUniqueArtifactNameInResourceInterfaces(String componentId, String artifactName, String artifactLabel) {
1600         Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1601             .getAllInterfacesOfResource(componentId, true, true);
1602         if (allInterfacesOfResource.isLeft()) {
1603             return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1604                 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1605                 .noneMatch(add -> artifactName.equals(add.getArtifactName()) && !artifactLabel.equals(add.getArtifactLabel()));
1606         }
1607         return true;
1608     }
1609
1610     private boolean isUniqueLabelInResourceInterfaces(String componentId, String artifactLabel) {
1611         Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation
1612             .getAllInterfacesOfResource(componentId, true, true);
1613         if (allInterfacesOfResource.isLeft()) {
1614             return allInterfacesOfResource.left().value().values().stream().map(InterfaceDefinition::getOperationsMap)
1615                 .flatMap(map -> map.values().stream()).map(OperationDataDefinition::getImplementation).filter(Objects::nonNull)
1616                 .noneMatch(add -> artifactLabel.equals(add.getArtifactLabel()));
1617         }
1618         return true;
1619     }
1620
1621     private Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(ComponentTypeEnum componentType, Component parentComponent,
1622                                                                                          String componentId,
1623                                                                                          ArtifactGroupTypeEnum artifactGroupType) {
1624         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse;
1625         if (componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1626             artifactsResponse = artifactToscaOperation.getAllInstanceArtifacts(parentComponent.getUniqueId(), componentId);
1627         } else {
1628             artifactsResponse = artifactToscaOperation.getArtifacts(componentId);
1629         }
1630         if (artifactsResponse.isRight() && artifactsResponse.right().value() == StorageOperationStatus.NOT_FOUND) {
1631             log.debug("failed to retrieve artifacts for {} ", componentId);
1632             return Either.right(artifactsResponse.right().value());
1633         }
1634         return Either.left(artifactsResponse.left().value().entrySet().stream().filter(x -> artifactGroupType == x.getValue().getArtifactGroupType())
1635             .collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
1636     }
1637
1638     // ***************************************************************
1639     private Either<ArtifactDefinition, Operation> createArtifact(Component parent, String parentId, ArtifactDefinition artifactInfo,
1640                                                                  byte[] decodedPayload, ComponentTypeEnum componentTypeEnum,
1641                                                                  AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) {
1642         DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
1643         if (artifactData == null) {
1644             BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact");
1645             log.debug("Failed to create artifact object for ES.");
1646             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1647         }
1648         ComponentInstance foundInstance = findComponentInstance(parentId, parent);
1649         String instanceId = null;
1650         if (foundInstance != null) {
1651             if (foundInstance.isArtifactExists(artifactInfo.getArtifactGroupType(), artifactInfo.getArtifactLabel())) {
1652                 log.debug("Failed to create artifact, already exists");
1653                 throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_EXIST, artifactInfo.getArtifactLabel());
1654             }
1655             instanceId = foundInstance.getUniqueId();
1656         }
1657         // set on graph object id of artifact in ES!
1658         artifactInfo.setEsId(artifactData.getId());
1659         Either<ArtifactDefinition, Operation> operationResult;
1660         if (interfaceType != null && operationName != null) {
1661             // lifecycle artifact
1662             Operation operation = convertToOperation(artifactInfo, operationName);
1663             Either<Operation, StorageOperationStatus> result = interfaceLifecycleOperation
1664                 .updateInterfaceOperation(parentId, interfaceType, operationName, operation);
1665             if (result.isRight()) {
1666                 throw new StorageException(result.right().value());
1667             }
1668             operationResult = Either.right(result.left().value());
1669         } else {
1670             // information/deployment/api artifacts
1671             NodeTypeEnum nodeType = convertParentType(componentTypeEnum);
1672             Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
1673                 .addArtifactToComponent(artifactInfo, parent, nodeType, true, instanceId);
1674             if (result.isRight()) {
1675                 throw new StorageException(result.right().value());
1676             }
1677             ArtifactDefinition artifactDefinition = result.left().value();
1678             artifactData.setId(artifactDefinition.getEsId());
1679             operationResult = Either.left(artifactDefinition);
1680             if (generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum) != StorageOperationStatus.OK) {
1681                 throw new StorageException(generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentTypeEnum));
1682             }
1683         }
1684         saveArtifactInCassandra(artifactData, parent, artifactInfo, "", "", auditingActionEnum, componentTypeEnum);
1685         return operationResult;
1686     }
1687
1688     private ComponentInstance findComponentInstance(String componentInstanceId, Component containerComponent) {
1689         ComponentInstance foundInstance = null;
1690         if (CollectionUtils.isNotEmpty(containerComponent.getComponentInstances())) {
1691             foundInstance = containerComponent.getComponentInstances().stream().filter(i -> i.getUniqueId().equals(componentInstanceId)).findFirst()
1692                 .orElse(null);
1693         }
1694         return foundInstance;
1695     }
1696
1697     private void validateDeploymentArtifact(final ArtifactDefinition artifactInfo, final Component component) {
1698         final ComponentTypeEnum componentType = component.getComponentType();
1699         if (componentType != ComponentTypeEnum.RESOURCE && componentType != ComponentTypeEnum.SERVICE
1700             && componentType != ComponentTypeEnum.RESOURCE_INSTANCE) {
1701             log.debug("Invalid component type '{}' for artifact. " + "Expected Resource, Component or Resource Instance", componentType.getValue());
1702             throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, componentType.getValue(),
1703                 "Service, Resource or ResourceInstance", componentType.getValue());
1704         }
1705         final String artifactType = artifactInfo.getArtifactType();
1706         final ArtifactConfiguration artifactConfiguration = loadArtifactTypeConfig(artifactType).orElse(null);
1707         if (artifactConfiguration == null) {
1708             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactType);
1709         }
1710         validateArtifactType(componentType, artifactInfo.getArtifactGroupType(), artifactConfiguration);
1711         if (componentType == ComponentTypeEnum.RESOURCE || componentType == ComponentTypeEnum.RESOURCE_INSTANCE) {
1712             final Resource resource = (Resource) component;
1713             final ResourceTypeEnum resourceType = resource.getResourceType();
1714             validateResourceType(resourceType, artifactInfo, artifactConfiguration.getResourceTypes());
1715         }
1716         validateArtifactExtension(artifactConfiguration, artifactInfo);
1717     }
1718
1719     private void validateHeatArtifact(final Component parentComponent, final String componentId, final ArtifactDefinition artifactDefinition) {
1720         final String artifactType = artifactDefinition.getArtifactType();
1721         final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1722         if (artifactTypeEnum == null) {
1723             return;
1724         }
1725         switch (artifactTypeEnum) {
1726             case HEAT:
1727             case HEAT_VOL:
1728             case HEAT_NET:
1729                 validateHeatTimeoutValue(artifactDefinition);
1730                 break;
1731             case HEAT_ENV:
1732                 validateHeatEnvDeploymentArtifact(parentComponent, componentId, artifactDefinition);
1733                 break;
1734             default:
1735                 break;
1736         }
1737     }
1738
1739     private void setArtifactTimeout(final ArtifactDefinition newArtifactInfo, final ArtifactDefinition existingArtifactInfo) {
1740         final String artifactType = newArtifactInfo.getArtifactType();
1741         final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
1742         if (artifactTypeEnum == null) {
1743             newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1744             return;
1745         }
1746         switch (artifactTypeEnum) {
1747             case HEAT:
1748             case HEAT_VOL:
1749             case HEAT_NET:
1750                 if (newArtifactInfo.getTimeout() == null) {
1751                     if (existingArtifactInfo == null) {
1752                         newArtifactInfo.setTimeout(NodeTemplateOperation.getDefaultHeatTimeout());
1753                     } else {
1754                         newArtifactInfo.setTimeout(existingArtifactInfo.getTimeout());
1755                     }
1756                 }
1757                 break;
1758             default:
1759                 newArtifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
1760                 break;
1761         }
1762     }
1763
1764     @VisibleForTesting
1765     void validateDeploymentArtifactTypeIsLegalForParent(ArtifactDefinition artifactInfo, ArtifactTypeEnum artifactType,
1766                                                         Map<String, ArtifactTypeConfig> resourceDeploymentArtifacts) {
1767         if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) {
1768             log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType());
1769             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType());
1770         }
1771     }
1772
1773     Optional<ArtifactConfiguration> loadArtifactTypeConfig(final String artifactType) {
1774         if (artifactType == null) {
1775             return Optional.empty();
1776         }
1777         final List<ArtifactConfiguration> artifactConfigurationList = ConfigurationManager.getConfigurationManager().getConfiguration()
1778             .getArtifacts();
1779         if (CollectionUtils.isEmpty(artifactConfigurationList)) {
1780             return Optional.empty();
1781         }
1782         return artifactConfigurationList.stream().filter(artifactConfiguration -> artifactConfiguration.getType().equalsIgnoreCase(artifactType))
1783             .findFirst();
1784     }
1785
1786     private Either<Boolean, ResponseFormat> extractHeatParameters(ArtifactDefinition artifactInfo) {
1787         // extract heat parameters
1788         if (artifactInfo.getPayloadData() != null) {
1789             String heatDecodedPayload = new String(Base64.decodeBase64(artifactInfo.getPayloadData()));
1790             Either<List<HeatParameterDefinition>, ResultStatusEnum> heatParameters = ImportUtils
1791                 .getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo.getArtifactType());
1792             if (heatParameters.isRight() && (heatParameters.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND)) {
1793                 log.info("failed to parse heat parameters ");
1794                 ResponseFormat responseFormat = componentsUtils
1795                     .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactType());
1796                 return Either.right(responseFormat);
1797             } else if (heatParameters.isLeft() && heatParameters.left().value() != null) {
1798                 artifactInfo.setListHeatParameters(heatParameters.left().value());
1799             }
1800         }
1801         return Either.left(true);
1802     }
1803
1804     @VisibleForTesting
1805     void validateArtifactExtension(final ArtifactConfiguration artifactConfiguration, final ArtifactDefinition artifactDefinition) {
1806         final List<String> acceptedTypes = artifactConfiguration.getAcceptedTypes();
1807         /*
1808          * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted.
1809          */
1810         if (CollectionUtils.isEmpty(acceptedTypes)) {
1811             return;
1812         }
1813         final String artifactName = artifactDefinition.getArtifactName();
1814         final String fileExtension = FilenameUtils.getExtension(artifactName);
1815         if (fileExtension == null || !acceptedTypes.contains(fileExtension.toLowerCase())) {
1816             final String artifactType = artifactDefinition.getArtifactType();
1817             log.debug("File extension \"{}\" is not allowed for artifact type \"{}\"", fileExtension, artifactType);
1818             throw new ByActionStatusComponentException(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, artifactType);
1819         }
1820     }
1821
1822     @VisibleForTesting
1823     void validateHeatEnvDeploymentArtifact(final Component parentComponent, final String parentId, final ArtifactDefinition artifactInfo) {
1824         final Wrapper<ArtifactDefinition> heatMDWrapper = new Wrapper<>();
1825         final Wrapper<byte[]> payloadWrapper = new Wrapper<>();
1826         validateYaml(artifactInfo);
1827         validateHeatExist(parentComponent.getUniqueId(), parentId, heatMDWrapper, artifactInfo, parentComponent.getComponentType());
1828         if (!heatMDWrapper.isEmpty()) {
1829             fillArtifactPayload(payloadWrapper, heatMDWrapper.getInnerElement());
1830         }
1831         if (!heatMDWrapper.isEmpty()) {
1832             validateEnvVsHeat(artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement());
1833         }
1834     }
1835
1836     public void fillArtifactPayload(Wrapper<byte[]> payloadWrapper, ArtifactDefinition artifactDefinition) {
1837         if (ArrayUtils.isEmpty(artifactDefinition.getPayloadData())) {
1838             Either<DAOArtifactData, CassandraOperationStatus> eitherArtifactData = artifactCassandraDao.getArtifact(artifactDefinition.getEsId());
1839             if (eitherArtifactData.isLeft()) {
1840                 byte[] data = eitherArtifactData.left().value().getDataAsArray();
1841                 payloadWrapper.setInnerElement(Base64.encodeBase64(data));
1842             } else {
1843                 log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName());
1844                 throw new StorageException(DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()));
1845             }
1846         } else {
1847             payloadWrapper.setInnerElement(artifactDefinition.getPayloadData());
1848         }
1849     }
1850
1851     private void validateEnvVsHeat(ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) {
1852         String envPayload = new String(Base64.decodeBase64(envArtifact.getPayloadData()));
1853         Map<String, Object> heatEnvToscaJson = (Map<String, Object>) new Yaml().load(envPayload);
1854         String heatDecodedPayload = new String(Base64.decodeBase64(heatPayloadData));
1855         Map<String, Object> heatToscaJson = (Map<String, Object>) new Yaml().load(heatDecodedPayload);
1856         Either<Map<String, Object>, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils
1857             .findFirstToscaMapElement(heatEnvToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1858         if (eitherHeatEnvProperties.isRight()) {
1859             log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName());
1860             throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat Env");
1861         }
1862         Either<Map<String, Object>, ResultStatusEnum> eitherHeatProperties = ImportUtils
1863             .findFirstToscaMapElement(heatToscaJson, TypeUtils.ToscaTagNamesEnum.PARAMETERS);
1864         if (eitherHeatProperties.isRight()) {
1865             log.debug("Invalid heat format for file:{}", heatArtifact.getArtifactName());
1866             throw new ByActionStatusComponentException(ActionStatus.CORRUPTED_FORMAT, "Heat");
1867         }
1868         Set<String> heatPropertiesKeys = eitherHeatProperties.left().value().keySet();
1869         Set<String> heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet();
1870         heatEnvPropertiesKeys.removeAll(heatPropertiesKeys);
1871         if (!heatEnvPropertiesKeys.isEmpty()) {
1872             log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(),
1873                 heatArtifact.getArtifactName());
1874             throw new ByActionStatusComponentException(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(),
1875                 heatArtifact.getArtifactName());
1876         }
1877     }
1878
1879     private void validateYaml(ArtifactDefinition artifactInfo) {
1880         YamlToObjectConverter yamlConverter = new YamlToObjectConverter();
1881         boolean isYamlValid = yamlConverter.isValidYamlEncoded64(artifactInfo.getPayloadData());
1882         if (!isYamlValid) {
1883             log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName());
1884             throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType());
1885         }
1886     }
1887
1888     private void validateSingleDeploymentArtifactName(final String artifactName, final Component parentComponent) {
1889         boolean artifactNameFound = false;
1890         final Iterator<ArtifactDefinition> parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, null).iterator();
1891         while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) {
1892             artifactNameFound = artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName());
1893         }
1894         if (artifactNameFound) {
1895             final ComponentTypeEnum componentType = parentComponent.getComponentType();
1896             log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName);
1897             throw new ByActionStatusComponentException(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, componentType.getValue(),
1898                 parentComponent.getName(), artifactName);
1899         }
1900     }
1901
1902     private void validateHeatExist(String componentId, String parentRiId, Wrapper<ArtifactDefinition> heatArtifactMDWrapper,
1903                                    ArtifactDefinition heatEnvArtifact, ComponentTypeEnum componentType) {
1904         final Either<ArtifactDefinition, StorageOperationStatus> res = artifactToscaOperation
1905             .getHeatArtifactByHeatEnvId(parentRiId, heatEnvArtifact, componentId, componentType);
1906         if (res.isRight()) {
1907             throw new ByActionStatusComponentException(ActionStatus.MISSING_HEAT);
1908         }
1909         heatArtifactMDWrapper.setInnerElement(res.left().value());
1910     }
1911
1912     @VisibleForTesting
1913     void validateHeatTimeoutValue(final ArtifactDefinition artifactInfo) {
1914         log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel());
1915         // timeout > 0 for HEAT artifacts
1916         if (artifactInfo.getTimeout() == null || artifactInfo.getTimeout() < 1) {
1917             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
1918         }
1919         // US649856 - Allow several HEAT files on Resource
1920         log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel());
1921     }
1922
1923     @VisibleForTesting
1924     void validateResourceType(final ResourceTypeEnum resourceType, final ArtifactDefinition artifactInfo, final List<String> typeList) {
1925         if (CollectionUtils.isEmpty(typeList) || typeList.contains(resourceType.getValue())) {
1926             return;
1927         }
1928         final String listToString = typeList.stream().collect(Collectors.joining(", "));
1929         throw new ByActionStatusComponentException(MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, artifactInfo.getArtifactGroupType().getType(),
1930             listToString, resourceType.getValue());
1931     }
1932
1933     @VisibleForTesting
1934     Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParameters(ArtifactDefinition artifactInfo, String artifactType) {
1935         if (artifactInfo.getHeatParameters() != null) {
1936             for (HeatParameterDefinition heatParam : artifactInfo.getListHeatParameters()) {
1937                 String parameterType = heatParam.getType();
1938                 HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType);
1939                 String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType();
1940                 if (heatParameterType == null) {
1941                     ResponseFormat responseFormat = componentsUtils
1942                         .getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam.getType());
1943                     return Either.right(responseFormat);
1944                 }
1945                 StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam);
1946                 if (validateAndUpdateProperty != StorageOperationStatus.OK) {
1947                     log.debug("Heat parameter {} is invalid. Status is {}", heatParam.getName(), validateAndUpdateProperty);
1948                     ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE;
1949                     ResponseFormat responseFormat = componentsUtils
1950                         .getResponseFormat(status, artifactTypeStr, heatParam.getType(), heatParam.getName());
1951                     return Either.right(responseFormat);
1952                 }
1953             }
1954         }
1955         return Either.left(artifactInfo);
1956     }
1957
1958     public List<ArtifactDefinition> getDeploymentArtifacts(final Component component, final String ciId) {
1959         final ComponentTypeEnum componentType = component.getComponentType();
1960         if (component.getDeploymentArtifacts() == null) {
1961             return Collections.emptyList();
1962         }
1963         final List<ArtifactDefinition> deploymentArtifacts = new ArrayList<>();
1964         if (ComponentTypeEnum.RESOURCE == componentType && ciId != null) {
1965             final Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(component, ciId, null, null, null);
1966             if (getRI.isRight()) {
1967                 return Collections.emptyList();
1968             }
1969             final ComponentInstance ri = getRI.left().value();
1970             if (ri.getDeploymentArtifacts() != null) {
1971                 deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values());
1972             }
1973         } else {
1974             deploymentArtifacts.addAll(component.getDeploymentArtifacts().values());
1975         }
1976         return deploymentArtifacts;
1977     }
1978
1979     private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) {
1980         // on create if null add informational to current
1981         if (artifactInfo.getArtifactGroupType() == null) {
1982             artifactInfo.setArtifactGroupType(type);
1983         }
1984         if (artifactInfo.getUniqueId() != null) {
1985             log.error("artifact uniqid cannot be set ignoring");
1986         }
1987         artifactInfo.setUniqueId(null);
1988         if (artifactInfo.getArtifactRef() != null) {
1989             log.error("artifact ref cannot be set ignoring");
1990         }
1991         artifactInfo.setArtifactRef(null);
1992         if (artifactInfo.getArtifactRepository() != null) {
1993             log.error("artifact repository cannot be set ignoring");
1994         }
1995         artifactInfo.setArtifactRepository(null);
1996         if (artifactInfo.getUserIdCreator() != null) {
1997             log.error("creator uuid cannot be set ignoring");
1998         }
1999         artifactInfo.setArtifactCreator(user.getUserId());
2000         if (artifactInfo.getUserIdLastUpdater() != null) {
2001             log.error("userId of last updater cannot be set ignoring");
2002         }
2003         artifactInfo.setUserIdLastUpdater(user.getUserId());
2004         if (artifactInfo.getCreatorFullName() != null) {
2005             log.error("creator Full name cannot be set ignoring");
2006         }
2007         String fullName = user.getFirstName() + " " + user.getLastName();
2008         artifactInfo.setUpdaterFullName(fullName);
2009         if (artifactInfo.getUpdaterFullName() != null) {
2010             log.error("updater Full name cannot be set ignoring");
2011         }
2012         artifactInfo.setUpdaterFullName(fullName);
2013         if (artifactInfo.getCreationDate() != null) {
2014             log.error("Creation Date cannot be set ignoring");
2015         }
2016         long time = System.currentTimeMillis();
2017         artifactInfo.setCreationDate(time);
2018         if (artifactInfo.getLastUpdateDate() != null) {
2019             log.error("Last Update Date cannot be set ignoring");
2020         }
2021         artifactInfo.setLastUpdateDate(time);
2022         if (artifactInfo.getEsId() != null) {
2023             log.error("es id cannot be set ignoring");
2024         }
2025         artifactInfo.setEsId(null);
2026     }
2027
2028     private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName,
2029                                      String operationName) {
2030         String id = artifactId;
2031         if (artifactId == null || artifactId.isEmpty()) {
2032             String uniqueId = null;
2033             if (interfaceName != null && operationName != null) {
2034                 uniqueId = UniqueIdBuilder
2035                     .buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo.getArtifactLabel());
2036             } else {
2037                 uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel());
2038             }
2039             artifactInfo.setUniqueId(uniqueId);
2040             artifactInfo.setEsId(uniqueId);
2041             id = uniqueId;
2042         } else {
2043             artifactInfo.setUniqueId(artifactId);
2044             artifactInfo.setEsId(artifactId);
2045         }
2046         return id;
2047     }
2048
2049     private Either<Boolean, ResponseFormat> validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2050         if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) {
2051             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD));
2052         }
2053         return Either.left(true);
2054     }
2055
2056     @VisibleForTesting
2057     Either<Boolean, ResponseFormat> validateAndSetArtifactName(ArtifactDefinition artifactInfo) {
2058         if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) {
2059             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2060         }
2061         String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName());
2062         if (normalizeFileName == null || normalizeFileName.isEmpty()) {
2063             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME));
2064         }
2065         artifactInfo.setArtifactName(normalizeFileName);
2066         if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) {
2067             return Either.right(
2068                 componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH)));
2069         }
2070         return Either.left(true);
2071     }
2072
2073     private void validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) {
2074         if (StringUtils.isEmpty(artifactInfo.getArtifactType())) {
2075             log.info("artifact type is missing operation ignored");
2076             throw new ByActionStatusComponentException(ActionStatus.MISSING_ARTIFACT_TYPE);
2077         }
2078         if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) {
2079             log.info("artifact type cannot be changed operation ignored");
2080             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2081         }
2082     }
2083
2084     private Either<ArtifactDefinition, ResponseFormat> validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo,
2085                                                                                       ArtifactDefinition currentArtifact) {
2086         if (null != artifactInfo && null != currentArtifact) {
2087             if (artifactInfo.getArtifactGroupType() == null) {
2088                 artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2089             } else if (!currentArtifact.getArtifactGroupType().getType().equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) {
2090                 log.info("artifact group type cannot be changed. operation failed");
2091                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2092             }
2093         }
2094         return Either.left(artifactInfo);
2095     }
2096
2097     private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact,
2098                                               ArtifactGroupTypeEnum type) {
2099         // on update if null add informational to current
2100         if (currentArtifact.getArtifactGroupType() == null && type != null) {
2101             currentArtifact.setArtifactGroupType(type);
2102         }
2103         if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) {
2104             log.error("artifact uniqid cannot be set ignoring");
2105         }
2106         artifactInfo.setUniqueId(currentArtifact.getUniqueId());
2107         if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef().equals(artifactInfo.getArtifactRef())) {
2108             log.error("artifact ref cannot be set ignoring");
2109         }
2110         artifactInfo.setArtifactRef(currentArtifact.getArtifactRef());
2111         if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository().equals(artifactInfo.getArtifactRepository())) {
2112             log.error("artifact repository cannot be set ignoring");
2113         }
2114         artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository());
2115         if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator().equals(artifactInfo.getUserIdCreator())) {
2116             log.error("creator uuid cannot be set ignoring");
2117         }
2118         artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator());
2119         if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator().equals(artifactInfo.getArtifactCreator())) {
2120             log.error("artifact creator cannot be set ignoring");
2121         }
2122         artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator());
2123         if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater().equals(artifactInfo.getUserIdLastUpdater())) {
2124             log.error("userId of last updater cannot be set ignoring");
2125         }
2126         artifactInfo.setUserIdLastUpdater(user.getUserId());
2127         if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName().equals(artifactInfo.getCreatorFullName())) {
2128             log.error("creator Full name cannot be set ignoring");
2129         }
2130         artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName());
2131         if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName().equals(artifactInfo.getUpdaterFullName())) {
2132             log.error("updater Full name cannot be set ignoring");
2133         }
2134         String fullName = user.getFirstName() + " " + user.getLastName();
2135         artifactInfo.setUpdaterFullName(fullName);
2136         if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate().equals(artifactInfo.getCreationDate())) {
2137             log.error("Creation Date cannot be set ignoring");
2138         }
2139         artifactInfo.setCreationDate(currentArtifact.getCreationDate());
2140         if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate().equals(artifactInfo.getLastUpdateDate())) {
2141             log.error("Last Update Date cannot be set ignoring");
2142         }
2143         long time = System.currentTimeMillis();
2144         artifactInfo.setLastUpdateDate(time);
2145         if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) {
2146             log.error("es id cannot be set ignoring");
2147         }
2148         artifactInfo.setEsId(currentArtifact.getUniqueId());
2149         if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName()
2150             .equals(artifactInfo.getArtifactDisplayName())) {
2151             log.error(" Artifact Display Name cannot be set ignoring");
2152         }
2153         artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName());
2154         if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi().equals(artifactInfo.getServiceApi())) {
2155             log.debug("serviceApi cannot be set. ignoring.");
2156         }
2157         artifactInfo.setServiceApi(currentArtifact.getServiceApi());
2158         if (artifactInfo.getArtifactGroupType() != null && currentArtifact.getArtifactGroupType() != artifactInfo.getArtifactGroupType()) {
2159             log.debug("artifact group cannot be set. ignoring.");
2160         }
2161         artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType());
2162         artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion());
2163         if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID().isEmpty() && !currentArtifact.getArtifactUUID()
2164             .equals(artifactInfo.getArtifactUUID())) {
2165             log.debug("artifact UUID cannot be set. ignoring.");
2166         }
2167         artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID());
2168         if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo.getHeatParameters().isEmpty()
2169             && !currentArtifact.getHeatParameters().isEmpty()) {
2170             checkAndSetUnupdatableHeatParams(artifactInfo.getListHeatParameters(), currentArtifact.getListHeatParameters());
2171         }
2172     }
2173
2174     private void checkAndSetUnupdatableHeatParams(List<HeatParameterDefinition> heatParameters, List<HeatParameterDefinition> currentParameters) {
2175         Map<String, HeatParameterDefinition> currentParametersMap = getMapOfParameters(currentParameters);
2176         for (HeatParameterDefinition parameter : heatParameters) {
2177             HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId());
2178             if (currentParam != null) {
2179                 if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) {
2180                     log.debug("heat parameter name cannot be updated  ({}). ignoring.", parameter.getName());
2181                     parameter.setName(currentParam.getName());
2182                 }
2183                 if (parameter.getDefaultValue() != null && !parameter.getDefaultValue().equalsIgnoreCase(currentParam.getDefaultValue())) {
2184                     log.debug("heat parameter defaultValue cannot be updated  ({}). ignoring.", parameter.getDefaultValue());
2185                     parameter.setDefaultValue(currentParam.getDefaultValue());
2186                 }
2187                 if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) {
2188                     log.debug("heat parameter type cannot be updated  ({}). ignoring.", parameter.getType());
2189                     parameter.setType(currentParam.getType());
2190                 }
2191                 if (parameter.getDescription() != null && !parameter.getDescription().equalsIgnoreCase(currentParam.getDescription())) {
2192                     log.debug("heat parameter description cannot be updated  ({}). ignoring.", parameter.getDescription());
2193                     parameter.setDescription(currentParam.getDescription());
2194                 }
2195                 // check and set current value
2196                 if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) {
2197                     log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue());
2198                     parameter.setCurrentValue(currentParam.getDefaultValue());
2199                 }
2200             }
2201         }
2202     }
2203
2204     private Map<String, HeatParameterDefinition> getMapOfParameters(List<HeatParameterDefinition> currentParameters) {
2205         Map<String, HeatParameterDefinition> currentParamsMap = new HashMap<>();
2206         for (HeatParameterDefinition param : currentParameters) {
2207             currentParamsMap.put(param.getUniqueId(), param);
2208         }
2209         return currentParamsMap;
2210     }
2211
2212     private Either<Boolean, ResponseFormat> validateAndServiceApiUrl(ArtifactDefinition artifactInfo) {
2213         if (!ValidationUtils.validateStringNotEmpty(artifactInfo.getApiUrl())) {
2214             log.debug("Artifact url cannot be empty.");
2215             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL));
2216         }
2217         artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase());
2218         if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) {
2219             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL));
2220         }
2221         if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) {
2222             return Either
2223                 .right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH)));
2224         }
2225         return Either.left(true);
2226     }
2227
2228     private Either<Boolean, ResponseFormat> validateAndCleanDescription(ArtifactDefinition artifactInfo) {
2229         if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) {
2230             log.debug("Artifact description cannot be empty.");
2231             return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION));
2232         }
2233         String description = artifactInfo.getDescription();
2234         description = ValidationUtils.removeNoneUtf8Chars(description);
2235         description = ValidationUtils.normaliseWhitespace(description);
2236         description = ValidationUtils.stripOctets(description);
2237         description = ValidationUtils.removeHtmlTagsOnly(description);
2238         if (!ValidationUtils.validateIsEnglish(description)) {
2239             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
2240         }
2241         if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) {
2242             return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION,
2243                 String.valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)));
2244         }
2245         artifactInfo.setDescription(description);
2246         return Either.left(true);
2247     }
2248
2249     private <T> Either<ArtifactDefinition, T> updateArtifactFlow(Component parent, String parentId, String artifactId,
2250                                                                  ArtifactDefinition artifactInfo, byte[] decodedPayload,
2251                                                                  ComponentTypeEnum componentType, AuditingActionEnum auditingAction) {
2252         DAOArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload);
2253         if (artifactData == null) {
2254             BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2255             log.debug("Failed to create artifact object for ES.");
2256             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
2257         }
2258         log.debug("Entry on graph is updated. Update artifact in ES");
2259         // Changing previous and current artifactId for auditing
2260         String currArtifactId = artifactInfo.getUniqueId();
2261         NodeTypeEnum parentType = convertParentType(componentType);
2262         if (decodedPayload == null) {
2263             if (!artifactInfo.getMandatory() || artifactInfo.getEsId() != null) {
2264                 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactInfo.getEsId());
2265                 if (artifactFromCassandra.isRight()) {
2266                     throw new StorageException(artifactFromCassandra.right().value());
2267                 }
2268                 // clone data to new artifact
2269                 artifactData.setData(artifactFromCassandra.left().value().getData());
2270                 artifactData.setId(artifactFromCassandra.left().value().getId());
2271             }
2272         } else if (artifactInfo.getEsId() == null) {
2273             artifactInfo.setEsId(artifactInfo.getUniqueId());
2274             artifactData.setId(artifactInfo.getUniqueId());
2275         }
2276         Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation
2277             .updateArtifactOnResource(artifactInfo, parent, artifactId, parentType, parentId, true);
2278         if (result.isRight()) {
2279             throw new StorageException(result.right().value());
2280         }
2281         ArtifactDefinition artifactDefinition = result.left().value();
2282         updateGeneratedIdInHeatEnv(parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType);
2283         StorageOperationStatus storageOperationStatus = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
2284         if (storageOperationStatus != StorageOperationStatus.OK) {
2285             throw new StorageException(storageOperationStatus);
2286         }
2287         if (artifactData.getData() != null) {
2288             if (!artifactDefinition.getDuplicated() || artifactData.getId() == null) {
2289                 artifactData.setId(artifactDefinition.getEsId());
2290             }
2291             saveArtifactInCassandra(artifactData, parent, artifactInfo, currArtifactId, artifactId, auditingAction, componentType);
2292         }
2293         return Either.left(artifactDefinition);
2294     }
2295
2296     private String updateGeneratedIdInHeatEnv(Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo,
2297                                               ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2298         if (NodeTypeEnum.Resource == parentType) {
2299             return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parent, parentId, artifactId, artifactInfo, artifactDefinition,
2300                 parentType, false);
2301         }
2302         return artifactDefinition.getUniqueId();
2303     }
2304
2305     private String updateGeneratedIdInHeatEnv(Map<String, ArtifactDefinition> deploymentArtifacts, Component parentComponent, String parentId,
2306                                               String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2307                                               NodeTypeEnum parentType, boolean isInstanceArtifact) {
2308         String artifactUniqueId;
2309         artifactUniqueId = artifactDefinition.getUniqueId();
2310         String artifactType = artifactInfo.getArtifactType();
2311         if ((ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType)
2312             || ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType)) && !artifactUniqueId.equals(artifactId)) {
2313             // need to update the generated id in heat env
2314             Optional<Entry<String, ArtifactDefinition>> findFirst = deploymentArtifacts.entrySet().stream()
2315                 .filter(a -> artifactId.equals(a.getValue().getGeneratedFromId())).findFirst();
2316             if (findFirst.isPresent()) {
2317                 ArtifactDefinition artifactEnvInfo = findFirst.get().getValue();
2318                 artifactEnvInfo.setIsFromCsar(artifactDefinition.getIsFromCsar());
2319                 artifactEnvInfo.setArtifactChecksum(null);
2320                 if (isInstanceArtifact) {
2321                     artifactToscaOperation
2322                         .updateHeatEnvArtifactOnInstance(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2323                 } else {
2324                     artifactToscaOperation
2325                         .updateHeatEnvArtifact(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2326                 }
2327             }
2328         }
2329         return artifactUniqueId;
2330     }
2331
2332     private String updateGeneratedIdInHeatEnvOnInstance(ComponentInstance parent, Component parentComponent, String artifactId,
2333                                                         ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition,
2334                                                         NodeTypeEnum parentType) {
2335         return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parentComponent, parent.getUniqueId(), artifactId, artifactInfo,
2336             artifactDefinition, parentType, true);
2337     }
2338
2339     @VisibleForTesting
2340     private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) {
2341         log.trace("Starting payload handling");
2342         byte[] payload = artifactInfo.getPayloadData();
2343         byte[] decodedPayload = null;
2344         if (payload != null && payload.length != 0) {
2345             // the generated artifacts were already decoded by the handler
2346             decodedPayload = artifactInfo.getGenerated() ? payload : Base64.decodeBase64(payload);
2347             if (decodedPayload.length == 0) {
2348                 log.debug("Failed to decode the payload.");
2349                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
2350                 return Either.right(responseFormat);
2351             }
2352             String checkSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(decodedPayload);
2353             artifactInfo.setArtifactChecksum(checkSum);
2354             log.trace("Calculated checksum, base64 payload: {},  checksum: {}", payload, checkSum);
2355             // Specific payload validations of different types
2356             Either<Boolean, ResponseFormat> result = Either.left(true);
2357             if (isDeploymentArtifact(artifactInfo)) {
2358                 log.trace("Starting deployment artifacts payload validation");
2359                 String artifactType = artifactInfo.getArtifactType();
2360                 String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName());
2361                 PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension);
2362                 final Optional<ResponseFormat> pmDictionaryError = validateIfPmDictionary(artifactType, decodedPayload);
2363                 if (pmDictionaryError.isPresent()) {
2364                     return Either.right(pmDictionaryError.get());
2365                 }
2366                 Either<Boolean, ActionStatus> isPayloadValid = payloadType.isValid(decodedPayload);
2367                 if (isPayloadValid.isRight()) {
2368                     ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType);
2369                     return Either.right(responseFormat);
2370                 }
2371                 if (payloadType.isHeatRelated()) {
2372                     log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType);
2373                     result = extractHeatParameters(artifactInfo);
2374                 }
2375             }
2376             if (result.isRight()) {
2377                 return Either.right(result.right().value());
2378             }
2379         } // null/empty payload is normal if called from metadata update ONLY.
2380
2381         // The validation of whether this is metadata/payload update case is
2382
2383         // currently done separately
2384         else {
2385             if (!isArtifactMetadataUpdate) {
2386                 log.debug("In artifact: {} Payload is missing.", artifactInfo.getArtifactName());
2387                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
2388                 return Either.right(responseFormat);
2389             }
2390         }
2391         log.trace("Ended payload handling");
2392         return Either.left(decodedPayload);
2393     }
2394
2395     private Optional<ResponseFormat> validateIfPmDictionary(String artifactType, byte[] decodedPayload) {
2396         return new PMDictionaryValidator().validateIfPmDictionary(artifactType, decodedPayload).map(this::preparePmDictionaryResponse);
2397     }
2398
2399     private ResponseFormat preparePmDictionaryResponse(String errorMessage) {
2400         return componentsUtils.getResponseFormat(ActionStatus.INVALID_PM_DICTIONARY_FILE, errorMessage);
2401     }
2402
2403     public Either<ArtifactDefinition, ResponseFormat> deleteArtifactByInterface(String resourceId, String userUserId, String artifactId,
2404                                                                                 boolean inTransaction) {
2405         return toscaOperationFacade.getToscaElement(resourceId, JsonParseFlagEnum.ParseMetadata).right().map(componentsUtils.toResponseFormat())
2406             .left().bind(parentComponent -> {
2407                 User user = new User(userUserId);
2408                 return handleDelete(resourceId, artifactId, user, parentComponent, false, inTransaction);
2409             });
2410     }
2411
2412     private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) {
2413         Operation op = new Operation();
2414         long time = System.currentTimeMillis();
2415         op.setCreationDate(time);
2416         String artifactName = artifactInfo.getArtifactName();
2417         artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName));
2418         op.setImplementation(artifactInfo);
2419         op.setLastUpdateDate(time);
2420         return op;
2421     }
2422
2423     private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) {
2424         String newArtifactName = operationName + "_" + artifactName;
2425         log.trace("converting artifact name {} to {}", artifactName, newArtifactName);
2426         return newArtifactName;
2427     }
2428
2429     // download by MSO
2430     public byte[] downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion,
2431                                               String artifactName) {
2432         // General validation
2433         if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) {
2434             log.debug(NULL_PARAMETER);
2435             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2436         }
2437         // Normalizing artifact name
2438         artifactName = ValidationUtils.normalizeFileName(artifactName);
2439         // Resource validation
2440         Resource resource = validateResourceNameAndVersion(resourceName, resourceVersion);
2441         String resourceId = resource.getUniqueId();
2442         // Service validation
2443         Service validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion);
2444         Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts();
2445         if (artifacts == null || artifacts.isEmpty()) {
2446             log.debug("Deployment artifacts of resource {} are not found", resourceId);
2447             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2448         }
2449         ArtifactDefinition deploymentArtifact = null;
2450         for (ArtifactDefinition artifactDefinition : artifacts.values()) {
2451             if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName().equals(artifactName)) {
2452                 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2453                 deploymentArtifact = artifactDefinition;
2454                 break;
2455             }
2456         }
2457         if (deploymentArtifact == null) {
2458             log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId);
2459             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2460         }
2461         // Downloading the artifact
2462         ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deploymentArtifact);
2463         log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId());
2464         return downloadArtifactEither.getRight();
2465     }
2466
2467     // download by MSO
2468     public byte[] downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) {
2469         // General validation
2470         if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) {
2471             log.debug(NULL_PARAMETER);
2472             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2473         }
2474         // Normalizing artifact name
2475         artifactName = ValidationUtils.normalizeFileName(artifactName);
2476         // Service validation
2477         Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2478         // ResourceInstance validation
2479         ComponentInstance resourceInstance = validateResourceInstance(service, resourceInstanceName);
2480         Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
2481         final String finalArtifactName = artifactName;
2482         Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName);
2483         ArtifactDefinition deployableArtifact =
2484             artifacts == null ? null : artifacts.values().stream().filter(filterArtifactByName).findFirst().orElse(null);
2485         if (deployableArtifact == null) {
2486             log.debug("Deployment artifact with name {} not found", artifactName);
2487             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
2488         }
2489         log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2490         ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deployableArtifact);
2491         log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId());
2492         return downloadArtifactEither.getRight();
2493     }
2494
2495     private ComponentInstance validateResourceInstance(Service service, String resourceInstanceName) {
2496         List<ComponentInstance> riList = service.getComponentInstances();
2497         for (ComponentInstance ri : riList) {
2498             if (ri.getNormalizedName().equals(resourceInstanceName)) {
2499                 return ri;
2500             }
2501         }
2502         throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName);
2503     }
2504
2505     private ComponentInstance validateResourceInstanceById(Component component, String resourceInstanceId) {
2506         List<ComponentInstance> riList = component.getComponentInstances();
2507         for (ComponentInstance ri : riList) {
2508             if (ri.getUniqueId().equals(resourceInstanceId)) {
2509                 return ri;
2510             }
2511         }
2512         throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceInstanceId);
2513     }
2514
2515     private Service validateServiceNameAndVersion(String serviceName, String serviceVersion) {
2516         Either<List<Service>, StorageOperationStatus> serviceListBySystemName = toscaOperationFacade
2517             .getBySystemName(ComponentTypeEnum.SERVICE, serviceName);
2518         if (serviceListBySystemName.isRight()) {
2519             log.debug("Couldn't fetch any service with name {}", serviceName);
2520             throw new ByActionStatusComponentException(
2521                 componentsUtils.convertFromStorageResponse(serviceListBySystemName.right().value(), ComponentTypeEnum.SERVICE), serviceName);
2522         }
2523         List<Service> serviceList = serviceListBySystemName.left().value();
2524         if (serviceList == null || serviceList.isEmpty()) {
2525             log.debug("Couldn't fetch any service with name {}", serviceName);
2526             throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceName);
2527         }
2528         Service foundService = null;
2529         for (Service service : serviceList) {
2530             if (service.getVersion().equals(serviceVersion)) {
2531                 log.trace("Found service with version {}", serviceVersion);
2532                 foundService = service;
2533                 break;
2534             }
2535         }
2536         if (foundService == null) {
2537             log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName);
2538             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE.getValue(),
2539                 serviceVersion);
2540         }
2541         return foundService;
2542     }
2543
2544     private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2545         Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade
2546             .getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2547         if (resourceListBySystemName.isRight()) {
2548             log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2549             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()),
2550                 resourceName);
2551         }
2552         return resourceListBySystemName.left().value();
2553     }
2554
2555     public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2556         // Validation
2557         log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion,
2558             artifactName);
2559         if (serviceName == null || serviceVersion == null || artifactName == null) {
2560             log.debug(NULL_PARAMETER);
2561             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2562         }
2563         // Normalizing artifact name
2564         final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2565         // Service validation
2566         Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2567         // Looking for deployment or tosca artifacts
2568         String serviceId = service.getUniqueId();
2569         if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2570             log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2571             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2572         }
2573         Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2574         if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2575             foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2576                 // filters artifact by name
2577                 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2578         }
2579         if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2580             foundArtifactOptl = service.getToscaArtifacts().values().stream()
2581                 // filters TOSCA artifact by name
2582                 .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2583         }
2584         if (!foundArtifactOptl.isPresent()) {
2585             log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2586             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2587         }
2588         log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2589         // Downloading the artifact
2590         ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl.get());
2591         log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2592         return downloadArtifactEither.getRight();
2593     }
2594
2595     public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2596         log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2597         Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2598         if (artifactById.isRight()) {
2599             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2600             log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2601             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2602         }
2603         ArtifactDefinition artifactDefinition = artifactById.left().value();
2604         if (artifactDefinition == null) {
2605             log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2606             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2607         }
2608         return downloadArtifact(artifactDefinition);
2609     }
2610
2611     private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId,
2612                                               ComponentTypeEnum componentType, String containerComponentType) {
2613         ComponentTypeEnum componentForAudit =
2614             null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
2615         componentForAudit.getNodeType();
2616         Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade.getToscaFullElement(componentId);
2617         if (componentResult.isRight()) {
2618             ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND
2619                 : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
2620             ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
2621             log.debug("Service not found, serviceId {}", componentId);
2622             handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
2623             throw new ByActionStatusComponentException(status, componentId);
2624         }
2625         return componentResult.left().value();
2626     }
2627
2628     private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId,
2629                                          ArtifactOperationInfo operation) {
2630         if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
2631             try {
2632                 validateCanWorkOnComponent(component, userId);
2633             } catch (ComponentException e) {
2634                 String uniqueId = component.getUniqueId();
2635                 log.debug("Service status isn't  CHECKOUT or user isn't owner, serviceId {}", uniqueId);
2636                 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(), component.getComponentType(),
2637                     null);
2638                 throw e;
2639             }
2640         }
2641     }
2642
2643     private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId,
2644                                   ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
2645         if (operation.isNotDownload()) {
2646             String role = user.getRole();
2647             if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
2648                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2649                 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
2650                 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2651                 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
2652             }
2653         }
2654     }
2655
2656     private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId,
2657                                     ComponentTypeEnum componentType, boolean inTransaction) {
2658         User user;
2659         try {
2660             user = validateUserExists(userId);
2661         } catch (ByResponseFormatComponentException e) {
2662             ResponseFormat responseFormat = e.getResponseFormat();
2663             handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2664             throw e;
2665         } catch (ByActionStatusComponentException e) {
2666             ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
2667             handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
2668             throw e;
2669         }
2670         return user;
2671     }
2672
2673     private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId, ResponseFormat responseFormat,
2674                                           ComponentTypeEnum componentType, String userId) {
2675         User user = new User();
2676         user.setUserId(userId);
2677         handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
2678     }
2679
2680     protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
2681         AuditingActionEnum auditingAction = null;
2682         switch (operation.getArtifactOperationEnum()) {
2683             case CREATE:
2684                 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
2685                 break;
2686             case UPDATE:
2687                 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API
2688                     : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
2689                 break;
2690             case DELETE:
2691                 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
2692                 break;
2693             case DOWNLOAD:
2694                 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
2695                 break;
2696             default:
2697                 break;
2698         }
2699         return auditingAction;
2700     }
2701
2702     private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
2703         String esArtifactId = artifactDefinition.getEsId();
2704         Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
2705         if (artifactfromES.isRight()) {
2706             CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
2707             StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
2708             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
2709             log.debug("Error when getting artifact from ES, error: {}", actionStatus);
2710             throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
2711         }
2712         DAOArtifactData DAOArtifactData = artifactfromES.left().value();
2713         byte[] data = DAOArtifactData.getDataAsArray();
2714         if (data == null) {
2715             log.debug("Artifact data from cassandra is null");
2716             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
2717         }
2718         String artifactName = artifactDefinition.getArtifactName();
2719         log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
2720         return new ImmutablePair<>(artifactName, data);
2721     }
2722
2723     public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
2724         return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
2725     }
2726
2727     private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo, String currArtifactId,
2728                                          String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
2729         CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
2730         if (resourceUploadStatus == CassandraOperationStatus.OK) {
2731             log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
2732             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
2733             handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2734                 componentType, null);
2735         } else {
2736             BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
2737             log.info(FAILED_SAVE_ARTIFACT);
2738             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2739             handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat,
2740                 componentType, null);
2741             throw new StorageException(resourceUploadStatus);
2742         }
2743     }
2744
2745     private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
2746         return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
2747     }
2748
2749     private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
2750         return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
2751     }
2752
2753     private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
2754         return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
2755     }
2756
2757     private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
2758         final String artifactType = artifactInfo.getArtifactType();
2759         final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
2760         if (artifactTypeEnum == null) {
2761             artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
2762             return false;
2763         }
2764         switch (artifactTypeEnum) {
2765             case HEAT:
2766             case HEAT_VOL:
2767             case HEAT_NET:
2768             case HEAT_ENV:
2769                 return true;
2770             default:
2771                 return false;
2772         }
2773     }
2774
2775     public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap,
2776                                                             String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
2777         User user = userBusinessLogic.getUser(userUserId, inTransaction);
2778         return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
2779     }
2780
2781     public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
2782                                                             ArtifactGroupTypeEnum groupType) {
2783         ArtifactDefinition artifactInfo = new ArtifactDefinition();
2784         String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
2785         String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
2786         String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
2787         artifactInfo.setArtifactDisplayName(artifactName);
2788         artifactInfo.setArtifactLabel(logicalName.toLowerCase());
2789         artifactInfo.setArtifactType(artifactType);
2790         artifactInfo.setDescription(artifactDescription);
2791         artifactInfo.setArtifactGroupType(groupType);
2792         nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
2793         setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
2794         return artifactInfo;
2795     }
2796
2797     private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
2798         String uniqueId = null;
2799         if (resourceId != null) {
2800             uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase());
2801             artifactInfo.setUniqueId(uniqueId);
2802         }
2803         artifactInfo.setUserIdCreator(user.getUserId());
2804         String fullName = user.getFullName();
2805         artifactInfo.setUpdaterFullName(fullName);
2806         long time = System.currentTimeMillis();
2807         artifactInfo.setCreatorFullName(fullName);
2808         artifactInfo.setCreationDate(time);
2809         artifactInfo.setLastUpdateDate(time);
2810         artifactInfo.setUserIdLastUpdater(user.getUserId());
2811         artifactInfo.setMandatory(true);
2812     }
2813
2814     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType,
2815                                                                                         ArtifactGroupTypeEnum groupType, String instanceId) {
2816         return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
2817     }
2818
2819     public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact,
2820                                                                                  Component component, NodeTypeEnum parentType, String instanceId) {
2821         return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
2822     }
2823
2824     private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
2825         byte[] payload = payloadStr.getBytes();
2826         DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
2827         return Either.left(artifactData);
2828     }
2829
2830     /**
2831      * @param artifactDefinition
2832      * @return
2833      */
2834     public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType,
2835                                                                               Component component, String resourceInstanceName, User modifier,
2836                                                                               String instanceId, boolean shouldLock, boolean inTransaction) {
2837         String payload = generateHeatEnvPayload(artifactDefinition);
2838         String prevUUID = artifactDefinition.getArtifactUUID();
2839         ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2840         return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2841             shouldLock, inTransaction).left()
2842             .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2843     }
2844
2845     public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition,
2846                                                                                    ComponentTypeEnum componentType, Component component,
2847                                                                                    String resourceInstanceName, User modifier, boolean shouldLock,
2848                                                                                    boolean inTransaction, String instanceId) {
2849         String payload = generateHeatEnvPayload(artifactDefinition);
2850         String prevUUID = artifactDefinition.getArtifactUUID();
2851         ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
2852         return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId,
2853             shouldLock, inTransaction).left()
2854             .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
2855     }
2856
2857     @VisibleForTesting
2858     Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID,
2859                                                                              ArtifactDefinition clonedBeforeGenerate,
2860                                                                              ArtifactDefinition updatedArtDef) {
2861         if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
2862             List<ComponentInstance> componentInstances = component.getComponentInstances();
2863             if (componentInstances != null) {
2864                 Optional<ComponentInstance> findFirst = componentInstances.stream().filter(ci -> ci.getUniqueId().equals(instanceId)).findFirst();
2865                 if (findFirst.isPresent()) {
2866                     ComponentInstance relevantInst = findFirst.get();
2867                     List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate,
2868                         relevantInst.getGroupInstances());
2869                     if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
2870                         updatedGroupInstances.forEach(gi -> {
2871                             gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
2872                             gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
2873                         });
2874                         Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade
2875                             .updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
2876                         if (status.isRight()) {
2877                             log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
2878                             ResponseFormat responseFormat = componentsUtils
2879                                 .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(status.right().value()),
2880                                     clonedBeforeGenerate.getArtifactDisplayName());
2881                             return Either.right(responseFormat);
2882                         }
2883                     }
2884                 }
2885             }
2886         }
2887         return Either.left(updatedArtDef);
2888     }
2889
2890     private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
2891         List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
2892         StringBuilder sb = new StringBuilder();
2893         sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
2894         sb.append("parameters:\n");
2895         if (heatParameters != null) {
2896             heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2897             List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
2898             for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
2899                 String heatValue = heatParameterDefinition.getCurrentValue();
2900                 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2901                     heatValue = heatParameterDefinition.getDefaultValue();
2902                     if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
2903                         empltyHeatValues.add(heatParameterDefinition);
2904                         continue;
2905                     }
2906                 }
2907                 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
2908                 if (type != null) {
2909                     switch (type) {
2910                         case BOOLEAN:
2911                             sb.append("  ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatValue))
2912                                 .append("\n");
2913                             break;
2914                         case NUMBER:
2915                             sb.append("  ").append(heatParameterDefinition.getName()).append(":").append(" ")
2916                                 .append(new BigDecimal(heatValue).toPlainString()).append("\n");
2917                             break;
2918                         case COMMA_DELIMITED_LIST:
2919                         case JSON:
2920                             sb.append("  ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatValue).append("\n");
2921                             break;
2922                         default:
2923                             String value = heatValue;
2924                             boolean starts = value.startsWith("\"");
2925                             boolean ends = value.endsWith("\"");
2926                             if (!(starts && ends)) {
2927                                 starts = value.startsWith("'");
2928                                 ends = value.endsWith("'");
2929                                 if (!(starts && ends)) {
2930                                     value = "\"" + value + "\"";
2931                                 }
2932                             }
2933                             sb.append("  ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value);
2934                             sb.append("\n");
2935                             break;
2936                     }
2937                 }
2938             }
2939             if (!empltyHeatValues.isEmpty()) {
2940                 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
2941                 empltyHeatValues.forEach(hv -> {
2942                     sb.append("  ").append(hv.getName()).append(":");
2943                     HeatParameterType type = HeatParameterType.isValidType(hv.getType());
2944                     if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv.getCurrentValue())
2945                         || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
2946                         sb.append(" \"\"").append("\n");
2947                     } else {
2948                         sb.append(" ").append("\n");
2949                     }
2950                 });
2951             }
2952         }
2953         sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
2954         // DE265919 fix
2955         return sb.toString().replace("\\\\n", "\n");
2956     }
2957
2958     /**
2959      * @param artifactDefinition
2960      * @param payload
2961      * @return
2962      */
2963     public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2964                                                                                      ComponentTypeEnum componentType, Component component,
2965                                                                                      String resourceInstanceName, User modifier, String instanceId,
2966                                                                                      boolean shouldLock, boolean inTransaction) {
2967         return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2968             artifactDefinition::getHeatParamsUpdateDate, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2969     }
2970
2971     public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload,
2972                                                                                           ComponentTypeEnum componentType, Component component,
2973                                                                                           String resourceInstanceName, User modifier,
2974                                                                                           String instanceId, boolean shouldLock,
2975                                                                                           boolean inTransaction) {
2976         return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction,
2977             System::currentTimeMillis, () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
2978     }
2979
2980     protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition,
2981                                                                                  ComponentTypeEnum componentType, Component component,
2982                                                                                  String resourceInstanceName, User modifier, boolean shouldLock,
2983                                                                                  boolean inTransaction, Supplier<Long> payloadUpdateDateGen,
2984                                                                                  Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator,
2985                                                                                  String instanceId) {
2986         log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2987         if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0
2988             || artifactDefinition.getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
2989             log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
2990             Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
2991             DAOArtifactData artifactData = null;
2992             if (artifactDataRes.isLeft()) {
2993                 artifactData = artifactDataRes.left().value();
2994             } else {
2995                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
2996                 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
2997                     artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
2998                     resourceInstanceName);
2999                 return Either.right(artifactDataRes.right().value());
3000             }
3001             String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
3002             String oldCheckSum;
3003             String esArtifactId = artifactDefinition.getEsId();
3004             Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
3005             DAOArtifactData DAOArtifactData;
3006             if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
3007                 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
3008                 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3009                 if (artifactfromES.isRight()) {
3010                     CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3011                     StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3012                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3013                     log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
3014                     return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
3015                 }
3016                 DAOArtifactData = artifactfromES.left().value();
3017                 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3018             } else {
3019                 oldCheckSum = artifactDefinition.getArtifactChecksum();
3020             }
3021             Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3022             if (shouldLock) {
3023                 try {
3024                     lockComponent(component, "Update Artifact - lock resource: ");
3025                 } catch (ComponentException e) {
3026                     handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null,
3027                         artifactDefinition.getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3028                     throw e;
3029                 }
3030             }
3031             try {
3032                 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3033                     artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3034                     updateArifactDefinitionStatus = artifactToscaOperation
3035                         .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3036                             instanceId, true);
3037                     log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3038                         artifactDefinition.getEsId());
3039                     if (updateArifactDefinitionStatus.isRight()) {
3040                         ResponseFormat responseFormat = componentsUtils
3041                             .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3042                                 artifactDefinition.getArtifactDisplayName());
3043                         log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3044                         handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3045                             artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3046                             resourceInstanceName);
3047                         return Either.right(responseFormat);
3048                     }
3049                 } else {
3050                     artifactDefinition.getArtifactChecksum();
3051                     artifactDefinition.setArtifactChecksum(newCheckSum);
3052                     artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3053                     log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(),
3054                         artifactDefinition.getEsId());
3055                     updateArifactDefinitionStatus = artifactToscaOperation
3056                         .updateArtifactOnResource(artifactDefinition, component, artifactDefinition.getUniqueId(), componentType.getNodeType(),
3057                             instanceId, true);
3058                     log.trace("Update Payload {}", artifactDefinition.getEsId());
3059                 }
3060                 if (updateArifactDefinitionStatus.isLeft()) {
3061                     artifactDefinition = updateArifactDefinitionStatus.left().value();
3062                     artifactData.setId(artifactDefinition.getUniqueId());
3063                     CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3064                     if (saveArtifactStatus == CassandraOperationStatus.OK) {
3065                         if (!inTransaction) {
3066                             janusGraphDao.commit();
3067                         }
3068                         log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3069                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3070                         handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3071                             artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3072                             resourceInstanceName);
3073                     } else {
3074                         if (!inTransaction) {
3075                             janusGraphDao.rollback();
3076                         }
3077                         log.info("Failed to save artifact {}.", artifactData.getId());
3078                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3079                         handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3080                             artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3081                             resourceInstanceName);
3082                         return Either.right(responseFormat);
3083                     }
3084                 } else {
3085                     ResponseFormat responseFormat = componentsUtils
3086                         .getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()),
3087                             artifactDefinition.getArtifactDisplayName());
3088                     log.debug("Failed To update artifact {}", artifactData.getId());
3089                     handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition,
3090                         artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3091                         resourceInstanceName);
3092                     return Either.right(responseFormat);
3093                 }
3094             } finally {
3095                 if (shouldLock) {
3096                     graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType());
3097                 }
3098             }
3099         }
3100         return Either.left(artifactDefinition);
3101     }
3102
3103     public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType,
3104                                                           List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3105         return this
3106             .buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType,
3107                 artifactDef.getArtifactLabel(), artifactDef.getArtifactDisplayName(), artifactDef.getDescription(), artifactDef.getPayloadData(),
3108                 updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3109     }
3110
3111     public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType,
3112                                                           ArtifactGroupTypeEnum artifactGroupType, String label, String displayName,
3113                                                           String description, byte[] artifactContent,
3114                                                           List<ArtifactTemplateInfo> updatedRequiredArtifacts,
3115                                                           List<HeatParameterDefinition> heatParameters) {
3116         Map<String, Object> json = new HashMap<>();
3117         if (artifactId != null && !artifactId.isEmpty()) {
3118             json.put(Constants.ARTIFACT_ID, artifactId);
3119         }
3120         json.put(Constants.ARTIFACT_NAME, artifactName);
3121         json.put(Constants.ARTIFACT_TYPE, artifactType);
3122         json.put(Constants.ARTIFACT_DESCRIPTION, description);
3123         if (artifactContent != null) {
3124             log.debug("payload is encoded. perform decode");
3125             String encodedPayload = Base64.encodeBase64String(artifactContent);
3126             json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3127         }
3128         json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3129         json.put(Constants.ARTIFACT_LABEL, label);
3130         json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3131         json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3132             : updatedRequiredArtifacts.stream().filter(
3133                     e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3134                 .map(ArtifactTemplateInfo::getFileName).collect(Collectors.toList()));
3135         json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>() : heatParameters);
3136         return json;
3137     }
3138
3139     public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user,
3140                                                                                          Map<String, Object> json, ArtifactOperationInfo operation,
3141                                                                                          ArtifactDefinition artifactInfo) {
3142         String jsonStr = gson.toJson(json);
3143         ArtifactDefinition artifactDefinitionFromJson =
3144             artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3145         String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3146         Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE,
3147             operation, artifactUniqueId, artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3148         return Either.left(uploadArtifactToService.left().value());
3149     }
3150
3151     private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo,
3152                                                                                  AuditingActionEnum auditingAction, String artifactId, User user,
3153                                                                                  ComponentTypeEnum componentType, Component parent, String originData,
3154                                                                                  String origMd5, ArtifactOperationInfo operation) {
3155         if (origMd5 != null) {
3156             validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3157             if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3158                 validateDeploymentArtifact(artifactInfo, parent);
3159                 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3160             } else { // duplicate
3161                 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3162             }
3163         }
3164         return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3165     }
3166
3167     private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId,
3168                                                                                  ArtifactDefinition artifactInfo, User user,
3169                                                                                  AuditingActionEnum auditingAction, Component parent,
3170                                                                                  ComponentTypeEnum componentType, String origMd5) {
3171         Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3172         if (getRI.isRight()) {
3173             throw new ByResponseFormatComponentException(getRI.right().value());
3174         }
3175         ComponentInstance ri = getRI.left().value();
3176         Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3177         if (getArtifactRes.isRight()) {
3178             throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3179         }
3180         ArtifactDefinition currArtifact = getArtifactRes.left().value();
3181         if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType()
3182             .equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3183             throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3184         }
3185         List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3186         List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3187         // upload
3188         if (origMd5 != null) {
3189             Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction,
3190                 parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams,
3191                 currArtifact.getArtifactName());
3192             if (uploadParamsValidationResult.isRight()) {
3193                 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3194             }
3195             artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3196         }
3197         Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo,
3198             ArtifactTypeEnum.HEAT_ENV.getType());
3199         if (validateAndConvertHeatParamers.isRight()) {
3200             throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3201         }
3202         if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3203             // fill reduced heat env parameters List for updating
3204             boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3205             if (updateRequired) {
3206                 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3207                 currArtifact.setListHeatParameters(currentHeatEnvParams);
3208                 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3209                     .updateArtifactOnResource(currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3210                 if (updateArtifactRes.isRight()) {
3211                     log.debug("Failed to update artifact on graph  - {}", artifactId);
3212                     throw new StorageException(updateArtifactRes.right().value());
3213                 }
3214                 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(),
3215                     parent.getUniqueId());
3216                 if (error != StorageOperationStatus.OK) {
3217                     throw new StorageException(error);
3218                 }
3219             }
3220         }
3221         updateHeatMetaDataIfNeeded(componentId, user, auditingAction, componentType, parent, ri, artifactInfo);
3222         StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3223         if (error != StorageOperationStatus.OK) {
3224             throw new StorageException(error);
3225         }
3226         return Either.left(currArtifact);
3227     }
3228
3229     private void updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType,
3230                                             Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3231         String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3232         Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId,
3233             auditingAction, user);
3234         if (getArtifactRes.isRight()) {
3235             throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3236         }
3237         ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3238         if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3239             validateHeatMetaData(updatedHeatEnvArtifact);
3240             updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3241             Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation
3242                 .updateArtifactOnResource(heatArtifactToUpdate, parent, heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId,
3243                     false);
3244             if (updateArtifactRes.isRight()) {
3245                 log.debug("Failed to update artifact on graph  - {}", heatArtifactId);
3246                 throw new StorageException(updateArtifactRes.right().value());
3247             }
3248             ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3249             updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition,
3250                 componentType.getNodeType());
3251             StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(),
3252                 parent.getUniqueId());
3253             if (error != StorageOperationStatus.OK) {
3254                 throw new StorageException(error);
3255             }
3256         }
3257     }
3258
3259     private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3260         Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3261         Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3262         Integer updateTimeout = updatedHeatEnv.getTimeout();
3263         if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3264             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3265         }
3266     }
3267
3268     private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3269         // currently only timeout metadata can be updated
3270         return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3271     }
3272
3273     private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3274         // currently only timeout metadata can be updated
3275         origHeat.setTimeout(updatedHeatEnv.getTimeout());
3276     }
3277
3278     private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams,
3279                                                          List<HeatParameterDefinition> updatedHeatEnvParams) {
3280         boolean isUpdate = false;
3281         List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3282         for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3283             String paramName = heatEnvParam.getName();
3284             validateParamName(paramName, currentParamsNames);
3285             for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3286                 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3287                     String updatedParamValue = heatEnvParam.getCurrentValue();
3288                     if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3289                         currHeatParam.setCurrentValue(updatedParamValue);
3290                         isUpdate = true;
3291                     }
3292                 }
3293             }
3294         }
3295         return isUpdate;
3296     }
3297
3298     private void validateParamName(String paramName, List<String> heatParamsNames) {
3299         if (!heatParamsNames.contains(paramName)) {
3300             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3301         }
3302     }
3303
3304     private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo,
3305                                                                    AuditingActionEnum auditingAction, Component parent,
3306                                                                    ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact,
3307                                                                    boolean needToUpdateGroup) {
3308         Either<ArtifactDefinition, Operation> insideEither = null;
3309         String currentHeatId = currHeatArtifact.getUniqueId();
3310         String esArtifactId = currHeatArtifact.getEsId();
3311         Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3312         if (artifactFromES.isRight()) {
3313             StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3314             throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3315         }
3316         DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3317         ArtifactDefinition updatedHeatArt = currHeatArtifact;
3318         List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3319         List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3320         List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3321         if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3322             //TODO: improve complexity - currently N^2
3323             String paramName;
3324             for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3325                 paramName = heatEnvParam.getName();
3326                 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3327                     if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3328                         String updatedParamValue = heatEnvParam.getCurrentValue();
3329                         if (updatedParamValue == null) {
3330                             updatedParamValue = heatEnvParam.getDefaultValue();
3331                         }
3332                         HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3333                         if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3334                             throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE, ArtifactTypeEnum.HEAT_ENV.getType(),
3335                                 paramType.getType(), paramName);
3336                         }
3337                         currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3338                         newHeatEnvParams.add(currHeatParam);
3339                         break;
3340                     }
3341                 }
3342             }
3343             if (!newHeatEnvParams.isEmpty()) {
3344                 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3345                 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation
3346                     .updateArtifactOnResource(currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId,
3347                         true);
3348                 if (operationStatus.isRight()) {
3349                     log.debug("Failed to update artifact on graph  - {}", currHeatArtifact.getUniqueId());
3350                     throw new StorageException(operationStatus.right().value());
3351                 }
3352                 updatedHeatArt = operationStatus.left().value();
3353                 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3354                     DAOArtifactData.setId(updatedHeatArt.getEsId());
3355                 }
3356                 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), auditingAction,
3357                     componentType);
3358                 insideEither = Either.left(updatedHeatArt);
3359             }
3360         }
3361         Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3362         if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3363             artifactEnvInfo.setArtifactChecksum(null);
3364             updateHeatEnvArtifact = artifactToscaOperation
3365                 .updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt.getUniqueId(), componentType.getNodeType(),
3366                     componentId);
3367         } else {
3368             //TODO Andrey check if componentId = parent.getUniqeId
3369             updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType.getNodeType());
3370         }
3371         if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3372             ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo, updateHeatEnvArtifact.left().value(), parent);
3373             if (result != ActionStatus.OK) {
3374                 throw new ByActionStatusComponentException(result);
3375             }
3376         }
3377         if (updatedHeatEnvParams.isEmpty()) {
3378             throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3379         }
3380         return insideEither;
3381     }
3382
3383     private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3384         StorageOperationStatus error = StorageOperationStatus.OK;
3385         log.debug("Need to re-generate  customization UUID for group instance on component instance  {}", ri.getUniqueId());
3386         List<GroupInstance> groupsInstances = ri.getGroupInstances();
3387         List<String> groupInstancesId = null;
3388         if (groupsInstances != null && !groupsInstances.isEmpty()) {
3389             groupInstancesId = groupsInstances.stream()
3390                 .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts().contains(artifactId))
3391                 .map(GroupInstanceDataDefinition::getUniqueId).collect(Collectors.toList());
3392         }
3393         if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3394             toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3395         }
3396         return error;
3397     }
3398
3399     public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent,
3400                                                                                                  User user, ArtifactDefinition artifactInfo,
3401                                                                                                  String artifactId, ComponentTypeEnum componentType,
3402                                                                                                  String riName,
3403                                                                                                  List<HeatParameterDefinition> currentHeatEnvParams,
3404                                                                                                  List<HeatParameterDefinition> updatedHeatEnvParams,
3405                                                                                                  String currArtifactName) {
3406         if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3407             ResponseFormat responseFormat = componentsUtils
3408                 .getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName);
3409             handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3410             return Either.right(responseFormat);
3411         }
3412         for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3413             String paramName = uploadedHeatParam.getName();
3414             boolean isExistsInHeat = false;
3415             for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3416                 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3417                     isExistsInHeat = true;
3418                     uploadedHeatParam.setType(currHeatParam.getType());
3419                     uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3420                     uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3421                     uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3422                     break;
3423                 }
3424             }
3425             if (!isExistsInHeat) {
3426                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3427                 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType,
3428                     riName);
3429                 return Either.right(responseFormat);
3430             }
3431         }
3432         return Either.left(updatedHeatEnvParams);
3433     }
3434
3435     private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId,
3436                                                                          AuditingActionEnum auditingAction, User user) {
3437         ResponseFormat responseFormat = null;
3438         List<ComponentInstance> ris = component.getComponentInstances();
3439         for (ComponentInstance ri : ris) {
3440             if (riID.equals(ri.getUniqueId())) {
3441                 return Either.left(ri);
3442             }
3443         }
3444         responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3445         log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3446         handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3447         return Either.right(responseFormat);
3448     }
3449
3450     private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId,
3451                                                                          AuditingActionEnum auditingAction, User user) {
3452         ResponseFormat responseFormat = null;
3453         Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3454         for (ArtifactDefinition artifact : rtifactsMap.values()) {
3455             if (artifactId.equals(artifact.getUniqueId())) {
3456                 return Either.left(artifact);
3457             }
3458         }
3459         responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3460         handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE,
3461             ri.getName());
3462         return Either.right(responseFormat);
3463     }
3464
3465     public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3466         ArtifactDefinition ret;
3467         if (eitherArtifact.isLeft()) {
3468             ret = eitherArtifact.left().value();
3469         } else {
3470             ret = eitherArtifact.right().value().getImplementationArtifact();
3471         }
3472         return ret;
3473     }
3474
3475     public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
3476                                                    ResourceCommonInfo resourceCommonInfo) {
3477         Component component = getComponentByUuid(componentType, componentUuid);
3478         resourceCommonInfo.setResourceName(component.getName());
3479         return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3480     }
3481
3482     /**
3483      * downloads an artifact of resource instance of component by UUIDs
3484      *
3485      * @param componentType
3486      * @param componentUuid
3487      * @param resourceInstanceName
3488      * @param artifactUUID
3489      * @return
3490      */
3491     public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
3492                                                           String artifactUUID) {
3493         ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3494         if (resourceInstance != null) {
3495             return downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, resourceInstance.getName());
3496         } else {
3497             return downloadArtifact(null, artifactUUID, null);
3498         }
3499     }
3500
3501     /**
3502      * uploads an artifact to a component by UUID
3503      *
3504      * @param data
3505      * @param request
3506      * @param componentType
3507      * @param componentUuid
3508      * @param resourceCommonInfo
3509      * @param operation
3510      * @return
3511      */
3512     public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3513                                                               String componentUuid, ResourceCommonInfo resourceCommonInfo,
3514                                                               ArtifactOperationInfo operation) {
3515         Either<ArtifactDefinition, Operation> actionResult;
3516         Component component;
3517         String componentId;
3518         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3519         String origMd5 = request.getHeader(Constants.MD5_HEADER);
3520         String userId = request.getHeader(Constants.USER_ID_HEADER);
3521         Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3522         ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3523         componentId = componentMetadataDataDefinition.getUniqueId();
3524         String componentName = componentMetadataDataDefinition.getName();
3525         if (!componentMetadataDataDefinition.getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3526             component = checkoutParentComponent(componentType, componentId, userId);
3527             if (component != null) {
3528                 componentId = component.getUniqueId();
3529                 componentName = component.getName();
3530             }
3531         }
3532         resourceCommonInfo.setResourceName(componentName);
3533         actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null,
3534             null);
3535         return actionResult.left().value();
3536     }
3537
3538     /**
3539      * upload an artifact to a resource instance by UUID
3540      *
3541      * @param data
3542      * @param request
3543      * @param componentType
3544      * @param componentUuid
3545      * @param resourceInstanceName
3546      * @param operation
3547      * @return
3548      */
3549     public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3550                                                        String resourceInstanceName, ArtifactOperationInfo operation) {
3551         Either<ArtifactDefinition, Operation> actionResult;
3552         Component component = null;
3553         String componentInstanceId;
3554         String componentId;
3555         String origMd5 = request.getHeader(Constants.MD5_HEADER);
3556         String userId = request.getHeader(Constants.USER_ID_HEADER);
3557         ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3558         Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid,
3559             resourceInstanceName);
3560         if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3561             component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3562         }
3563         if (component == null) {
3564             componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3565         } else {
3566             componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3567         }
3568         componentInstanceId = componentRiPair.getRight().getUniqueId();
3569         componentId = componentRiPair.getLeft().getUniqueId();
3570         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3571         actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5,
3572             data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3573         return actionResult.left().value();
3574     }
3575
3576     /**
3577      * updates an artifact on a component by UUID
3578      *
3579      * @param data
3580      * @param request
3581      * @param componentType
3582      * @param componentUuid
3583      * @param artifactUUID
3584      * @param resourceCommonInfo
3585      * @param operation          TODO
3586      * @return
3587      */
3588     public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3589                                                               String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3590                                                               ArtifactOperationInfo operation) {
3591         Either<ArtifactDefinition, Operation> actionResult;
3592         Component component;
3593         String componentId;
3594         String artifactId;
3595         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3596         String origMd5 = request.getHeader(Constants.MD5_HEADER);
3597         String userId = request.getHeader(Constants.USER_ID_HEADER);
3598         Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3599         componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3600         String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3601         if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3602             component = checkoutParentComponent(componentType, componentId, userId);
3603             if (component != null) {
3604                 componentId = component.getUniqueId();
3605                 componentName = component.getName();
3606             }
3607         }
3608         resourceCommonInfo.setResourceName(componentName);
3609         artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3610         actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null,
3611             null);
3612         if (actionResult.isRight()) {
3613             log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult.right().value());
3614         }
3615         return actionResult.left().value();
3616     }
3617
3618     /**
3619      * updates an artifact on a resource instance by UUID
3620      *
3621      * @param data
3622      * @param request
3623      * @param componentType
3624      * @param componentUuid
3625      * @param resourceInstanceName
3626      * @param artifactUUID
3627      * @param operation            TODO
3628      * @return
3629      */
3630     public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3631                                                        String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3632         Either<ArtifactDefinition, Operation> actionResult;
3633         Component component = null;
3634         String componentInstanceId;
3635         String componentId;
3636         String artifactId;
3637         String origMd5 = request.getHeader(Constants.MD5_HEADER);
3638         String userId = request.getHeader(Constants.USER_ID_HEADER);
3639         ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3640         Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3641         if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3642             component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3643         }
3644         if (component == null) {
3645             componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3646         } else {
3647             componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3648         }
3649         componentInstanceId = componentRiPair.getRight().getUniqueId();
3650         componentId = componentRiPair.getLeft().getUniqueId();
3651         artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3652         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3653         actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo,
3654             origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3655         return actionResult.left().value();
3656     }
3657
3658     private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid,
3659                                                                                ArtifactDefinition artifactInfo) {
3660         Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3661         if (componentStorageOperationStatusEither.isRight()) {
3662             StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3663             log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
3664             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3665         }
3666         Component storedComponent = componentStorageOperationStatusEither.left().value();
3667         Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3668             .getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
3669         if (!optionalInterface.isPresent()) {
3670             log.debug("Failed to get resource interface for resource Id {}", componentId);
3671             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
3672         }
3673         //fetch the operation from storage
3674         InterfaceDefinition gotInterface = optionalInterface.get();
3675         Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
3676         Optional<Operation> optionalOperation = operationsMap.values().stream().filter(o -> o.getUniqueId().equals(operationUuid)).findFirst();
3677         if (!optionalOperation.isPresent()) {
3678             log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
3679             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
3680             return Either.right(responseFormat);
3681         }
3682         Operation operation = optionalOperation.get();
3683         ArtifactDefinition implementationArtifact = operation.getImplementationArtifact();
3684         implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
3685         implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
3686         implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
3687         implementationArtifact.setDescription(artifactInfo.getDescription());
3688         implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
3689         implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
3690         implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
3691         implementationArtifact.setEsId(artifactInfo.getEsId());
3692         operation.setImplementation(implementationArtifact);
3693         gotInterface.setOperationsMap(operationsMap);
3694         Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = interfaceOperation
3695             .updateInterfaces(storedComponent, Collections.singletonList(gotInterface));
3696         if (interfaceDefinitionStorageOperationStatusEither.isRight()) {
3697             StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
3698             ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
3699             return Either.right(componentsUtils.getResponseFormat(actionStatus));
3700         }
3701         return Either.left(artifactInfo);
3702     }
3703
3704     /**
3705      * updates an artifact on a component by UUID
3706      *
3707      * @param data
3708      * @param request
3709      * @param componentType
3710      * @param componentUuid
3711      * @param artifactUUID
3712      * @param operation
3713      * @return
3714      */
3715     public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(String data, HttpServletRequest request,
3716                                                                                                        ComponentTypeEnum componentType,
3717                                                                                                        String componentUuid, String interfaceUUID,
3718                                                                                                        String operationUUID, String artifactUUID,
3719                                                                                                        ResourceCommonInfo resourceCommonInfo,
3720                                                                                                        ArtifactOperationInfo operation) {
3721         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
3722         Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
3723         String componentId = null;
3724         ArtifactDefinition existingArtifactInfo = null;
3725         String interfaceName = null;
3726         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
3727         String origMd5 = request.getHeader(Constants.MD5_HEADER);
3728         String userId = request.getHeader(Constants.USER_ID_HEADER);
3729         Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3730             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(as));
3731             return as;
3732         });
3733         if (errorWrapper.isEmpty()) {
3734             componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3735             String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3736             if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3737                 Component component = checkoutParentComponent(componentType, componentId, userId);
3738                 if (component != null) {
3739                     componentId = component.getUniqueId();
3740                     componentName = component.getName();
3741                 }
3742             }
3743             resourceCommonInfo.setResourceName(componentName);
3744         }
3745         if (errorWrapper.isEmpty()) {
3746             Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
3747             if (interfaceNameEither.isRight()) {
3748                 errorWrapper.setInnerElement(interfaceNameEither.right().value());
3749             } else {
3750                 interfaceName = interfaceNameEither.left().value();
3751             }
3752             if (errorWrapper.isEmpty()) {
3753                 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
3754                 if (toscaComponentEither.isRight()) {
3755                     StorageOperationStatus status = toscaComponentEither.right().value();
3756                     log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
3757                     errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
3758                 }
3759                 if (errorWrapper.isEmpty()) {
3760                     NodeTypeEnum parentType = convertParentType(componentType);
3761                     final List<ArtifactDefinition> existingDeploymentArtifacts = getDeploymentArtifacts(toscaComponentEither.left().value(), null);
3762                     for (ArtifactDefinition artifactDefinition : existingDeploymentArtifacts) {
3763                         if (artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())) {
3764                             existingArtifactInfo = artifactDefinition;
3765                             break;
3766                         }
3767                     }
3768                     if (existingArtifactInfo != null) {
3769                         return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
3770                     }
3771                 }
3772             }
3773         }
3774         if (errorWrapper.isEmpty()) {
3775             updateArtifactResult = handleArtifactRequestAndFlatten(componentId, userId, componentType, operation, artifactUUID, artifactInfo, origMd5,
3776                 data, interfaceName, operationUUID);
3777         } else {
3778             updateArtifactResult = Either.right(errorWrapper.getInnerElement());
3779         }
3780         return updateArtifactResult;
3781     }
3782
3783     private Either<ArtifactDefinition, ResponseFormat> handleArtifactRequestAndFlatten(String componentId, String userId,
3784                                                                                        ComponentTypeEnum componentType,
3785                                                                                        ArtifactOperationInfo operation, String artifactId,
3786                                                                                        ArtifactDefinition artifactInfo, String origMd5,
3787                                                                                        String originData, String interfaceName,
3788                                                                                        String operationName) {
3789         try {
3790             return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName,
3791                 operationName, null, null).right().map(op -> {
3792                 log.debug("Unexpected value returned while calling handleArtifactRequest: {}", op);
3793                 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3794             });
3795         } catch (ComponentException e) {
3796             return Either.right(e.getResponseFormat());
3797         }
3798     }
3799
3800     private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid) {
3801         return fetchLatestComponentMetadataOrThrow(componentType, componentUuid, componentUuid);
3802     }
3803
3804     private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadataOrThrow(ComponentTypeEnum componentType, String componentUuid,
3805                                                                                             String resourceInstanceName) {
3806         return fetchLatestComponentMetadata(componentType, componentUuid).right().map(as -> {
3807             throw new ByActionStatusComponentException(as, resourceInstanceName);
3808         });
3809     }
3810
3811     private Either<ComponentMetadataData, ActionStatus> fetchLatestComponentMetadata(ComponentTypeEnum componentType, String componentUuid) {
3812         return toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true).right().map(sos -> {
3813             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, sos);
3814             return componentsUtils.convertFromStorageResponse(sos, componentType);
3815         });
3816     }
3817
3818     private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
3819         Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
3820         if (componentStorageOperationStatusEither.isRight()) {
3821             StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
3822             log.debug("Failed to fetch component information by component id, error {}", errorStatus);
3823             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
3824         }
3825         Component storedComponent = componentStorageOperationStatusEither.left().value();
3826         Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
3827             .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
3828         if (!optionalInterface.isPresent()) {
3829             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
3830         }
3831         return Either.left(optionalInterface.get().getType());
3832     }
3833
3834     /**
3835      * deletes an artifact on a component by UUID
3836      *
3837      * @param request
3838      * @param componentType
3839      * @param componentUuid
3840      * @param artifactUUID
3841      * @param resourceCommonInfo
3842      * @param operation          TODO
3843      * @return
3844      */
3845     public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3846                                                               String artifactUUID, ResourceCommonInfo resourceCommonInfo,
3847                                                               ArtifactOperationInfo operation) {
3848         Either<ArtifactDefinition, Operation> actionResult;
3849         Component component;
3850         String componentId;
3851         String artifactId;
3852         String origMd5 = request.getHeader(Constants.MD5_HEADER);
3853         String userId = request.getHeader(Constants.USER_ID_HEADER);
3854         Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3855         componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
3856         String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
3857         if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3858             component = checkoutParentComponent(componentType, componentId, userId);
3859             if (component != null) {
3860                 componentId = component.getUniqueId();
3861                 componentName = component.getName();
3862             }
3863         }
3864         resourceCommonInfo.setResourceName(componentName);
3865         artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
3866         actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
3867         return actionResult.left().value();
3868     }
3869
3870     /**
3871      * deletes an artifact from a resource instance by UUID
3872      *
3873      * @param request
3874      * @param componentType
3875      * @param componentUuid
3876      * @param resourceInstanceName
3877      * @param artifactUUID
3878      * @param operation            TODO
3879      * @return
3880      */
3881     public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid,
3882                                                        String resourceInstanceName, String artifactUUID, ArtifactOperationInfo operation) {
3883         Either<ArtifactDefinition, Operation> actionResult;
3884         Component component = null;
3885         String componentInstanceId;
3886         String componentId;
3887         String artifactId;
3888         String origMd5 = request.getHeader(Constants.MD5_HEADER);
3889         String userId = request.getHeader(Constants.USER_ID_HEADER);
3890         ImmutablePair<Component, ComponentInstance> componentRiPair = null;
3891         Either<ComponentMetadataData, ActionStatus> getComponentRes = fetchLatestComponentMetadataOrThrow(componentType, componentUuid);
3892         if (!getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
3893             component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId);
3894         }
3895         if (component == null) {
3896             componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
3897         } else {
3898             componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
3899         }
3900         componentInstanceId = componentRiPair.getRight().getUniqueId();
3901         componentId = componentRiPair.getLeft().getUniqueId();
3902         artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
3903         actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5,
3904             null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType));
3905         return actionResult.left().value();
3906     }
3907
3908     private String findArtifactId(ComponentInstance instance, String artifactUUID) {
3909         String artifactId = null;
3910         ArtifactDefinition foundArtifact = null;
3911         if (instance.getDeploymentArtifacts() != null) {
3912             foundArtifact = instance.getDeploymentArtifacts().values().stream()
3913                 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3914         }
3915         if (foundArtifact == null && instance.getArtifacts() != null) {
3916             foundArtifact = instance.getArtifacts().values().stream()
3917                 .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID().equals(artifactUUID)).findFirst().orElse(null);
3918         }
3919         if (foundArtifact == null) {
3920             log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
3921             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
3922         } else {
3923             artifactId = foundArtifact.getUniqueId();
3924         }
3925         return artifactId;
3926     }
3927
3928     @SuppressWarnings("unchecked")
3929     public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact, String envType,
3930                                                        String parentId, NodeTypeEnum parentType, String parentName, User user, Component component,
3931                                                        Map<String, String> existingEnvVersions) {
3932         Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
3933             .getDeploymentResourceInstanceArtifacts();
3934         if (deploymentResourceArtifacts == null) {
3935             log.debug("no deployment artifacts are configured for generated artifacts");
3936             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3937         }
3938         Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
3939         if (placeHolderData == null) {
3940             log.debug("no env type {} are configured for generated artifacts", envType);
3941             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
3942         }
3943         String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
3944         ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user.getUserId(),
3945             ArtifactGroupTypeEnum.DEPLOYMENT, true);
3946         ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
3947         artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
3948         artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
3949         artifactHeatEnv.setTimeout(0);
3950         artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
3951         buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
3952         // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
3953         handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
3954         ArtifactDefinition heatEnvPlaceholder;
3955         // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
3956         if (parentType != NodeTypeEnum.ResourceInstance) {
3957             String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
3958             artifactHeatEnv.setArtifactChecksum(checkSum);
3959             Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component,
3960                 parentType, parentId);
3961             if (addHeatEnvArtifact.isRight()) {
3962                 log.debug("failed to create heat env artifact on resource instance");
3963                 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(
3964                     componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact.right().value(), false), "", null));
3965             }
3966             heatEnvPlaceholder = createArtifactPlaceHolder;
3967         } else {
3968             heatEnvPlaceholder = artifactHeatEnv;
3969             artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
3970             setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
3971         }
3972         ComponentTypeEnum componentType = component.getComponentType();
3973         if (parentType == NodeTypeEnum.ResourceInstance) {
3974             componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
3975         }
3976         createdArtifacts.add(heatEnvPlaceholder);
3977         componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
3978             new ResourceCommonInfo(parentName, componentType.getValue()), ResourceVersionInfo.newBuilder().build(),
3979             ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(), null, heatEnvPlaceholder, null);
3980         return heatEnvPlaceholder;
3981     }
3982
3983     private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
3984         if (artifact.getListHeatParameters() == null) {
3985             return;
3986         }
3987         List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
3988         for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
3989             HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
3990             heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
3991             heatEnvParameter.setCurrentValue(null);
3992             heatEnvParameters.add(heatEnvParameter);
3993         }
3994         artifactDefinition.setListHeatParameters(heatEnvParameters);
3995     }
3996
3997     private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
3998         String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
3999         String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
4000         String name = heatArtifact.getArtifactName();
4001         String fileName;
4002         if (name == null) {
4003             name = heatArtifact.getArtifactLabel();
4004             fileName = name + "." + envExtension;
4005         } else {
4006             fileName = name.replaceAll("." + heatExtension, "." + envExtension);
4007         }
4008         heatEnvArtifact.setArtifactName(fileName);
4009     }
4010
4011     private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
4012         if (null != existingEnvVersions) {
4013             String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
4014             if (null != prevVersion) {
4015                 heatEnvArtifact.setArtifactVersion(prevVersion);
4016             }
4017         }
4018     }
4019
4020     public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user,
4021                                                                         List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4022                                                                         ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4023         ComponentTypeEnum componentType = component.getComponentType();
4024         List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4025         Either<ArtifactDefinition, Operation> result;
4026         try {
4027             for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4028                 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4029                 uploadedArtifacts.add(result.left().value());
4030             }
4031         } catch (ComponentException e) {
4032             log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component.getName(), e.getResponseFormat());
4033             if (operation.isCreateOrLink()) {
4034                 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4035             }
4036             throw e;
4037         }
4038         return uploadedArtifacts;
4039     }
4040
4041     public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Component component, User user, ArtifactOperationInfo operation,
4042                                                                       boolean shouldLock, boolean inTransaction, ComponentTypeEnum componentType,
4043                                                                       ArtifactDefinition artifactDefinition) {
4044         AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4045         String componentId = component.getUniqueId();
4046         String artifactId = artifactDefinition.getUniqueId();
4047         Either<ArtifactDefinition, Operation> result;
4048         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4049         //artifact validation
4050         artifactDefinition = validateArtifact(componentId, componentType, operation, artifactId, artifactDefinition, auditingAction, user, component,
4051             shouldLock, inTransaction);
4052         switch (operation.getArtifactOperationEnum()) {
4053             case CREATE:
4054                 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType,
4055                     component, null, null);
4056                 result = createArtifact(component, componentId, artifactDefinition, validPayload, componentType, auditingAction, null, null);
4057                 break;
4058             case UPDATE:
4059                 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component,
4060                     null, null);
4061                 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4062                     auditingAction, user, component, true);
4063                 break;
4064             case DELETE:
4065                 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4066                 break;
4067             case DOWNLOAD:
4068                 if (artifactGenerationRequired(component, artifactDefinition)) {
4069                     result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4070                 } else {
4071                     result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4072                 }
4073                 break;
4074             case LINK:
4075                 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4076                 break;
4077             default:
4078                 throw new UnsupportedOperationException(
4079                     "In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4080         }
4081         return result;
4082     }
4083
4084     public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component,
4085                                                                                User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4086                                                                                ArtifactOperationInfo operation, boolean shouldLock,
4087                                                                                boolean inTransaction) {
4088         List<ArtifactDefinition> handleArtifactsResult;
4089         ComponentTypeEnum componentType = component.getComponentType();
4090         List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4091         Either<ArtifactDefinition, Operation> actionResult;
4092         String originData;
4093         String origMd5;
4094         try {
4095             for (ArtifactDefinition artifact : artifactsToHandle) {
4096                 originData = ArtifactUtils.buildJsonStringForCsarVfcArtifact(artifact);
4097                 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4098                 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact.getUniqueId(),
4099                     artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4100                 uploadedArtifacts.add(actionResult.left().value());
4101             }
4102             handleArtifactsResult = uploadedArtifacts;
4103         } catch (ComponentException e) {
4104             if (operation.isCreateOrLink()) {
4105                 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4106             }
4107             throw e;
4108         }
4109         return handleArtifactsResult;
4110     }
4111
4112     private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName) {
4113         String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4114         Option<Component> oComponent = Option.of(getComponentByUuid(componentType, componentUuid));
4115         return oComponent.toTry(componentNotFound(componentType, componentUuid)).flatMap(
4116             component -> findFirstMatching(component, ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4117                 .toTry(componentInstanceNotFound(componentType, resourceInstanceName, component))).get();
4118     }
4119
4120     private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName) {
4121         String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4122         ComponentInstance componentInstance = findFirstMatching(component,
4123             ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName()).equals(normalizedName))
4124             .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4125         return new ImmutablePair<>(component, componentInstance);
4126     }
4127
4128     private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid,
4129                                                                                              String resourceInstanceName) {
4130         Component component = getLatestComponentByUuid(componentType, componentUuid);
4131         ComponentInstance componentInstance = findFirstMatching(component, ci -> ci.getNormalizedName().equals(resourceInstanceName))
4132             .toTry(componentInstanceNotFound(component.getComponentType(), resourceInstanceName, component)).get();
4133         return new ImmutablePair<>(component, componentInstance);
4134     }
4135
4136     private Supplier<Throwable> componentNotFound(ComponentTypeEnum componentType, String componentUuid) {
4137         return () -> {
4138             log.debug(FAILED_FETCH_COMPONENT, componentType.getValue(), componentUuid);
4139             return new ByActionStatusComponentException(ActionStatus.COMPONENT_NOT_FOUND, componentUuid);
4140         };
4141     }
4142
4143     private Supplier<Throwable> componentInstanceNotFound(ComponentTypeEnum componentType, String resourceInstanceName, Component component) {
4144         return () -> {
4145             log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4146             return new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4147                 RESOURCE_INSTANCE, componentType.getValue(), component.getName());
4148         };
4149     }
4150
4151     private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4152         ImmutablePair<String, byte[]> downloadArtifact;
4153         List<ArtifactDefinition> artifactsList = null;
4154         ArtifactDefinition deploymentArtifact;
4155         if (artifacts != null && !artifacts.isEmpty()) {
4156             artifactsList = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID))
4157                 .collect(Collectors.toList());
4158         }
4159         if (artifactsList == null || artifactsList.isEmpty()) {
4160             log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4161             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4162         }
4163         deploymentArtifact = artifactsList.get(0);
4164         downloadArtifact = downloadArtifact(deploymentArtifact);
4165         log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4166         return downloadArtifact.getRight();
4167     }
4168
4169     private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4170         Component component;
4171         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4172         if (getComponentRes.isRight()) {
4173             StorageOperationStatus status = getComponentRes.right().value();
4174             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4175             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4176         } else {
4177             component = getComponentRes.left().value();
4178         }
4179         return component;
4180     }
4181
4182     private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4183         Component component;
4184         Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4185         if (getComponentRes.isRight()) {
4186             StorageOperationStatus status = getComponentRes.right().value();
4187             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4188             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4189         } else {
4190             List<Component> value = getComponentRes.left().value();
4191             if (value.isEmpty()) {
4192                 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4193                 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4194                 throw new ByActionStatusComponentException(status);
4195             } else {
4196                 component = value.get(0);
4197             }
4198         }
4199         return component;
4200     }
4201
4202     private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4203         ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4204         StorageOperationStatus storageStatus;
4205         ArtifactDefinition latestArtifact;
4206         List<ArtifactDefinition> artifacts;
4207         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4208         if (getArtifactsRes.isRight()) {
4209             storageStatus = getArtifactsRes.right().value();
4210             log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4211             if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4212                 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4213             }
4214             throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4215         }
4216         artifacts = getArtifactsRes.left().value().values().stream()
4217             .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList());
4218         if (artifacts == null || artifacts.isEmpty()) {
4219             log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4220                 parentId, actionStatus);
4221             throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4222         }
4223         latestArtifact = artifacts.stream().max((a1, a2) -> {
4224             int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4225             if (compareRes == 0) {
4226                 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(),
4227                     a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate());
4228             }
4229             return compareRes;
4230         }).get();
4231         if (latestArtifact == null) {
4232             log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType,
4233                 parentId, actionStatus);
4234             throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4235         }
4236         return latestArtifact.getUniqueId();
4237     }
4238
4239     private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4240         Component component = null;
4241         User modifier = userBusinessLogic.getUser(userId, false);
4242         LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout",
4243             LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4244         Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic
4245             .changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4246         if (checkoutRes.isRight()) {
4247             log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId,
4248                 checkoutRes.right().value().getStatus());
4249             throw new ByResponseFormatComponentException(checkoutRes.right().value());
4250         }
4251         return checkoutRes.left().value();
4252     }
4253
4254     @Autowired
4255     void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4256         this.nodeTemplateOperation = nodeTemplateOperation;
4257     }
4258
4259     public List<ArtifactConfiguration> getConfiguration() {
4260         return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
4261     }
4262
4263     public enum ArtifactOperationEnum {
4264         CREATE, UPDATE, DELETE, DOWNLOAD, LINK;
4265
4266         public static boolean isCreateOrLink(ArtifactOperationEnum operation) {
4267             return operation == CREATE || operation == LINK;
4268         }
4269     }
4270 }