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