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