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