fix bug - Error 500 while adding an Operation
[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         log.debug("Entry on graph is updated. Update artifact in ES");
2474         // Changing previous and current artifactId for auditing
2475         prevArtifactId = currArtifactId;
2476         currArtifactId = artifactDefinition.getUniqueId();
2477
2478         NodeTypeEnum parentType = convertParentType(componentType);
2479
2480         if (decodedPayload == null) {
2481             if (!artifactDefinition.getMandatory() || artifactDefinition.getEsId() != null) {
2482                 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactDefinition.getEsId());
2483                 if (artifactFromCassandra.isRight()) {
2484                     throw new StorageException(artifactFromCassandra.right().value());
2485                 }
2486                 // clone data to new artifact
2487                 artifactData.setData(artifactFromCassandra.left().value().getData());
2488                 artifactData.setId(artifactFromCassandra.left().value().getId());
2489             }
2490         } else if (artifactDefinition.getEsId() == null) {
2491             artifactDefinition.setEsId(artifactDefinition.getUniqueId());
2492             artifactData.setId(artifactDefinition.getUniqueId());
2493         }
2494
2495         Either<ArtifactDefinition, StorageOperationStatus> result = artifactToscaOperation.updateArtifactOnResource(artifactInfo,
2496                 parent, artifactId, parentType, parentId, true);
2497         if (result.isRight()) {
2498             throw new StorageException(result.right().value());
2499         }
2500         artifactDefinition = result.left().value();
2501         updateGeneratedIdInHeatEnv(parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType);
2502
2503         StorageOperationStatus storageOperationStatus = generateCustomizationUUIDOnInstance(parent.getUniqueId(), parentId, componentType);
2504         if (storageOperationStatus != StorageOperationStatus.OK) {
2505             throw new StorageException(storageOperationStatus);
2506         }
2507         if (artifactData.getData() != null) {
2508             if (!artifactDefinition.getDuplicated() || artifactData.getId() == null) {
2509                 artifactData.setId(artifactDefinition.getEsId());
2510             }
2511             saveArtifactInCassandra(artifactData, parent, artifactInfo, currArtifactId, prevArtifactId, auditingAction, componentType);
2512         }
2513         return Either.left(artifactDefinition);
2514     }
2515
2516     private Either<Either<ArtifactDefinition, Operation>, ResponseFormat> updateArtifactsFlowForInterfaceOperations(
2517             Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo, User user,
2518             byte[] decodedPayload, ComponentTypeEnum componentType, AuditingActionEnum auditingAction, String interfaceType,
2519             String operationUuid, DAOArtifactData artifactData, String prevArtifactId, String currArtifactId,
2520             ArtifactDefinition artifactDefinition) {
2521         StorageOperationStatus error;
2522         Either<Either<ArtifactDefinition, Operation>, ResponseFormat> resultOp;
2523         if (decodedPayload == null) {
2524             if (!artifactDefinition.getMandatory() || artifactDefinition.getEsId() != null) {
2525                 Either<DAOArtifactData, CassandraOperationStatus> artifactFromCassandra = artifactCassandraDao.getArtifact(artifactDefinition
2526                         .getEsId());
2527                 if (artifactFromCassandra.isRight()) {
2528                     log.debug("Failed to get artifact data from ES for artifact id  {}", artifactId);
2529                     error = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromCassandra.right()
2530                             .value());
2531                     ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(error));
2532                     handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null);
2533                     resultOp = Either.right(responseFormat);
2534                     return resultOp;
2535                 }
2536                 // clone data to new artifact
2537                 artifactData.setData(artifactFromCassandra.left().value().getData());
2538                 artifactData.setId(artifactFromCassandra.left().value().getId());
2539             } else {
2540                 // todo if not exist(first time)
2541             }
2542
2543         } else {
2544             if (artifactDefinition.getEsId() == null) {
2545                 artifactDefinition.setEsId(artifactDefinition.getUniqueId());
2546                 artifactData.setId(artifactDefinition.getUniqueId());
2547             }
2548         }
2549         NodeTypeEnum convertParentType = convertParentType(componentType);
2550         // Set additional fields for artifact
2551         artifactInfo.setArtifactLabel(artifactInfo.getArtifactName());
2552         artifactInfo.setArtifactDisplayName(artifactInfo.getArtifactName());
2553
2554         Either<ArtifactDefinition, StorageOperationStatus> updateArtifactOnResourceEither =
2555                 artifactToscaOperation.updateArtifactOnResource(artifactInfo, parent, artifactId, convertParentType, parentId, true);
2556         if(updateArtifactOnResourceEither.isRight()){
2557             log.debug("Failed to persist operation artifact {} in resource, error is {}",artifactInfo.getArtifactName(), updateArtifactOnResourceEither.right().value());
2558             ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(updateArtifactOnResourceEither.right().value());
2559             return Either.right(componentsUtils.getResponseFormat(convertedFromStorageResponse));
2560         }
2561         if (artifactData.getData() != null) {
2562             CassandraOperationStatus cassandraOperationStatus = artifactCassandraDao.saveArtifact(artifactData);
2563             if(cassandraOperationStatus != CassandraOperationStatus.OK){
2564                 log.debug("Failed to persist operation artifact {}, error is {}",artifactInfo.getArtifactName(),cassandraOperationStatus);
2565                 StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(cassandraOperationStatus);
2566                 ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus);
2567                 return Either.right(componentsUtils.getResponseFormat(convertedFromStorageResponse));
2568             }
2569         }
2570
2571         Either<ArtifactDefinition, ResponseFormat> updateOprEither = updateOperationArtifact(parentId, interfaceType, operationUuid, updateArtifactOnResourceEither.left().value());
2572         if(updateOprEither.isRight()){
2573             return Either.right(updateOprEither.right().value());
2574         }
2575
2576         return Either.left(Either.left(updateOprEither.left().value()));
2577     }
2578
2579     private String updateGeneratedIdInHeatEnv(Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2580         if (NodeTypeEnum.Resource == parentType) {
2581             return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parent, parentId, artifactId, artifactInfo, artifactDefinition, parentType, false);
2582         }
2583         return artifactDefinition.getUniqueId();
2584     }
2585
2586     private String updateGeneratedIdInHeatEnv(Map<String, ArtifactDefinition> deploymentArtifacts, Component parentComponent, String parentId, String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition, NodeTypeEnum parentType, boolean isInstanceArtifact) {
2587         String artifactUniqueId;
2588         artifactUniqueId = artifactDefinition.getUniqueId();
2589         String artifactType = artifactInfo.getArtifactType();
2590         if ((ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) ||
2591                 ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType) ||
2592                 ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType))
2593                 && !artifactUniqueId.equals(artifactId)) {
2594             // need to update the generated id in heat env
2595             Optional<Entry<String, ArtifactDefinition>> findFirst = deploymentArtifacts.entrySet()
2596                     .stream()
2597                     .filter(a -> artifactId.equals(a.getValue().getGeneratedFromId()))
2598                     .findFirst();
2599             if (findFirst.isPresent()) {
2600                 ArtifactDefinition artifactEnvInfo = findFirst.get().getValue();
2601                 artifactEnvInfo.setIsFromCsar(artifactDefinition.getIsFromCsar());
2602                 artifactEnvInfo.setArtifactChecksum(null);
2603                 if (isInstanceArtifact) {
2604                     artifactToscaOperation.updateHeatEnvArtifactOnInstance(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2605                 } else {
2606                     artifactToscaOperation.updateHeatEnvArtifact(parentComponent, artifactEnvInfo, artifactId, artifactUniqueId, parentType, parentId);
2607                 }
2608             }
2609         }
2610         return artifactUniqueId;
2611     }
2612
2613     private String updateGeneratedIdInHeatEnvOnInstance(ComponentInstance parent, Component parentComponent, String artifactId, ArtifactDefinition artifactInfo, ArtifactDefinition artifactDefinition, NodeTypeEnum parentType) {
2614         return updateGeneratedIdInHeatEnv(parent.getDeploymentArtifacts(), parentComponent, parent.getUniqueId(),artifactId, artifactInfo, artifactDefinition, parentType, true);
2615     }
2616
2617     @VisibleForTesting
2618     private Either<byte[], ResponseFormat> handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) {
2619         log.trace("Starting payload handling");
2620         byte[] payload = artifactInfo.getPayloadData();
2621         byte[] decodedPayload = null;
2622
2623         if (payload != null && payload.length != 0) {
2624             // the generated artifacts were already decoded by the handler
2625             decodedPayload = artifactInfo.getGenerated() ? payload : Base64.decodeBase64(payload);
2626             if (decodedPayload.length == 0) {
2627                 log.debug("Failed to decode the payload.");
2628                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT);
2629                 return Either.right(responseFormat);
2630             }
2631
2632             String checkSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(decodedPayload);
2633             artifactInfo.setArtifactChecksum(checkSum);
2634             log.trace("Calculated checksum, base64 payload: {},  checksum: {}", payload, checkSum);
2635
2636             // Specific payload validations of different types
2637             Either<Boolean, ResponseFormat> result = Either.left(true);
2638             if (isDeploymentArtifact(artifactInfo)) {
2639                 log.trace("Starting deployment artifacts payload validation");
2640                 String artifactType = artifactInfo.getArtifactType();
2641                 String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName());
2642                 PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension);
2643                 Either<Boolean, ActionStatus> isPayloadValid = payloadType.isValid(decodedPayload);
2644                 if (isPayloadValid.isRight()) {
2645                     ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType);
2646                     return Either.right(responseFormat);
2647                 }
2648
2649                 if (payloadType.isHeatRelated()) {
2650                     log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType);
2651                     result = extractHeatParameters(artifactInfo);
2652                 }
2653             }
2654             if (result.isRight()) {
2655                 return Either.right(result.right().value());
2656             }
2657
2658         } // null/empty payload is normal if called from metadata update ONLY.
2659         // The validation of whether this is metadata/payload update case is
2660         // currently done separately
2661         else {
2662             if (!isArtifactMetadataUpdate) {
2663                 log.debug("In artifact: {} Payload is missing.",artifactInfo.getArtifactName());
2664                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
2665                 return Either.right(responseFormat);
2666             }
2667         }
2668         log.trace("Ended payload handling");
2669         return Either.left(decodedPayload);
2670     }
2671
2672
2673     public Either<Operation, ResponseFormat> deleteArtifactByInterface(String resourceId, String userUserId, String artifactId,
2674                                                                        boolean inTransaction) {
2675         User user = new User();
2676         user.setUserId(userUserId);
2677         Either<Resource, StorageOperationStatus> parent = toscaOperationFacade.getToscaElement(resourceId, JsonParseFlagEnum.ParseMetadata);
2678         if (parent.isRight()) {
2679             ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(parent
2680                     .right()
2681                     .value()));
2682             return Either.right(responseFormat);
2683         }
2684         Either<Either<ArtifactDefinition, Operation>, ResponseFormat> handleDelete = handleDelete(resourceId, artifactId, user, AuditingActionEnum.ARTIFACT_DELETE, ComponentTypeEnum.RESOURCE, parent
2685                         .left()
2686                         .value(),
2687                 false, inTransaction);
2688         if (handleDelete.isRight()) {
2689             return Either.right(handleDelete.right().value());
2690         }
2691         Either<ArtifactDefinition, Operation> result = handleDelete.left().value();
2692         return Either.left(result.right().value());
2693
2694     }
2695
2696     private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) {
2697         Operation op = new Operation();
2698         long time = System.currentTimeMillis();
2699         op.setCreationDate(time);
2700
2701         String artifactName = artifactInfo.getArtifactName();
2702         artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName));
2703
2704         op.setImplementation(artifactInfo);
2705         op.setLastUpdateDate(time);
2706         return op;
2707     }
2708
2709     private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) {
2710         String newArtifactName = operationName + "_" + artifactName;
2711         log.trace("converting artifact name {} to {}", artifactName, newArtifactName);
2712         return newArtifactName;
2713     }
2714
2715     // download by MSO
2716     public byte[] downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion, String artifactName) {
2717
2718         // General validation
2719         if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) {
2720             log.debug(NULL_PARAMETER);
2721             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2722         }
2723
2724         // Normalizing artifact name
2725         artifactName = ValidationUtils.normalizeFileName(artifactName);
2726
2727         // Resource validation
2728         Resource resource = validateResourceNameAndVersion(resourceName, resourceVersion);
2729         String resourceId = resource.getUniqueId();
2730
2731         // Service validation
2732         Service validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion);
2733
2734         Map<String, ArtifactDefinition> artifacts = resource.getDeploymentArtifacts();
2735         if (artifacts == null || artifacts.isEmpty()) {
2736             log.debug("Deployment artifacts of resource {} are not found", resourceId);
2737             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2738         }
2739
2740         ArtifactDefinition deploymentArtifact = null;
2741
2742         for (ArtifactDefinition artifactDefinition : artifacts.values()) {
2743             if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName()
2744                     .equals(artifactName)) {
2745                 log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2746                 deploymentArtifact = artifactDefinition;
2747                 break;
2748             }
2749         }
2750
2751         if (deploymentArtifact == null) {
2752             log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId);
2753             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactName);
2754         }
2755
2756         // Downloading the artifact
2757         ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deploymentArtifact);
2758         log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId());
2759         return downloadArtifactEither.getRight();
2760     }
2761
2762     // download by MSO
2763     public byte[] downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) {
2764
2765         // General validation
2766         if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) {
2767             log.debug(NULL_PARAMETER);
2768             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2769         }
2770
2771         // Normalizing artifact name
2772         artifactName = ValidationUtils.normalizeFileName(artifactName);
2773
2774         // Service validation
2775         Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2776
2777         // ResourceInstance validation
2778         ComponentInstance resourceInstance = validateResourceInstance(service, resourceInstanceName);
2779
2780         Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
2781
2782         final String finalArtifactName = artifactName;
2783         Predicate<ArtifactDefinition> filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName);
2784
2785         ArtifactDefinition deployableArtifact = artifacts==null ? null :
2786                 artifacts.values().stream()
2787                         .filter(filterArtifactByName)
2788                         .findFirst()
2789                         .orElse(null);
2790
2791         if (deployableArtifact == null) {
2792             log.debug("Deployment artifact with name {} not found", artifactName);
2793             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName));
2794         }
2795
2796         log.debug(FOUND_DEPLOYMENT_ARTIFACT, artifactName);
2797         ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(deployableArtifact);
2798
2799         log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId());
2800         return downloadArtifactEither.getRight();
2801     }
2802
2803     private ComponentInstance validateResourceInstance(Service service, String resourceInstanceName) {
2804
2805         List<ComponentInstance> riList = service.getComponentInstances();
2806         for (ComponentInstance ri : riList) {
2807             if (ri.getNormalizedName().equals(resourceInstanceName)) {
2808                 return ri;
2809             }
2810         }
2811         throw new ByActionStatusComponentException(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName);
2812     }
2813
2814     private ComponentInstance validateResourceInstanceById(Component component, String resourceInstanceId) {
2815
2816         List<ComponentInstance> riList = component.getComponentInstances();
2817         for (ComponentInstance ri : riList) {
2818             if (ri.getUniqueId().equals(resourceInstanceId)) {
2819                 return ri;
2820             }
2821         }
2822         throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceInstanceId);
2823     }
2824
2825     private Service validateServiceNameAndVersion(String serviceName, String serviceVersion) {
2826
2827         Either<List<Service>, StorageOperationStatus> serviceListBySystemName = toscaOperationFacade.getBySystemName(ComponentTypeEnum.SERVICE, serviceName);
2828         if (serviceListBySystemName.isRight()) {
2829             log.debug("Couldn't fetch any service with name {}", serviceName);
2830             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(serviceListBySystemName
2831                     .right()
2832                     .value(), ComponentTypeEnum.SERVICE), serviceName);
2833         }
2834         List<Service> serviceList = serviceListBySystemName.left().value();
2835         if (serviceList == null || serviceList.isEmpty()) {
2836             log.debug("Couldn't fetch any service with name {}", serviceName);
2837             throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceName);
2838         }
2839
2840         Service foundService = null;
2841         for (Service service : serviceList) {
2842             if (service.getVersion().equals(serviceVersion)) {
2843                 log.trace("Found service with version {}", serviceVersion);
2844                 foundService = service;
2845                 break;
2846             }
2847         }
2848
2849         if (foundService == null) {
2850             log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName);
2851             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE
2852                     .getValue(), serviceVersion);
2853         }
2854         return foundService;
2855     }
2856
2857     private Resource validateResourceNameAndVersion(String resourceName, String resourceVersion) {
2858
2859         Either<Resource, StorageOperationStatus> resourceListBySystemName = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.RESOURCE, resourceName, resourceVersion, JsonParseFlagEnum.ParseMetadata);
2860         if (resourceListBySystemName.isRight()) {
2861             log.debug("Couldn't fetch any resource with name {} and version {}. ", resourceName, resourceVersion);
2862             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(resourceListBySystemName
2863                     .right()
2864                     .value()), resourceName);
2865         }
2866         return resourceListBySystemName.left().value();
2867     }
2868
2869     public byte[] downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) {
2870         // Validation
2871         log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion, artifactName);
2872         if (serviceName == null || serviceVersion == null || artifactName == null) {
2873             log.debug(NULL_PARAMETER);
2874             throw new ByActionStatusComponentException(ActionStatus.INVALID_CONTENT);
2875         }
2876
2877         // Normalizing artifact name
2878         final String normalizedArtifactName = ValidationUtils.normalizeFileName(artifactName);
2879
2880         // Service validation
2881         Service service = validateServiceNameAndVersion(serviceName, serviceVersion);
2882         // Looking for deployment or tosca artifacts
2883         String serviceId = service.getUniqueId();
2884
2885         if (MapUtils.isEmpty(service.getDeploymentArtifacts()) && MapUtils.isEmpty(service.getToscaArtifacts())) {
2886             log.debug("Neither Deployment nor Tosca artifacts of service {} are found", serviceId);
2887             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2888         }
2889
2890         Optional<ArtifactDefinition> foundArtifactOptl = Optional.empty();
2891
2892         if (!MapUtils.isEmpty(service.getDeploymentArtifacts())) {
2893             foundArtifactOptl = service.getDeploymentArtifacts().values().stream()
2894                     // filters artifact by name
2895                     .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2896         }
2897         if ((!foundArtifactOptl.isPresent()) && !MapUtils.isEmpty(service.getToscaArtifacts())) {
2898             foundArtifactOptl = service.getToscaArtifacts().values().stream()
2899                     // filters TOSCA artifact by name
2900                     .filter(a -> a.getArtifactName().equals(normalizedArtifactName)).findAny();
2901         }
2902         if (!foundArtifactOptl.isPresent()) {
2903             log.debug("The artifact {} was not found for service {}", normalizedArtifactName, serviceId);
2904             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, normalizedArtifactName);
2905         }
2906         log.debug(FOUND_DEPLOYMENT_ARTIFACT, normalizedArtifactName);
2907         // Downloading the artifact
2908         ImmutablePair<String, byte[]> downloadArtifactEither = downloadArtifact(foundArtifactOptl
2909                 .get());
2910         log.trace("Download of service artifact succeeded, uniqueId {}", foundArtifactOptl.get().getUniqueId());
2911         return downloadArtifactEither.getRight();
2912     }
2913
2914     public ImmutablePair<String, byte[]> downloadArtifact(String parentId, String artifactUniqueId) {
2915         log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId);
2916         Either<ArtifactDefinition, StorageOperationStatus> artifactById = artifactToscaOperation.getArtifactById(parentId, artifactUniqueId);
2917         if (artifactById.isRight()) {
2918             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value());
2919             log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus);
2920             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatByArtifactId(actionStatus, ""));
2921         }
2922         ArtifactDefinition artifactDefinition = artifactById.left().value();
2923         if (artifactDefinition == null) {
2924             log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId);
2925             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""));
2926         }
2927
2928         return downloadArtifact(artifactDefinition);
2929     }
2930
2931     private boolean checkArtifactInComponent(Component component, String artifactId) {
2932         boolean found = false;
2933         Map<String, ArtifactDefinition> artifactsS = component.getArtifacts();
2934         if (artifactsS != null) {
2935             for (Map.Entry<String, ArtifactDefinition> entry : artifactsS.entrySet()) {
2936                 if (entry.getValue().getUniqueId().equals(artifactId)) {
2937                     found = true;
2938                     break;
2939                 }
2940             }
2941         }
2942         Map<String, ArtifactDefinition> deploymentArtifactsS = component.getDeploymentArtifacts();
2943         if (!found && deploymentArtifactsS != null) {
2944             for (Map.Entry<String, ArtifactDefinition> entry : deploymentArtifactsS.entrySet()) {
2945                 if (entry.getValue().getUniqueId().equals(artifactId)) {
2946                     found = true;
2947                     break;
2948                 }
2949             }
2950         }
2951         Map<String, ArtifactDefinition> toscaArtifactsS = component.getToscaArtifacts();
2952         if (!found && toscaArtifactsS != null) {
2953             for (Map.Entry<String, ArtifactDefinition> entry : toscaArtifactsS.entrySet()) {
2954                 if (entry.getValue().getUniqueId().equals(artifactId)) {
2955                     found = true;
2956                     break;
2957                 }
2958             }
2959         }
2960
2961         Map<String, InterfaceDefinition> interfaces = component.getInterfaces();
2962         if (!found && interfaces != null) {
2963             for (Map.Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) {
2964                 Map<String, Operation> operations = entry.getValue().getOperationsMap();
2965                 for (Map.Entry<String, Operation> entryOp : operations.entrySet()) {
2966                     if (entryOp.getValue().getImplementation() != null && entryOp.getValue()
2967                             .getImplementation()
2968                             .getUniqueId()
2969                             .equals(artifactId)) {
2970                         found = true;
2971                         break;
2972                     }
2973                 }
2974             }
2975         }
2976         switch (component.getComponentType()) {
2977             case RESOURCE:
2978                 break;
2979             case SERVICE:
2980                 Map<String, ArtifactDefinition> apiArtifacts = ((Service) component).getServiceApiArtifacts();
2981                 if (!found && apiArtifacts != null) {
2982                     for (Map.Entry<String, ArtifactDefinition> entry : apiArtifacts.entrySet()) {
2983                         if (entry.getValue().getUniqueId().equals(artifactId)) {
2984                             found = true;
2985                             break;
2986                         }
2987                     }
2988                 }
2989                 break;
2990             default:
2991
2992         }
2993
2994         return found;
2995     }
2996
2997     private boolean checkArtifactInResourceInstance(Component component, String resourceInstanceId, String artifactId) {
2998
2999         boolean found = false;
3000         List<ComponentInstance> resourceInstances = component.getComponentInstances();
3001         ComponentInstance resourceInstance = null;
3002         for (ComponentInstance ri : resourceInstances) {
3003             if (ri.getUniqueId().equals(resourceInstanceId)) {
3004                 resourceInstance = ri;
3005                 break;
3006             }
3007         }
3008         if (resourceInstance != null) {
3009             Map<String, ArtifactDefinition> artifacts = resourceInstance.getDeploymentArtifacts();
3010             if (artifacts != null) {
3011                 for (Map.Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) {
3012                     if (entry.getValue().getUniqueId().equals(artifactId)) {
3013                         found = true;
3014                         break;
3015                     }
3016                 }
3017             }
3018             if (!found) {
3019                 artifacts = resourceInstance.getArtifacts();
3020                 if (artifacts != null) {
3021                     for (Map.Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) {
3022                         if (entry.getValue().getUniqueId().equals(artifactId)) {
3023                             found = true;
3024                             break;
3025                         }
3026                     }
3027                 }
3028             }
3029         }
3030         return found;
3031     }
3032
3033     private Component validateComponentExists(String componentId, AuditingActionEnum auditingAction, User user, String artifactId, ComponentTypeEnum componentType,
3034                                               String containerComponentType) {
3035
3036         ComponentTypeEnum componentForAudit = null == containerComponentType ? componentType : ComponentTypeEnum.findByParamName(containerComponentType);
3037         componentForAudit.getNodeType();
3038
3039         Either<? extends Component, StorageOperationStatus> componentResult = toscaOperationFacade
3040                 .getToscaFullElement(componentId);
3041
3042         if (componentResult.isRight()) {
3043             ActionStatus status = componentForAudit == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : componentForAudit == ComponentTypeEnum.SERVICE ? ActionStatus.SERVICE_NOT_FOUND : ActionStatus.PRODUCT_NOT_FOUND;
3044             ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId);
3045             log.debug("Service not found, serviceId {}", componentId);
3046             handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null);
3047             throw new ByActionStatusComponentException(status, componentId);
3048         }
3049         return componentResult.left().value();
3050     }
3051
3052     private void validateWorkOnComponent(Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId, ArtifactOperationInfo operation) {
3053         if (operation.getArtifactOperationEnum() != ArtifactOperationEnum.DOWNLOAD && !operation.ignoreLifecycleState()) {
3054             try {
3055                 validateCanWorkOnComponent(component, userId);
3056             }catch (ComponentException e) {
3057                 String uniqueId = component.getUniqueId();
3058                 log.debug("Service status isn't  CHECKOUT or user isn't owner, serviceId {}", uniqueId);
3059                 handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, e.getResponseFormat(),
3060                         component.getComponentType(), null);
3061                 throw e;
3062             }
3063         }
3064     }
3065
3066     private void validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType, ArtifactOperationInfo operation) {
3067
3068         if (operation.isNotDownload()) {
3069             String role = user.getRole();
3070             if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) {
3071                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
3072                 log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role);
3073                 handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
3074                 throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3075             }
3076         }
3077     }
3078
3079     private User validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType, boolean inTransaction) {
3080         User user;
3081         try{
3082             user = validateUserExists(userId);
3083         } catch(ByResponseFormatComponentException e){
3084             ResponseFormat responseFormat = e.getResponseFormat();
3085             handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
3086             throw e;
3087         } catch(ByActionStatusComponentException e){
3088             ResponseFormat responseFormat = componentsUtils.getResponseFormat(e.getActionStatus(), e.getParams());
3089             handleComponentException(auditingAction, componentId, artifactId, responseFormat, componentType, userId);
3090             throw e;
3091         }
3092         return user;
3093     }
3094
3095     private void handleComponentException(AuditingActionEnum auditingAction, String componentId, String artifactId,
3096         ResponseFormat responseFormat, ComponentTypeEnum componentType, String userId){
3097         User user = new User();
3098         user.setUserId(userId);
3099         handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null);
3100     }
3101
3102     protected AuditingActionEnum detectAuditingType(ArtifactOperationInfo operation, String origMd5) {
3103         AuditingActionEnum auditingAction = null;
3104         switch (operation.getArtifactOperationEnum()) {
3105             case CREATE:
3106                 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD;
3107                 break;
3108             case UPDATE:
3109                 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE;
3110                 break;
3111             case DELETE:
3112                 auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE;
3113                 break;
3114             case DOWNLOAD:
3115                 auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD;
3116                 break;
3117             default:
3118                 break;
3119         }
3120         return auditingAction;
3121     }
3122
3123     private ImmutablePair<String, byte[]> downloadArtifact(ArtifactDefinition artifactDefinition) {
3124         String esArtifactId = artifactDefinition.getEsId();
3125         Either<DAOArtifactData, CassandraOperationStatus> artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3126         if (artifactfromES.isRight()) {
3127             CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3128             StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3129             ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3130             log.debug("Error when getting artifact from ES, error: {}", actionStatus);
3131             throw new ByActionStatusComponentException(actionStatus, artifactDefinition.getArtifactDisplayName());
3132         }
3133
3134         DAOArtifactData DAOArtifactData = artifactfromES.left().value();
3135         byte[] data = DAOArtifactData.getDataAsArray();
3136         if (data == null) {
3137             log.debug("Artifact data from cassandra is null");
3138             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName());
3139         }
3140         String artifactName = artifactDefinition.getArtifactName();
3141         log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName);
3142         return new ImmutablePair<>(artifactName, data);
3143     }
3144
3145     public DAOArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) {
3146         return new DAOArtifactData(artifactInfo.getEsId(), artifactPayload);
3147     }
3148
3149     private void saveArtifactInCassandra(DAOArtifactData artifactData, Component parent, ArtifactDefinition artifactInfo,
3150                                          String currArtifactId, String prevArtifactId, AuditingActionEnum auditingAction, ComponentTypeEnum componentType) {
3151         CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData);
3152
3153         if (resourceUploadStatus == CassandraOperationStatus.OK) {
3154             log.debug("Artifact {} was saved in component {}.", artifactData.getId(), parent.getUniqueId());
3155             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3156             handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId,
3157                     currArtifactId, responseFormat, componentType, null);
3158         }
3159         else {
3160             BeEcompErrorManager.getInstance().logBeDaoSystemError(UPDATE_ARTIFACT);
3161             log.info(FAILED_SAVE_ARTIFACT);
3162             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3163             handleAuditing(auditingAction, parent, parent.getUniqueId(), null, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null);
3164             throw new StorageException(resourceUploadStatus);
3165         }
3166     }
3167
3168     private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) {
3169         return auditingActionEnum == AuditingActionEnum.ARTIFACT_METADATA_UPDATE;
3170     }
3171
3172     private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) {
3173         return ArtifactGroupTypeEnum.DEPLOYMENT == artifactInfo.getArtifactGroupType();
3174     }
3175
3176     private boolean isInformationalArtifact(final ArtifactDefinition artifactInfo) {
3177         return ArtifactGroupTypeEnum.INFORMATIONAL == artifactInfo.getArtifactGroupType();
3178     }
3179
3180     private boolean isHeatArtifact(final ArtifactDefinition artifactInfo) {
3181         final String artifactType = artifactInfo.getArtifactType();
3182         final ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.parse(artifactType);
3183         if (artifactTypeEnum == null) {
3184             artifactInfo.setTimeout(NodeTemplateOperation.NON_HEAT_TIMEOUT);
3185             return false;
3186         }
3187         switch (artifactTypeEnum) {
3188             case HEAT:
3189             case HEAT_VOL:
3190             case HEAT_NET:
3191             case HEAT_ENV:
3192                 return true;
3193             default:
3194                 return false;
3195         }
3196     }
3197
3198
3199     public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, String userUserId, ArtifactGroupTypeEnum groupType, boolean inTransaction) {
3200         User user = userBusinessLogic.getUser(userUserId, inTransaction);
3201         return createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user, groupType);
3202     }
3203
3204     public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map<String, Object> artifactInfoMap, User user, ArtifactGroupTypeEnum groupType) {
3205         ArtifactDefinition artifactInfo = new ArtifactDefinition();
3206
3207         String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME);
3208         String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE);
3209         String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION);
3210
3211         artifactInfo.setArtifactDisplayName(artifactName);
3212         artifactInfo.setArtifactLabel(logicalName.toLowerCase());
3213         artifactInfo.setArtifactType(artifactType);
3214         artifactInfo.setDescription(artifactDescription);
3215         artifactInfo.setArtifactGroupType(groupType);
3216         nodeTemplateOperation.setDefaultArtifactTimeout(groupType, artifactInfo);
3217
3218         setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo);
3219
3220         return artifactInfo;
3221     }
3222
3223     private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) {
3224         String uniqueId = null;
3225
3226         if (resourceId != null) {
3227             uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel()
3228                     .toLowerCase());
3229             artifactInfo.setUniqueId(uniqueId);
3230         }
3231         artifactInfo.setUserIdCreator(user.getUserId());
3232         String fullName = user.getFullName();
3233         artifactInfo.setUpdaterFullName(fullName);
3234
3235         long time = System.currentTimeMillis();
3236
3237         artifactInfo.setCreatorFullName(fullName);
3238         artifactInfo.setCreationDate(time);
3239
3240         artifactInfo.setLastUpdateDate(time);
3241         artifactInfo.setUserIdLastUpdater(user.getUserId());
3242
3243         artifactInfo.setMandatory(true);
3244     }
3245
3246     public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, ArtifactGroupTypeEnum groupType, String instanceId) {
3247         return artifactToscaOperation.getArtifacts(parentId, parentType, groupType, instanceId);
3248     }
3249
3250     public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact, Component component, NodeTypeEnum parentType, String instanceId) {
3251         return artifactToscaOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, component, parentType, true, instanceId);
3252     }
3253
3254     private Either<DAOArtifactData, ResponseFormat> createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String payloadStr) {
3255
3256         byte[] payload = payloadStr.getBytes();
3257
3258         DAOArtifactData artifactData = createEsArtifactData(artifactDefinition, payload);
3259         return Either.left(artifactData);
3260     }
3261
3262     /**
3263      * @param artifactDefinition
3264      * @return
3265      */
3266     public Either<ArtifactDefinition, ResponseFormat> generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType, Component component, String resourceInstanceName, User modifier,
3267                                                                               String instanceId, boolean shouldLock, boolean inTransaction) {
3268         String payload = generateHeatEnvPayload(artifactDefinition);
3269         String prevUUID = artifactDefinition.getArtifactUUID();
3270         ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
3271         return generateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId, shouldLock, inTransaction)
3272                 .left()
3273                 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
3274     }
3275
3276     public Either<ArtifactDefinition, ResponseFormat> forceGenerateHeatEnvArtifact(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType, Component component, String resourceInstanceName, User modifier,
3277                                                                                    boolean shouldLock, boolean inTransaction, String instanceId) {
3278         String payload = generateHeatEnvPayload(artifactDefinition);
3279         String prevUUID = artifactDefinition.getArtifactUUID();
3280         ArtifactDefinition clonedBeforeGenerate = new ArtifactDefinition(artifactDefinition);
3281         return forceGenerateAndSaveHeatEnvArtifact(artifactDefinition, payload, componentType, component, resourceInstanceName, modifier, instanceId, shouldLock, inTransaction)
3282                 .left()
3283                 .bind(artifactDef -> updateArtifactOnGroupInstance(component, instanceId, prevUUID, clonedBeforeGenerate, artifactDef));
3284     }
3285
3286     @VisibleForTesting
3287     Either<ArtifactDefinition, ResponseFormat> updateArtifactOnGroupInstance(Component component, String instanceId, String prevUUID, ArtifactDefinition clonedBeforeGenerate, ArtifactDefinition updatedArtDef) {
3288         if (prevUUID == null || !prevUUID.equals(updatedArtDef.getArtifactUUID())) {
3289             List<ComponentInstance> componentInstances = component.getComponentInstances();
3290             if (componentInstances != null) {
3291                 Optional<ComponentInstance> findFirst = componentInstances.stream()
3292                         .filter(ci -> ci.getUniqueId()
3293                                 .equals(instanceId))
3294                         .findFirst();
3295                 if (findFirst.isPresent()) {
3296                     ComponentInstance relevantInst = findFirst.get();
3297                     List<GroupInstance> updatedGroupInstances = getUpdatedGroupInstances(updatedArtDef.getUniqueId(), clonedBeforeGenerate, relevantInst
3298                             .getGroupInstances());
3299
3300                     if (CollectionUtils.isNotEmpty(updatedGroupInstances)) {
3301                         updatedGroupInstances.forEach(gi -> {
3302                             gi.getGroupInstanceArtifacts().add(updatedArtDef.getUniqueId());
3303                             gi.getGroupInstanceArtifactsUuid().add(updatedArtDef.getArtifactUUID());
3304                         });
3305                         Either<List<GroupInstance>, StorageOperationStatus> status = toscaOperationFacade.updateGroupInstancesOnComponent(component, instanceId, updatedGroupInstances);
3306                         if (status.isRight()) {
3307                             log.debug(FAILED_UPDATE_GROUPS, component.getUniqueId());
3308                             ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils
3309                                     .convertFromStorageResponse(status.right()
3310                                             .value()), clonedBeforeGenerate.getArtifactDisplayName());
3311                             return Either.right(responseFormat);
3312                         }
3313                     }
3314                 }
3315             }
3316         }
3317         return Either.left(updatedArtDef);
3318     }
3319
3320     private String generateHeatEnvPayload(ArtifactDefinition artifactDefinition) {
3321         List<HeatParameterDefinition> heatParameters = artifactDefinition.getListHeatParameters();
3322         StringBuilder sb = new StringBuilder();
3323         sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader());
3324         sb.append("parameters:\n");
3325         if (heatParameters != null) {
3326             heatParameters.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
3327
3328             List<HeatParameterDefinition> empltyHeatValues = new ArrayList<>();
3329
3330             for (HeatParameterDefinition heatParameterDefinition : heatParameters) {
3331
3332                 String heatValue = heatParameterDefinition.getCurrentValue();
3333                 if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
3334                     heatValue = heatParameterDefinition.getDefaultValue();
3335                     if (!ValidationUtils.validateStringNotEmpty(heatValue)) {
3336                         empltyHeatValues.add(heatParameterDefinition);
3337                         continue;
3338                     }
3339                 }
3340                 HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType());
3341                 if (type != null) {
3342                     switch (type) {
3343                         case BOOLEAN:
3344                             sb.append("  ")
3345                                     .append(heatParameterDefinition.getName())
3346                                     .append(":")
3347                                     .append(" ")
3348                                     .append(Boolean.parseBoolean(heatValue))
3349                                     .append("\n");
3350                             break;
3351                         case NUMBER:
3352                             sb.append("  ")
3353                                     .append(heatParameterDefinition.getName())
3354                                     .append(":")
3355                                     .append(" ")
3356                                     .append(new BigDecimal(heatValue).toPlainString())
3357                                     .append("\n");
3358                             break;
3359                         case COMMA_DELIMITED_LIST:
3360                         case JSON:
3361                             sb.append("  ")
3362                                     .append(heatParameterDefinition.getName())
3363                                     .append(":")
3364                                     .append(" ")
3365                                     .append(heatValue)
3366                                     .append("\n");
3367                             break;
3368                         default:
3369                             String value = heatValue;
3370                             boolean starts = value.startsWith("\"");
3371                             boolean ends = value.endsWith("\"");
3372                             if (!(starts && ends)) {
3373                                 starts = value.startsWith("'");
3374                                 ends = value.endsWith("'");
3375                                 if (!(starts && ends)) {
3376                                     value = "\"" + value + "\"";
3377                                 }
3378                             }
3379                             sb.append("  ")
3380                                     .append(heatParameterDefinition.getName())
3381                                     .append(":")
3382                                     .append(" ")
3383                                     .append(value);
3384                             sb.append("\n");
3385                             break;
3386
3387                     }
3388                 }
3389             }
3390             if (!empltyHeatValues.isEmpty()) {
3391                 empltyHeatValues.sort(Comparator.comparing(HeatParameterDataDefinition::getName));
3392                 empltyHeatValues.forEach(hv -> {
3393                     sb.append("  ").append(hv.getName()).append(":");
3394                     HeatParameterType type = HeatParameterType.isValidType(hv.getType());
3395                     if (type != null && type == HeatParameterType.STRING && (hv.getCurrentValue() != null && "".equals(hv
3396                             .getCurrentValue()) || hv.getDefaultValue() != null && "".equals(hv.getDefaultValue()))) {
3397                         sb.append(" \"\"").append("\n");
3398                     }
3399                     else {
3400                         sb.append(" ").append("\n");
3401                     }
3402                 });
3403             }
3404         }
3405         sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter());
3406
3407         // DE265919 fix
3408         return sb.toString().replaceAll("\\\\n", "\n");
3409     }
3410
3411     /**
3412      * @param artifactDefinition
3413      * @param payload
3414      * @return
3415      */
3416     public Either<ArtifactDefinition, ResponseFormat> generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload, ComponentTypeEnum componentType, Component component, String resourceInstanceName,
3417                                                                                      User modifier, String instanceId, boolean shouldLock, boolean inTransaction) {
3418         return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction, artifactDefinition::getHeatParamsUpdateDate,
3419                 () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
3420
3421     }
3422
3423     public Either<ArtifactDefinition, ResponseFormat> forceGenerateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload, ComponentTypeEnum componentType, Component component, String resourceInstanceName,
3424                                                                                           User modifier, String instanceId, boolean shouldLock, boolean inTransaction) {
3425         return generateArtifactPayload(artifactDefinition, componentType, component, resourceInstanceName, modifier, shouldLock, inTransaction, System::currentTimeMillis,
3426                 () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload), instanceId);
3427
3428     }
3429
3430     protected Either<ArtifactDefinition, ResponseFormat> generateArtifactPayload(ArtifactDefinition artifactDefinition, ComponentTypeEnum componentType, Component component, String resourceInstanceName, User modifier,
3431                                                                                  boolean shouldLock, boolean inTransaction, Supplier<Long> payloadUpdateDateGen, Supplier<Either<DAOArtifactData, ResponseFormat>> esDataCreator, String instanceId) {
3432
3433         log.trace("Start generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition
3434                 .getEsId());
3435         if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0 || artifactDefinition
3436                 .getPayloadUpdateDate() <= payloadUpdateDateGen.get()) {
3437
3438             log.trace("Generating payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId());
3439             Either<DAOArtifactData, ResponseFormat> artifactDataRes = esDataCreator.get();
3440             DAOArtifactData artifactData = null;
3441
3442             if (artifactDataRes.isLeft()) {
3443                 artifactData = artifactDataRes.left().value();
3444             }
3445             else {
3446                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3447                 handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3448                                 .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3449                         ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3450
3451                 return Either.right(artifactDataRes.right().value());
3452             }
3453             String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(artifactData.getDataAsArray());
3454             String oldCheckSum;
3455             String esArtifactId = artifactDefinition.getEsId();
3456             Either<DAOArtifactData, CassandraOperationStatus> artifactfromES;
3457             DAOArtifactData DAOArtifactData;
3458             if (esArtifactId != null && !esArtifactId.isEmpty() && artifactDefinition.getPayloadData() == null) {
3459                 log.debug("Try to fetch artifact from cassandra with id : {}", esArtifactId);
3460                 artifactfromES = artifactCassandraDao.getArtifact(esArtifactId);
3461                 if (artifactfromES.isRight()) {
3462                     CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value();
3463                     StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus);
3464                     ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse);
3465                     log.debug("Error when getting artifact from ES, error: {} esid : {}", actionStatus, esArtifactId);
3466                     return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName()));
3467                 }
3468                 DAOArtifactData = artifactfromES.left().value();
3469                 oldCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(DAOArtifactData.getDataAsArray());
3470             }
3471             else {
3472                 oldCheckSum = artifactDefinition.getArtifactChecksum();
3473
3474             }
3475             Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinitionStatus = null;
3476
3477             if (shouldLock) {
3478                 try {
3479                     lockComponent(component, "Update Artifact - lock resource: ");
3480                 }catch (ComponentException e){
3481                     handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null, artifactDefinition
3482                             .getUniqueId(), e.getResponseFormat(), component.getComponentType(), null);
3483                     throw e;
3484                 }
3485             }
3486             try {
3487                 if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) {
3488
3489                     artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get());
3490                     updateArifactDefinitionStatus = artifactToscaOperation.updateArtifactOnResource(artifactDefinition, component
3491                             ,artifactDefinition.getUniqueId(), componentType.getNodeType(), instanceId, true);
3492                     log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition
3493                             .getArtifactType(), artifactDefinition.getEsId());
3494                     if (updateArifactDefinitionStatus.isRight()) {
3495                         ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus
3496                                 .right()
3497                                 .value()), artifactDefinition.getArtifactDisplayName());
3498                         log.trace("Failed to update payloadUpdateDate {}", artifactDefinition.getEsId());
3499                         handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3500                                         .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3501                                 ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3502
3503                         return Either.right(responseFormat);
3504                     }
3505                 }
3506                 else {
3507                     artifactDefinition.getArtifactChecksum();
3508                     artifactDefinition.setArtifactChecksum(newCheckSum);
3509                     artifactDefinition.setEsId(artifactDefinition.getUniqueId());
3510                     log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition
3511                             .getArtifactType(), artifactDefinition.getEsId());
3512                     updateArifactDefinitionStatus = artifactToscaOperation.updateArtifactOnResource(artifactDefinition, component,
3513                             artifactDefinition.getUniqueId(), componentType.getNodeType(), instanceId, true);
3514
3515                     log.trace("Update Payload {}", artifactDefinition.getEsId());
3516                 }
3517                 if (updateArifactDefinitionStatus.isLeft()) {
3518
3519                     artifactDefinition = updateArifactDefinitionStatus.left().value();
3520                     artifactData.setId(artifactDefinition.getUniqueId());
3521                     CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData);
3522
3523                     if (saveArtifactStatus == CassandraOperationStatus.OK) {
3524                         if (!inTransaction) {
3525                             janusGraphDao.commit();
3526                         }
3527                         log.debug("Artifact Saved In cassandra {}", artifactData.getId());
3528                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
3529                         handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3530                                         .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3531                                 ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3532
3533                     }
3534                     else {
3535                         if (!inTransaction) {
3536                             janusGraphDao.rollback();
3537                         }
3538                         log.info("Failed to save artifact {}.", artifactData.getId());
3539                         ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
3540                         handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3541                                         .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3542                                 ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3543
3544                         return Either.right(responseFormat);
3545                     }
3546                 }
3547                 else {
3548                     ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus
3549                             .right()
3550                             .value()), artifactDefinition.getArtifactDisplayName());
3551                     log.debug("Failed To update artifact {}", artifactData.getId());
3552                     handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition
3553                                     .getUniqueId(), artifactDefinition.getUniqueId(), responseFormat,
3554                             ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName);
3555
3556                     return Either.right(responseFormat);
3557
3558                 }
3559             }
3560             finally {
3561                 if (shouldLock) {
3562                     graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType()
3563                             .getNodeType());
3564                 }
3565             }
3566         }
3567
3568         return Either.left(artifactDefinition);
3569     }
3570
3571
3572     public Map<String, Object> buildJsonForUpdateArtifact(ArtifactDefinition artifactDef, ArtifactGroupTypeEnum artifactGroupType, List<ArtifactTemplateInfo> updatedRequiredArtifacts) {
3573         return this.buildJsonForUpdateArtifact(artifactDef.getUniqueId(), artifactDef.getArtifactName(), artifactDef.getArtifactType(), artifactGroupType, artifactDef
3574                         .getArtifactLabel(), artifactDef.getArtifactDisplayName(),
3575                 artifactDef.getDescription(), artifactDef.getPayloadData(), updatedRequiredArtifacts, artifactDef.getListHeatParameters());
3576
3577     }
3578
3579     public Map<String, Object> buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType, ArtifactGroupTypeEnum artifactGroupType, String label, String displayName, String description, byte[] artifactContent,
3580                                                           List<ArtifactTemplateInfo> updatedRequiredArtifacts, List<HeatParameterDefinition> heatParameters) {
3581
3582         Map<String, Object> json = new HashMap<>();
3583         if (artifactId != null && !artifactId.isEmpty()) {
3584             json.put(Constants.ARTIFACT_ID, artifactId);
3585         }
3586
3587         json.put(Constants.ARTIFACT_NAME, artifactName);
3588         json.put(Constants.ARTIFACT_TYPE, artifactType);
3589         json.put(Constants.ARTIFACT_DESCRIPTION, description);
3590
3591         if (artifactContent != null) {
3592             log.debug("payload is encoded. perform decode");
3593             String encodedPayload = Base64.encodeBase64String(artifactContent);
3594             json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload);
3595         }
3596         json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName);
3597         json.put(Constants.ARTIFACT_LABEL, label);
3598         json.put(Constants.ARTIFACT_GROUP_TYPE, artifactGroupType.getType());
3599         json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>()
3600                 : updatedRequiredArtifacts.stream()
3601                 .filter(e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e
3602                         .getType()
3603                         .equals(ArtifactTypeEnum.HEAT_NESTED.getType()))
3604                 .map(ArtifactTemplateInfo::getFileName)
3605                 .collect(Collectors.toList()));
3606         json.put(Constants.ARTIFACT_HEAT_PARAMS, (heatParameters == null || heatParameters.isEmpty()) ? new ArrayList<>()
3607                 : heatParameters);
3608         return json;
3609     }
3610
3611     public Either<ArtifactDefinition, Operation> updateResourceInstanceArtifactNoContent(String resourceId, Component containerComponent, User user, Map<String, Object> json, ArtifactOperationInfo operation, ArtifactDefinition artifactInfo) {
3612
3613         String jsonStr = gson.toJson(json);
3614         ArtifactDefinition artifactDefinitionFromJson = artifactInfo == null ? RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class, false) : artifactInfo;
3615         String artifactUniqueId = artifactDefinitionFromJson == null ? null : artifactDefinitionFromJson.getUniqueId();
3616         Either<ArtifactDefinition, Operation> uploadArtifactToService = validateAndHandleArtifact(resourceId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactUniqueId,
3617                 artifactDefinitionFromJson, null, jsonStr, null, null, user, containerComponent, false, false, true);
3618
3619         return Either.left(uploadArtifactToService.left().value());
3620     }
3621
3622     private Either<ArtifactDefinition, Operation> handleUpdateHeatEnvAndHeatMeta(String componentId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType,
3623                                                                                  Component parent, String originData, String origMd5, ArtifactOperationInfo operation) {
3624         if (origMd5 != null) {
3625             validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation);
3626             if (ArrayUtils.isNotEmpty(artifactInfo.getPayloadData())) {
3627                 validateDeploymentArtifact(artifactInfo, parent);
3628                 handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction));
3629             } else { // duplicate
3630                 throw new ByActionStatusComponentException(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD);
3631             }
3632         }
3633         return updateHeatEnvParamsAndMetadata(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, origMd5);
3634     }
3635
3636     private Either<ArtifactDefinition, Operation> updateHeatEnvParamsAndMetadata(String componentId, String artifactId, ArtifactDefinition artifactInfo, User user, AuditingActionEnum auditingAction, Component parent,
3637                                                                                  ComponentTypeEnum componentType, String origMd5) {
3638         Either<ComponentInstance, ResponseFormat> getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user);
3639         if (getRI.isRight()) {
3640             throw new ByResponseFormatComponentException(getRI.right().value());
3641         }
3642         ComponentInstance ri = getRI.left().value();
3643         Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user);
3644         if (getArtifactRes.isRight()) {
3645             throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3646         }
3647         ArtifactDefinition currArtifact = getArtifactRes.left().value();
3648
3649         if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) ||
3650                 currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_VOL.getType()) ||
3651                 currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) {
3652             throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION);
3653         }
3654         List<HeatParameterDefinition> currentHeatEnvParams = currArtifact.getListHeatParameters();
3655         List<HeatParameterDefinition> updatedHeatEnvParams = artifactInfo.getListHeatParameters();
3656
3657         // upload
3658         if (origMd5 != null) {
3659             Either<List<HeatParameterDefinition>, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction, parent, user, artifactInfo,
3660                     artifactId, componentType, ri.getName(), currentHeatEnvParams, updatedHeatEnvParams, currArtifact.getArtifactName());
3661             if (uploadParamsValidationResult.isRight()) {
3662                 throw new ByResponseFormatComponentException(uploadParamsValidationResult.right().value());
3663             }
3664             artifactInfo.setListHeatParameters(updatedHeatEnvParams);
3665         }
3666
3667         Either<ArtifactDefinition, ResponseFormat> validateAndConvertHeatParamers = validateAndConvertHeatParameters(artifactInfo, ArtifactTypeEnum.HEAT_ENV.getType());
3668         if (validateAndConvertHeatParamers.isRight()) {
3669             throw new ByResponseFormatComponentException(validateAndConvertHeatParamers.right().value());
3670         }
3671
3672         if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) {
3673             // fill reduced heat env parameters List for updating
3674             boolean updateRequired = replaceCurrHeatValueWithUpdatedValue(currentHeatEnvParams, updatedHeatEnvParams);
3675             if (updateRequired) {
3676                 currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis());
3677                 currArtifact.setListHeatParameters(currentHeatEnvParams);
3678                 Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation.updateArtifactOnResource(
3679                         currArtifact, parent, currArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3680                 if (updateArtifactRes.isRight()) {
3681                     log.debug("Failed to update artifact on graph  - {}", artifactId);
3682                     throw new StorageException(updateArtifactRes.right().value());
3683                 }
3684                 StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(ri, updateArtifactRes.left().value().getUniqueId(), parent.getUniqueId());
3685                 if (error != StorageOperationStatus.OK) {
3686                     throw new StorageException(error);
3687                 }
3688             }
3689         }
3690         updateHeatMetaDataIfNeeded(componentId,user,auditingAction,componentType, parent,ri,artifactInfo);
3691         StorageOperationStatus error = generateCustomizationUUIDOnInstance(parent.getUniqueId(), ri.getUniqueId(), componentType);
3692         if (error != StorageOperationStatus.OK) {
3693             throw new StorageException(error);
3694         }
3695
3696         return Either.left(currArtifact);
3697     }
3698
3699     private void
3700     updateHeatMetaDataIfNeeded(String componentId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType, Component parent, ComponentInstance resourceInstance, ArtifactDefinition updatedHeatEnvArtifact) {
3701         String heatArtifactId = updatedHeatEnvArtifact.getGeneratedFromId();
3702         Either<ArtifactDefinition, ResponseFormat> getArtifactRes = getArtifactFromRI(parent, resourceInstance, componentId, heatArtifactId, auditingAction, user);
3703         if (getArtifactRes.isRight()) {
3704             throw new ByResponseFormatComponentException(getArtifactRes.right().value());
3705         }
3706         ArtifactDefinition heatArtifactToUpdate = getArtifactRes.left().value();
3707         if (isUpdateHeatMetaDataNeeded(updatedHeatEnvArtifact, heatArtifactToUpdate)) {
3708             validateHeatMetaData(updatedHeatEnvArtifact);
3709             updateHeatMetadataFromHeatEnv(updatedHeatEnvArtifact, heatArtifactToUpdate);
3710             Either<ArtifactDefinition, StorageOperationStatus> updateArtifactRes = artifactToscaOperation.updateArtifactOnResource(heatArtifactToUpdate, parent,
3711                     heatArtifactToUpdate.getUniqueId(), componentType.getNodeType(), componentId, false);
3712
3713             if (updateArtifactRes.isRight()) {
3714                 log.debug("Failed to update artifact on graph  - {}", heatArtifactId);
3715                 throw new StorageException(updateArtifactRes.right().value());
3716             }
3717             ArtifactDefinition artifactDefinition = updateArtifactRes.left().value();
3718             updateGeneratedIdInHeatEnvOnInstance(resourceInstance, parent, heatArtifactId, heatArtifactToUpdate, artifactDefinition, componentType.getNodeType());
3719             StorageOperationStatus error = generateCustomizationUUIDOnGroupInstance(resourceInstance, artifactDefinition.getUniqueId(), parent.getUniqueId());
3720             if (error != StorageOperationStatus.OK) {
3721                 throw new StorageException(error);
3722             }
3723         }
3724     }
3725
3726     private void validateHeatMetaData(ArtifactDefinition updatedHeatEnv) {
3727         Integer maxMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMaxMinutes();
3728         Integer minMinutes = ConfigurationManager.getConfigurationManager().getConfiguration().getHeatArtifactDeploymentTimeout().getMinMinutes();
3729         Integer updateTimeout = updatedHeatEnv.getTimeout();
3730         if (updateTimeout > maxMinutes || updateTimeout < minMinutes) {
3731             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_INVALID_TIMEOUT);
3732         }
3733     }
3734
3735     private boolean isUpdateHeatMetaDataNeeded(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3736         // currently only timeout metadata can be updated
3737         return !origHeat.getTimeout().equals(updatedHeatEnv.getTimeout());
3738     }
3739
3740     private void updateHeatMetadataFromHeatEnv(ArtifactDefinition updatedHeatEnv, ArtifactDefinition origHeat) {
3741         // currently only timeout metadata can be updated
3742         origHeat.setTimeout(updatedHeatEnv.getTimeout());
3743     }
3744
3745     private boolean replaceCurrHeatValueWithUpdatedValue(List<HeatParameterDefinition> currentHeatEnvParams, List<HeatParameterDefinition> updatedHeatEnvParams) {
3746         boolean isUpdate = false;
3747         List<String> currentParamsNames = currentHeatEnvParams.stream().map(x -> x.getName()).collect(Collectors.toList());
3748         for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3749             String paramName = heatEnvParam.getName();
3750             validateParamName(paramName, currentParamsNames);
3751             for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3752                 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3753                     String updatedParamValue = heatEnvParam.getCurrentValue();
3754                     if (!Objects.equals(updatedParamValue, currHeatParam.getCurrentValue())) {
3755                         currHeatParam.setCurrentValue(updatedParamValue);
3756                         isUpdate = true;
3757                     }
3758                 }
3759             }
3760         }
3761         return isUpdate;
3762     }
3763
3764     private void validateParamName(String paramName, List<String> heatParamsNames) {
3765         if (!heatParamsNames.contains(paramName)) {
3766             throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, paramName);
3767         }
3768     }
3769
3770     private Either<ArtifactDefinition, Operation> updateHeatParams(String componentId, ArtifactDefinition artifactEnvInfo, AuditingActionEnum auditingAction, Component parent,
3771                                                                    ComponentTypeEnum componentType, ArtifactDefinition currHeatArtifact, boolean needToUpdateGroup) {
3772         Either<ArtifactDefinition, Operation> insideEither = null;
3773         String currentHeatId = currHeatArtifact.getUniqueId();
3774
3775         String esArtifactId = currHeatArtifact.getEsId();
3776         Either<DAOArtifactData, CassandraOperationStatus> artifactFromES = artifactCassandraDao.getArtifact(esArtifactId);
3777         if (artifactFromES.isRight()) {
3778             StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromES.right().value());
3779             throw new StorageException(storageResponse, currHeatArtifact.getArtifactDisplayName());
3780         }
3781
3782         DAOArtifactData DAOArtifactData = artifactFromES.left().value();
3783         ArtifactDefinition updatedHeatArt = currHeatArtifact;
3784         List<HeatParameterDefinition> updatedHeatEnvParams = artifactEnvInfo.getListHeatParameters();
3785         List<HeatParameterDefinition> currentHeatEnvParams = currHeatArtifact.getListHeatParameters();
3786         List<HeatParameterDefinition> newHeatEnvParams = new ArrayList<>();
3787
3788         if (CollectionUtils.isNotEmpty(updatedHeatEnvParams) && CollectionUtils.isNotEmpty(currentHeatEnvParams)) {
3789             //TODO: improve complexity - currently N^2
3790             String paramName;
3791             for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) {
3792                 paramName = heatEnvParam.getName();
3793                 for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3794                     if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3795                         String updatedParamValue = heatEnvParam.getCurrentValue();
3796                         if (updatedParamValue == null) {
3797                             updatedParamValue = heatEnvParam.getDefaultValue();
3798                         }
3799                         HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType());
3800                         if (!paramType.getValidator().isValid(updatedParamValue, null)) {
3801                             throw new ByActionStatusComponentException(ActionStatus.INVALID_HEAT_PARAMETER_VALUE,
3802                                     ArtifactTypeEnum.HEAT_ENV.getType(), paramType.getType(), paramName);
3803                         }
3804                         currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null));
3805                         newHeatEnvParams.add(currHeatParam);
3806                         break;
3807                     }
3808                 }
3809             }
3810             if (!newHeatEnvParams.isEmpty()) {
3811                 currHeatArtifact.setListHeatParameters(currentHeatEnvParams);
3812                 Either<ArtifactDefinition, StorageOperationStatus> operationStatus = artifactToscaOperation.updateArtifactOnResource(
3813                         currHeatArtifact, parent, currHeatArtifact.getUniqueId(), componentType.getNodeType(), componentId, true);
3814
3815                 if (operationStatus.isRight()) {
3816                     log.debug("Failed to update artifact on graph  - {}", currHeatArtifact.getUniqueId());
3817                     throw new StorageException(operationStatus.right().value());
3818                 }
3819                 updatedHeatArt = operationStatus.left().value();
3820                 if (!updatedHeatArt.getDuplicated() || DAOArtifactData.getId() == null) {
3821                     DAOArtifactData.setId(updatedHeatArt.getEsId());
3822                 }
3823                 saveArtifactInCassandra(DAOArtifactData, parent, artifactEnvInfo, currentHeatId, updatedHeatArt
3824                         .getUniqueId(), auditingAction, componentType);
3825                 insideEither = Either.left(updatedHeatArt);
3826             }
3827         }
3828         Either<ArtifactDefinition, StorageOperationStatus> updateHeatEnvArtifact;
3829         if (!currentHeatId.equals(updatedHeatArt.getUniqueId())) {
3830             artifactEnvInfo.setArtifactChecksum(null);
3831             updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvArtifact(parent, artifactEnvInfo, currentHeatId, updatedHeatArt
3832                     .getUniqueId(), componentType.getNodeType(), componentId);
3833         }
3834         else {
3835             //TODO Andrey check if componentId = parent.getUniqeId
3836             updateHeatEnvArtifact = artifactToscaOperation.updateHeatEnvPlaceholder(artifactEnvInfo, parent, componentType
3837                     .getNodeType());
3838
3839         }
3840         if (needToUpdateGroup && updateHeatEnvArtifact.isLeft()) {
3841             ActionStatus result = updateGroupForHeat(currHeatArtifact, updatedHeatArt, artifactEnvInfo,
3842                     updateHeatEnvArtifact.left().value(), parent);
3843             if (result != ActionStatus.OK) {
3844                 throw new ByActionStatusComponentException(result);
3845             }
3846         }
3847         if (updatedHeatEnvParams.isEmpty()) {
3848             throw new ByActionStatusComponentException(ActionStatus.INVALID_YAML, currHeatArtifact.getArtifactName());
3849         }
3850         return insideEither;
3851     }
3852
3853
3854     private StorageOperationStatus generateCustomizationUUIDOnGroupInstance(ComponentInstance ri, String artifactId, String componentId) {
3855         StorageOperationStatus error = StorageOperationStatus.OK;
3856         log.debug("Need to re-generate  customization UUID for group instance on component instance  {}", ri.getUniqueId());
3857         List<GroupInstance> groupsInstances = ri.getGroupInstances();
3858         List<String> groupInstancesId = null;
3859         if (groupsInstances != null && !groupsInstances.isEmpty()) {
3860             groupInstancesId = groupsInstances.stream()
3861                     .filter(p -> p.getGroupInstanceArtifacts() != null && p.getGroupInstanceArtifacts()
3862                             .contains(artifactId))
3863                     .map(GroupInstanceDataDefinition::getUniqueId)
3864                     .collect(Collectors.toList());
3865         }
3866         if (groupInstancesId != null && !groupInstancesId.isEmpty()) {
3867             toscaOperationFacade.generateCustomizationUUIDOnInstanceGroup(componentId, ri.getUniqueId(), groupInstancesId);
3868         }
3869         return error;
3870
3871     }
3872
3873     public Either<List<HeatParameterDefinition>, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent, User user, ArtifactDefinition artifactInfo, String artifactId, ComponentTypeEnum componentType,
3874                                                                                                  String riName, List<HeatParameterDefinition> currentHeatEnvParams, List<HeatParameterDefinition> updatedHeatEnvParams, String currArtifactName) {
3875
3876         if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) {
3877             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo
3878                     .getArtifactName(), currArtifactName);
3879             handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3880             return Either.right(responseFormat);
3881         }
3882
3883         for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) {
3884             String paramName = uploadedHeatParam.getName();
3885             boolean isExistsInHeat = false;
3886             for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) {
3887                 if (paramName.equalsIgnoreCase(currHeatParam.getName())) {
3888
3889                     isExistsInHeat = true;
3890                     uploadedHeatParam.setType(currHeatParam.getType());
3891                     uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue());
3892                     uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue());
3893                     uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId());
3894                     break;
3895                 }
3896             }
3897             if (!isExistsInHeat) {
3898                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName);
3899                 handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName);
3900                 return Either.right(responseFormat);
3901             }
3902         }
3903         return Either.left(updatedHeatEnvParams);
3904     }
3905
3906     private Either<ComponentInstance, ResponseFormat> getRIFromComponent(Component component, String riID, String artifactId, AuditingActionEnum auditingAction, User user) {
3907         ResponseFormat responseFormat = null;
3908         List<ComponentInstance> ris = component.getComponentInstances();
3909         for (ComponentInstance ri : ris) {
3910             if (riID.equals(ri.getUniqueId())) {
3911                 return Either.left(ri);
3912             }
3913         }
3914         responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID);
3915         log.debug("Resource Instance not found, resourceInstanceId {}", riID);
3916         handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null);
3917         return Either.right(responseFormat);
3918     }
3919
3920     private Either<ArtifactDefinition, ResponseFormat> getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId, AuditingActionEnum auditingAction, User user) {
3921         ResponseFormat responseFormat = null;
3922         Map<String, ArtifactDefinition> rtifactsMap = ri.getDeploymentArtifacts();
3923         for (ArtifactDefinition artifact : rtifactsMap.values()) {
3924             if (artifactId.equals(artifact.getUniqueId())) {
3925                 return Either.left(artifact);
3926             }
3927         }
3928         responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId());
3929         handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, ri
3930                 .getName());
3931         return Either.right(responseFormat);
3932     }
3933
3934     public ArtifactDefinition extractArtifactDefinition(Either<ArtifactDefinition, Operation> eitherArtifact) {
3935         ArtifactDefinition ret;
3936         if (eitherArtifact.isLeft()) {
3937             ret = eitherArtifact.left().value();
3938         }
3939         else {
3940             ret = eitherArtifact.right().value().getImplementationArtifact();
3941         }
3942         return ret;
3943     }
3944
3945     public byte[] downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo) {
3946         Component component = getComponentByUuid(componentType, componentUuid);
3947         resourceCommonInfo.setResourceName(component.getName());
3948         return downloadArtifact(component.getAllArtifacts(), artifactUUID, component.getName());
3949     }
3950
3951     /**
3952      * downloads an artifact of resource instance of component by UUIDs
3953      *
3954      * @param componentType
3955      * @param componentUuid
3956      * @param resourceInstanceName
3957      * @param artifactUUID
3958      * @return
3959      */
3960     public byte[] downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid,
3961                                                           String resourceInstanceName, String artifactUUID) {
3962         ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName);
3963         return downloadArtifact(resourceInstance == null ? null : resourceInstance.getDeploymentArtifacts(),
3964                 artifactUUID, resourceInstance.getName());
3965     }
3966
3967     /**
3968      * uploads an artifact to a component by UUID
3969      *
3970      * @param data
3971      * @param request
3972      * @param componentType
3973      * @param componentUuid
3974      * @param resourceCommonInfo
3975      * @param operation
3976      * @return
3977      */
3978     public ArtifactDefinition uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType,
3979                                                               String componentUuid, ResourceCommonInfo resourceCommonInfo,                                                                                      ArtifactOperationInfo operation) {
3980         Either<ArtifactDefinition, Operation> actionResult;
3981         Component component;
3982         String componentId;
3983         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
3984         String origMd5 = request.getHeader(Constants.MD5_HEADER);
3985         String userId = request.getHeader(Constants.USER_ID_HEADER);
3986
3987         Either<ComponentMetadataData, StorageOperationStatus> getComponentRes =
3988                 toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true);
3989         if (getComponentRes.isRight()) {
3990             StorageOperationStatus status = getComponentRes.right().value();
3991             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
3992             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status, componentType), componentUuid);
3993         }
3994
3995         ComponentMetadataDataDefinition componentMetadataDataDefinition = getComponentRes.left().value().getMetadataDataDefinition();
3996         componentId = componentMetadataDataDefinition.getUniqueId();
3997         String componentName = componentMetadataDataDefinition.getName();
3998
3999         if (!componentMetadataDataDefinition
4000                 .getState()
4001                 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4002             component = checkoutParentComponent(componentType, componentId, userId);
4003             if (component != null) {
4004                 componentId = component.getUniqueId();
4005                 componentName = component.getName();
4006             }
4007         }
4008         resourceCommonInfo.setResourceName(componentName);
4009
4010         actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo,
4011                 origMd5, data, null, null, null, null);
4012         return actionResult.left().value();
4013     }
4014
4015     /**
4016      * upload an artifact to a resource instance by UUID
4017      *
4018      * @param data
4019      * @param request
4020      * @param componentType
4021      * @param componentUuid
4022      * @param resourceInstanceName
4023      * @param operation
4024      * @return
4025      */
4026     public ArtifactDefinition uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName,
4027                                                        ArtifactOperationInfo operation) {
4028         Either<ArtifactDefinition, Operation> actionResult;
4029         Component component = null;
4030         String componentInstanceId;
4031         String componentId;
4032         String origMd5 = request.getHeader(Constants.MD5_HEADER);
4033         String userId = request.getHeader(Constants.USER_ID_HEADER);
4034
4035         ImmutablePair<Component, ComponentInstance> componentRiPair = null;
4036         Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true);
4037         if (getComponentRes.isRight()) {
4038             StorageOperationStatus status = getComponentRes.right().value();
4039             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4040             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status, componentType), resourceInstanceName);
4041         }
4042         if (!getComponentRes.left()
4043                 .value()
4044                 .getMetadataDataDefinition()
4045                 .getState()
4046                 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4047             component = checkoutParentComponent(componentType, getComponentRes.left()
4048                     .value()
4049                     .getMetadataDataDefinition()
4050                     .getUniqueId(), userId);
4051         }
4052         if (component == null) {
4053             componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
4054         }
4055         else {
4056             componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
4057         }
4058         componentInstanceId = componentRiPair.getRight().getUniqueId();
4059         componentId = componentRiPair.getLeft().getUniqueId();
4060         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
4061
4062         actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE,
4063                 operation, null, artifactInfo, origMd5, data, null, null,
4064                 componentId, ComponentTypeEnum.findParamByType(componentType));
4065
4066         return actionResult.left().value();
4067     }
4068
4069     /**
4070      * updates an artifact on a component by UUID
4071      *
4072      * @param data
4073      * @param request
4074      * @param componentType
4075      * @param componentUuid
4076      * @param artifactUUID
4077      * @param resourceCommonInfo
4078      * @param operation        TODO
4079      * @return
4080      */
4081     public ArtifactDefinition updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String artifactUUID,
4082                                                               ResourceCommonInfo resourceCommonInfo, ArtifactOperationInfo operation) {
4083         Either<ArtifactDefinition, Operation> actionResult;
4084         Component component;
4085         String componentId;
4086         String artifactId ;
4087         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
4088         String origMd5 = request.getHeader(Constants.MD5_HEADER);
4089         String userId = request.getHeader(Constants.USER_ID_HEADER);
4090
4091         Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true);
4092         if (getComponentRes.isRight()) {
4093             StorageOperationStatus status = getComponentRes.right().value();
4094             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4095             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4096         }
4097         componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
4098         String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
4099
4100         if (!getComponentRes.left()
4101                 .value()
4102                 .getMetadataDataDefinition()
4103                 .getState()
4104                 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4105             component = checkoutParentComponent(componentType, componentId, userId);
4106             if (component != null) {
4107                 componentId = component.getUniqueId();
4108                 componentName = component.getName();
4109             }
4110         }
4111         resourceCommonInfo.setResourceName(componentName);
4112         artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
4113         actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo,
4114                 origMd5, data, null, null, null, null);
4115         if (actionResult.isRight()) {
4116             log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, componentUuid, actionResult
4117                     .right()
4118                     .value());
4119         }
4120
4121         return actionResult.left().value();
4122     }
4123
4124     /**
4125      * updates an artifact on a resource instance by UUID
4126      *
4127      * @param data
4128      * @param request
4129      * @param componentType
4130      * @param componentUuid
4131      * @param resourceInstanceName
4132      * @param artifactUUID
4133      * @param operation            TODO
4134      * @return
4135      */
4136     public ArtifactDefinition updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, String artifactUUID,
4137                                                        ArtifactOperationInfo operation) {
4138
4139         Either<ArtifactDefinition, Operation> actionResult;
4140         Component component = null;
4141         String componentInstanceId;
4142         String componentId;
4143         String artifactId;
4144         String origMd5 = request.getHeader(Constants.MD5_HEADER);
4145         String userId = request.getHeader(Constants.USER_ID_HEADER);
4146
4147         ImmutablePair<Component, ComponentInstance> componentRiPair = null;
4148         Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true);
4149         if (getComponentRes.isRight()) {
4150             StorageOperationStatus status = getComponentRes.right().value();
4151             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4152             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4153         }
4154         if (!getComponentRes.left()
4155                 .value()
4156                 .getMetadataDataDefinition()
4157                 .getState()
4158                 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4159             component = checkoutParentComponent(componentType, getComponentRes.left()
4160                     .value()
4161                     .getMetadataDataDefinition()
4162                     .getUniqueId(), userId);
4163         }
4164         if (component == null) {
4165             componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
4166         }
4167         else {
4168             componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
4169         }
4170         componentInstanceId = componentRiPair.getRight().getUniqueId();
4171         componentId = componentRiPair.getLeft().getUniqueId();
4172         artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
4173         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class, false);
4174
4175         actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo, origMd5, data, null, null, componentId, ComponentTypeEnum
4176                 .findParamByType(componentType));
4177         return actionResult.left().value();
4178     }
4179
4180     private Either<ArtifactDefinition, ResponseFormat> updateOperationArtifact(String componentId, String interfaceType, String operationUuid, ArtifactDefinition artifactInfo){
4181         Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
4182         if (componentStorageOperationStatusEither.isRight()) {
4183             StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
4184             log.debug("Failed to fetch resource information by resource id, error {}", errorStatus);
4185             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
4186         }
4187         Component storedComponent = componentStorageOperationStatusEither.left().value();
4188
4189         Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType);
4190         if(!optionalInterface.isPresent()) {
4191             log.debug("Failed to get resource interface for resource Id {}", componentId);
4192             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType));
4193         }
4194
4195         //fetch the operation from storage
4196         InterfaceDefinition gotInterface = optionalInterface.get();
4197         Map<String, Operation> operationsMap = gotInterface.getOperationsMap();
4198         Optional<Operation> optionalOperation = operationsMap.values()
4199                 .stream()
4200                 .filter(o -> o.getUniqueId().equals(operationUuid))
4201                 .findFirst();
4202         if (!optionalOperation.isPresent()) {
4203             log.debug("Failed to get resource interface operation for resource Id {} and operationId {}", componentId, operationUuid);
4204             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId);
4205             return Either.right(responseFormat);
4206         }
4207
4208         Operation operation = optionalOperation.get();
4209         ArtifactDefinition implementationArtifact =  operation.getImplementationArtifact();
4210         implementationArtifact.setArtifactUUID(artifactInfo.getArtifactUUID());
4211         implementationArtifact.setUniqueId(artifactInfo.getUniqueId());
4212         implementationArtifact.setArtifactName(artifactInfo.getArtifactName());
4213         implementationArtifact.setDescription(artifactInfo.getDescription());
4214         implementationArtifact.setArtifactType(artifactInfo.getArtifactType());
4215         implementationArtifact.setArtifactLabel(artifactInfo.getArtifactLabel());
4216         implementationArtifact.setArtifactDisplayName(artifactInfo.getArtifactDisplayName());
4217         implementationArtifact.setEsId(artifactInfo.getEsId());
4218         operation.setImplementation(implementationArtifact);
4219         gotInterface.setOperationsMap(operationsMap);
4220         Either<List<InterfaceDefinition>, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither =
4221                 interfaceOperation.updateInterfaces(storedComponent.getUniqueId(), Collections.singletonList(gotInterface));
4222         if (interfaceDefinitionStorageOperationStatusEither.isRight()){
4223             StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value();
4224             ActionStatus actionStatus =
4225                     componentsUtils.convertFromStorageResponseForDataType(storageOperationStatus);
4226             return Either.right(componentsUtils.getResponseFormat(actionStatus));
4227         }
4228
4229         return Either.left(artifactInfo);
4230     }
4231
4232
4233     /**
4234      * updates an artifact on a component by UUID
4235      *
4236      * @param data
4237      * @param request
4238      * @param componentType
4239      * @param componentUuid
4240      * @param artifactUUID
4241      * @param operation
4242      * @return
4243      */
4244     public Either<ArtifactDefinition, ResponseFormat> updateArtifactOnInterfaceOperationByResourceUUID(
4245             String data, HttpServletRequest request, ComponentTypeEnum componentType,
4246             String componentUuid, String interfaceUUID, String operationUUID, String artifactUUID,
4247         ResourceCommonInfo resourceCommonInfo,ArtifactOperationInfo operation) {
4248         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4249         Either<ArtifactDefinition, ResponseFormat> updateArtifactResult;
4250         Either<Either<ArtifactDefinition, Operation>, ResponseFormat> actionResult = null;
4251         ArtifactDefinition updateArtifact = null;
4252         String componentId = null;
4253         ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinitionForUpdate(data, ArtifactDefinition.class);
4254         String origMd5 = request.getHeader(Constants.MD5_HEADER);
4255         String userId = request.getHeader(Constants.USER_ID_HEADER);
4256         ArtifactDefinition existingArtifactInfo = null;
4257         String interfaceName = null;
4258
4259         Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true);
4260         if (getComponentRes.isRight()) {
4261             StorageOperationStatus status = getComponentRes.right().value();
4262             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4263             errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
4264         }
4265
4266         if (errorWrapper.isEmpty()) {
4267             componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
4268             String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
4269             if (!getComponentRes.left()
4270                     .value()
4271                     .getMetadataDataDefinition()
4272                     .getState()
4273                     .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4274                 Component component = checkoutParentComponent(componentType, componentId, userId);
4275                 if (component != null) {
4276                     componentId = component.getUniqueId();
4277                     componentName = component.getName();
4278                 }
4279
4280             }
4281             resourceCommonInfo.setResourceName(componentName);
4282         }
4283
4284         if(errorWrapper.isEmpty()){
4285             Either<String, ResponseFormat> interfaceNameEither = fetchInterfaceName(componentId, interfaceUUID);
4286             if (interfaceNameEither.isRight()) {
4287                 errorWrapper.setInnerElement(interfaceNameEither.right().value());
4288             }
4289             else {
4290                 interfaceName = interfaceNameEither.left().value();
4291             }
4292
4293             if(errorWrapper.isEmpty()){
4294                 Either<Component, StorageOperationStatus> toscaComponentEither = toscaOperationFacade.getToscaElement(componentId);
4295                 if (toscaComponentEither.isRight()) {
4296                     StorageOperationStatus status = toscaComponentEither.right().value();
4297                     log.debug("Could not fetch component with type {} and id {}. Status is {}. ", componentType, componentId, status);
4298                     errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status)));
4299                 }
4300
4301                 if (errorWrapper.isEmpty()) {
4302                     NodeTypeEnum parentType = convertParentType(componentType);
4303                     final List<ArtifactDefinition> existingDeploymentArtifacts =
4304                         getDeploymentArtifacts(toscaComponentEither.left().value(),null);
4305                     for (ArtifactDefinition artifactDefinition: existingDeploymentArtifacts){
4306                         if(artifactInfo.getArtifactName().equalsIgnoreCase(artifactDefinition.getArtifactName())){
4307                             existingArtifactInfo = artifactDefinition;
4308                             break;
4309                         }
4310                     }
4311                     if(existingArtifactInfo != null){
4312                         return updateOperationArtifact(componentId, interfaceName, operationUUID, existingArtifactInfo);
4313                     }
4314                 }
4315             }
4316         }
4317
4318         if (errorWrapper.isEmpty()) {
4319                 try {
4320                     actionResult = Either.left(handleArtifactRequest(componentId, userId, componentType, operation,
4321                             artifactUUID, artifactInfo, origMd5, data, interfaceName,
4322                             operationUUID, null, null));
4323                 }catch (ComponentException e){
4324                     errorWrapper.setInnerElement(e.getResponseFormat());
4325             }
4326         }
4327
4328         if (errorWrapper.isEmpty()) {
4329             updateArtifact = actionResult.left().value().left().value();
4330             updateArtifactResult = Either.left(updateArtifact);
4331
4332         }
4333         else {
4334             updateArtifactResult = Either.right(errorWrapper.getInnerElement());
4335         }
4336         return updateArtifactResult;
4337     }
4338
4339     private Either<String, ResponseFormat> fetchInterfaceName(String componentId, String interfaceUUID) {
4340         Either<Component, StorageOperationStatus> componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId);
4341         if (componentStorageOperationStatusEither.isRight()) {
4342             StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value();
4343             log.debug("Failed to fetch component information by component id, error {}", errorStatus);
4344             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
4345         }
4346         Component storedComponent = componentStorageOperationStatusEither.left().value();
4347
4348         Optional<InterfaceDefinition> optionalInterface = InterfaceOperationUtils
4349             .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID);
4350         if(!optionalInterface.isPresent()) {
4351             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID));
4352         }
4353         return Either.left(optionalInterface.get().getType());
4354     }
4355
4356     /**
4357      * deletes an artifact on a component by UUID
4358      *
4359      * @param request
4360      * @param componentType
4361      * @param componentUuid
4362      * @param artifactUUID
4363      * @param resourceCommonInfo
4364      * @param operation        TODO
4365      * @return
4366      */
4367     public ArtifactDefinition deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String artifactUUID, ResourceCommonInfo resourceCommonInfo,
4368                                                               ArtifactOperationInfo operation) {
4369
4370         Either<ArtifactDefinition, Operation> actionResult;
4371         Component component;
4372         String componentId ;
4373         String artifactId;
4374         String origMd5 = request.getHeader(Constants.MD5_HEADER);
4375         String userId = request.getHeader(Constants.USER_ID_HEADER);
4376
4377         Either<ComponentMetadataData, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true);
4378         if (getComponentRes.isRight()) {
4379             StorageOperationStatus status = getComponentRes.right().value();
4380             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4381             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status, componentType), componentUuid);
4382         }
4383         componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId();
4384         String componentName = getComponentRes.left().value().getMetadataDataDefinition().getName();
4385         if (!getComponentRes.left()
4386                 .value()
4387                 .getMetadataDataDefinition()
4388                 .getState()
4389                 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4390             component = checkoutParentComponent(componentType, componentId, userId);
4391             if (component != null) {
4392                 componentId = component.getUniqueId();
4393                 componentName = component.getName();
4394             }
4395         }
4396         resourceCommonInfo.setResourceName(componentName);
4397         artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, componentId, componentType);
4398         actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null);
4399         return actionResult.left().value();
4400     }
4401
4402     /**
4403      * deletes an artifact from a resource instance by UUID
4404      *
4405      * @param request
4406      * @param componentType
4407      * @param componentUuid
4408      * @param resourceInstanceName
4409      * @param artifactUUID
4410      * @param operation            TODO
4411      * @return
4412      */
4413     public ArtifactDefinition deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType,
4414                                                        String componentUuid, String resourceInstanceName,
4415                                                        String artifactUUID, ArtifactOperationInfo operation) {
4416
4417         Either<ArtifactDefinition, Operation> actionResult;
4418         Component component = null;
4419         String componentInstanceId;
4420         String componentId;
4421         String artifactId;
4422         String origMd5 = request.getHeader(Constants.MD5_HEADER);
4423         String userId = request.getHeader(Constants.USER_ID_HEADER);
4424         ImmutablePair<Component, ComponentInstance> componentRiPair = null;
4425         Either<ComponentMetadataData, StorageOperationStatus> getComponentRes =
4426                 toscaOperationFacade.getLatestComponentMetadataByUuid(componentUuid, JsonParseFlagEnum.ParseMetadata, true);
4427         if (getComponentRes.isRight()) {
4428             StorageOperationStatus status = getComponentRes.right().value();
4429             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4430             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4431         }
4432         if (!getComponentRes.left()
4433                 .value()
4434                 .getMetadataDataDefinition()
4435                 .getState()
4436                 .equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
4437             component = checkoutParentComponent(componentType, getComponentRes.left()
4438                     .value()
4439                     .getMetadataDataDefinition()
4440                     .getUniqueId(), userId);
4441         }
4442         if (component == null) {
4443             componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName);
4444         }
4445         else {
4446             componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName);
4447         }
4448         componentInstanceId = componentRiPair.getRight().getUniqueId();
4449         componentId = componentRiPair.getLeft().getUniqueId();
4450         artifactId = findArtifactId(componentRiPair.getRight(), artifactUUID);
4451
4452         actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5, null, null, null, componentId, ComponentTypeEnum
4453                 .findParamByType(componentType));
4454         return actionResult.left().value();
4455     }
4456
4457     private String findArtifactId(ComponentInstance instance, String artifactUUID) {
4458         String artifactId = null;
4459         ArtifactDefinition foundArtifact = null;
4460         if (instance.getDeploymentArtifacts() != null) {
4461             foundArtifact = instance.getDeploymentArtifacts()
4462                     .values()
4463                     .stream()
4464                     .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID()
4465                             .equals(artifactUUID))
4466                     .findFirst()
4467                     .orElse(null);
4468         }
4469         if (foundArtifact == null && instance.getArtifacts() != null) {
4470             foundArtifact = instance.getArtifacts()
4471                     .values()
4472                     .stream()
4473                     .filter(e -> e.getArtifactUUID() != null && e.getArtifactUUID()
4474                             .equals(artifactUUID))
4475                     .findFirst()
4476                     .orElse(null);
4477         }
4478         if (foundArtifact == null) {
4479             log.debug("The artifact {} was not found on instance {}. ", artifactUUID, instance.getUniqueId());
4480             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4481         }
4482         else {
4483             artifactId = foundArtifact.getUniqueId();
4484         }
4485         return artifactId;
4486     }
4487
4488     @SuppressWarnings("unchecked")
4489     public ArtifactDefinition createHeatEnvPlaceHolder(List<ArtifactDefinition> createdArtifacts, ArtifactDefinition heatArtifact,
4490                                                        String envType, String parentId, NodeTypeEnum parentType,
4491                                                        String parentName, User user, Component component,
4492                                                        Map<String, String> existingEnvVersions) {
4493         Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager()
4494                 .getConfiguration()
4495                 .getDeploymentResourceInstanceArtifacts();
4496         if (deploymentResourceArtifacts == null) {
4497             log.debug("no deployment artifacts are configured for generated artifacts");
4498             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
4499         }
4500         Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(envType);
4501         if (placeHolderData == null) {
4502             log.debug("no env type {} are configured for generated artifacts", envType);
4503             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
4504         }
4505
4506         String envLabel = (heatArtifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase();
4507         ArtifactDefinition createArtifactPlaceHolder = createArtifactPlaceHolderInfo(parentId, envLabel, placeHolderData, user
4508                 .getUserId(), ArtifactGroupTypeEnum.DEPLOYMENT, true);
4509         ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder;
4510         artifactHeatEnv.setGeneratedFromId(heatArtifact.getUniqueId());
4511         artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis());
4512         artifactHeatEnv.setTimeout(0);
4513         artifactHeatEnv.setIsFromCsar(heatArtifact.getIsFromCsar());
4514         buildHeatEnvFileName(heatArtifact, artifactHeatEnv, placeHolderData);
4515         // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow
4516         handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions);
4517         ArtifactDefinition heatEnvPlaceholder;
4518         // Evg : for resource instance artifact will be added later as block with other env artifacts from BL
4519         if (parentType != NodeTypeEnum.ResourceInstance) {
4520             String checkSum = artifactToscaOperation.sortAndCalculateChecksumForHeatParameters(heatArtifact.getHeatParameters());
4521             artifactHeatEnv.setArtifactChecksum(checkSum);
4522             Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact = addHeatEnvArtifact(artifactHeatEnv, heatArtifact, component, parentType, parentId);
4523             if (addHeatEnvArtifact.isRight()) {
4524                 log.debug("failed to create heat env artifact on resource instance");
4525                 throw new ByResponseFormatComponentException(componentsUtils.getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact
4526                         .right()
4527                         .value(), false), "", null));
4528             }
4529             heatEnvPlaceholder = createArtifactPlaceHolder;
4530         }
4531         else {
4532             heatEnvPlaceholder = artifactHeatEnv;
4533             artifactToscaOperation.generateUUID(heatEnvPlaceholder, heatEnvPlaceholder.getArtifactVersion());
4534             setHeatCurrentValuesOnHeatEnvDefaultValues(heatArtifact, heatEnvPlaceholder);
4535         }
4536         ComponentTypeEnum componentType = component.getComponentType();
4537         if (parentType == NodeTypeEnum.ResourceInstance) {
4538             componentType = ComponentTypeEnum.RESOURCE_INSTANCE;
4539         }
4540         createdArtifacts.add(heatEnvPlaceholder);
4541         componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user, component, AuditingActionEnum.ARTIFACT_UPLOAD,
4542                 new ResourceCommonInfo(parentName, componentType.getValue()),
4543                 ResourceVersionInfo.newBuilder().build(),
4544                 ResourceVersionInfo.newBuilder().artifactUuid(heatEnvPlaceholder.getUniqueId()).build(),
4545                 null, heatEnvPlaceholder, null);
4546         return heatEnvPlaceholder;
4547     }
4548
4549     private void setHeatCurrentValuesOnHeatEnvDefaultValues(ArtifactDefinition artifact, ArtifactDefinition artifactDefinition) {
4550         if (artifact.getListHeatParameters() == null) {
4551             return;
4552         }
4553         List<HeatParameterDefinition> heatEnvParameters = new ArrayList<>();
4554         for (HeatParameterDefinition parameter : artifact.getListHeatParameters()) {
4555             HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter);
4556             heatEnvParameter.setDefaultValue(parameter.getCurrentValue());
4557             heatEnvParameter.setCurrentValue(null);
4558             heatEnvParameters.add(heatEnvParameter);
4559         }
4560         artifactDefinition.setListHeatParameters(heatEnvParameters);
4561     }
4562
4563     private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map<String, Object> placeHolderData) {
4564         String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName());
4565         String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION);
4566         String name = heatArtifact.getArtifactName();
4567         String fileName;
4568         if (name == null) {
4569             name = heatArtifact.getArtifactLabel();
4570             fileName = name + "." + envExtension;
4571         }
4572         else {
4573             fileName = name.replaceAll("." + heatExtension, "." + envExtension);
4574         }
4575         heatEnvArtifact.setArtifactName(fileName);
4576     }
4577
4578     private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map<String, String> existingEnvVersions) {
4579         if (null != existingEnvVersions) {
4580             String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName());
4581             if (null != prevVersion) {
4582                 heatEnvArtifact.setArtifactVersion(prevVersion);
4583             }
4584         }
4585     }
4586
4587     public List<ArtifactDefinition> handleArtifactsForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4588                                                                         ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4589         ComponentTypeEnum componentType = component.getComponentType();
4590         List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4591         Either<ArtifactDefinition, Operation> result;
4592         try {
4593             for (ArtifactDefinition artifactDefinition : artifactsToHandle) {
4594                 result = handleLoadedArtifact(component, user, operation, shouldLock, inTransaction, componentType, artifactDefinition);
4595                 uploadedArtifacts.add(result.left().value());
4596             }
4597         } catch (ComponentException e) {
4598             log.debug(FAILED_UPLOAD_ARTIFACT_TO_COMPONENT, componentType, component
4599                     .getName(), e.getResponseFormat());
4600             if (operation.isCreateOrLink()) {
4601                 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4602             }
4603             throw e;
4604         }
4605         return uploadedArtifacts;
4606     }
4607
4608     public Either<ArtifactDefinition, Operation> handleLoadedArtifact(Resource component, User user, ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction,
4609                                                                       ComponentTypeEnum componentType, ArtifactDefinition artifactDefinition) {
4610         AuditingActionEnum auditingAction = detectAuditingType(operation, "");
4611         String componentId = component.getUniqueId();
4612         String artifactId = artifactDefinition.getUniqueId();
4613         Either<ArtifactDefinition, Operation> result;
4614         Wrapper<ResponseFormat> errorWrapper = new Wrapper<>();
4615         //artifact validation
4616         artifactDefinition = validateArtifact(componentId, componentType, operation,
4617                 artifactId, artifactDefinition, auditingAction, user,
4618                 component, shouldLock, inTransaction);
4619         switch (operation.getArtifactOperationEnum()) {
4620             case CREATE:
4621                 byte[] validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component, null, null);
4622                 result = createArtifact(component, componentId, artifactDefinition, validPayload,
4623                         componentType, auditingAction, null, null);
4624                 break;
4625             case UPDATE:
4626                 validPayload = getValidPayload(componentId, artifactDefinition, operation, auditingAction, artifactId, user, componentType, component, null, null);
4627                 result = handleUpdate(componentId, componentType, operation, artifactId, artifactDefinition, validPayload, null, null, null, null,
4628                         auditingAction, user, component, true);
4629                 break;
4630             case DELETE:
4631                 result = Either.left(handleDeleteInternal(componentId, artifactId, componentType, component));
4632                 break;
4633             case DOWNLOAD:
4634                 if (artifactGenerationRequired(component, artifactDefinition)) {
4635                     result = Either.left(generateNotSavedArtifact(component, artifactDefinition));
4636                 } else {
4637                     result = Either.left(handleDownload(componentId, artifactId, componentType, component));
4638                 }
4639                 break;
4640             case LINK:
4641                 result = Either.left(handleLink(componentId, artifactDefinition, componentType, component));
4642                 break;
4643             default:
4644                 throw new UnsupportedOperationException("In ArtifactsBusinessLogic received illegal operation: " + operation.getArtifactOperationEnum());
4645         }
4646         return result;
4647     }
4648
4649     public List<ArtifactDefinition> handleArtifactsRequestForInnerVfcComponent(List<ArtifactDefinition> artifactsToHandle, Resource component, User user, List<ArtifactDefinition> vfcsNewCreatedArtifacts,
4650                                                                                ArtifactOperationInfo operation, boolean shouldLock, boolean inTransaction) {
4651
4652         List<ArtifactDefinition> handleArtifactsResult;
4653         ComponentTypeEnum componentType = component.getComponentType();
4654         List<ArtifactDefinition> uploadedArtifacts = new ArrayList<>();
4655         Either<ArtifactDefinition, Operation> actionResult;
4656         String originData;
4657         String origMd5;
4658         try {
4659             for (ArtifactDefinition artifact : artifactsToHandle) {
4660                 originData = buildJsonStringForCsarVfcArtifact(artifact);
4661                 origMd5 = GeneralUtility.calculateMD5Base64EncodedByString(originData);
4662                 actionResult = handleArtifactRequest(component.getUniqueId(), user.getUserId(), componentType, operation, artifact
4663                         .getUniqueId(), artifact, origMd5, originData, null, null, null, null, shouldLock, inTransaction);
4664                 uploadedArtifacts.add(actionResult.left().value());
4665             }
4666             handleArtifactsResult = uploadedArtifacts;
4667         }catch (ComponentException e){
4668             if (operation.isCreateOrLink()) {
4669                 vfcsNewCreatedArtifacts.addAll(uploadedArtifacts);
4670             }
4671             throw e;
4672         }
4673         return handleArtifactsResult;
4674     }
4675
4676     private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName) {
4677         ComponentInstance componentInstance;
4678         String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4679         Component component = getComponentByUuid(componentType, componentUuid);
4680         componentInstance = (component == null) ? null : component.getComponentInstances()
4681                 .stream()
4682                 .filter(ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName())
4683                         .equals(normalizedName))
4684                 .findFirst()
4685                 .orElse(null);
4686         if (componentInstance == null) {
4687             log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4688             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4689                     RESOURCE_INSTANCE, component.getComponentType().getValue(), component.getName());
4690         }
4691         return componentInstance;
4692     }
4693
4694     private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(Component component, String resourceInstanceName) {
4695
4696         ImmutablePair<Component, ComponentInstance> relatedComponentComponentInstancePair = null;
4697         String normalizedName = ValidationUtils.normalizeComponentInstanceName(resourceInstanceName);
4698         ComponentInstance componentInstance = component.getComponentInstances()
4699                 .stream()
4700                 .filter(ci -> ValidationUtils.normalizeComponentInstanceName(ci.getName())
4701                         .equals(normalizedName))
4702                 .findFirst()
4703                 .orElse(null);
4704         if (componentInstance == null) {
4705             log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4706             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName,
4707                     RESOURCE_INSTANCE, component.getComponentType().getValue(), component.getName());
4708         }
4709         else {
4710             relatedComponentComponentInstancePair = new ImmutablePair<>(component, componentInstance);
4711         }
4712         return relatedComponentComponentInstancePair;
4713     }
4714
4715     private ImmutablePair<Component, ComponentInstance> getRelatedComponentComponentInstance(ComponentTypeEnum componentType,
4716                                                                                              String componentUuid, String resourceInstanceName) {
4717         ComponentInstance componentInstance;
4718         ImmutablePair<Component, ComponentInstance> relatedComponentComponentInstancePair;
4719         Component component = getLatestComponentByUuid(componentType, componentUuid);
4720         componentInstance = component.getComponentInstances()
4721                 .stream()
4722                 .filter(ci -> ci.getNormalizedName().equals(resourceInstanceName))
4723                 .findFirst()
4724                 .orElse(null);
4725         if (componentInstance == null) {
4726             log.debug(COMPONENT_INSTANCE_NOT_FOUND, resourceInstanceName, component.getName());
4727             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
4728                     resourceInstanceName, RESOURCE_INSTANCE, component
4729                     .getComponentType().getValue(), component.getName());
4730         }
4731         else {
4732             relatedComponentComponentInstancePair = new ImmutablePair<>(component, componentInstance);
4733         }
4734         return relatedComponentComponentInstancePair;
4735     }
4736
4737     private byte[] downloadArtifact(Map<String, ArtifactDefinition> artifacts, String artifactUUID, String componentName) {
4738
4739         ImmutablePair<String, byte[]> downloadArtifact;
4740         List<ArtifactDefinition> artifactsList = null;
4741         ArtifactDefinition deploymentArtifact;
4742         if (artifacts != null && !artifacts.isEmpty()) {
4743             artifactsList = artifacts.values()
4744                     .stream()
4745                     .filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID()
4746                             .equals(artifactUUID))
4747                     .collect(Collectors.toList());
4748         }
4749         if (artifactsList == null || artifactsList.isEmpty()) {
4750             log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName);
4751             throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID);
4752         }
4753         deploymentArtifact = artifactsList.get(0);
4754         downloadArtifact = downloadArtifact(deploymentArtifact);
4755         log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId());
4756         return downloadArtifact.getRight();
4757     }
4758
4759     private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4760         Component component;
4761         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getLatestComponentByUuid(componentUuid);
4762         if (getComponentRes.isRight()) {
4763             StorageOperationStatus status = getComponentRes.right().value();
4764             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4765             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4766         }
4767         else {
4768             component = getComponentRes.left().value();
4769         }
4770         return component;
4771     }
4772
4773     private Component getComponentByUuid(ComponentTypeEnum componentType, String componentUuid) {
4774         Component component;
4775         Either<List<Component>, StorageOperationStatus> getComponentRes = toscaOperationFacade.getComponentListByUuid(componentUuid, null);
4776         if (getComponentRes.isRight()) {
4777             StorageOperationStatus status = getComponentRes.right().value();
4778             log.debug(FAILED_FETCH_COMPONENT, componentType, componentUuid, status);
4779             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status));
4780         }
4781         else {
4782             List<Component> value = getComponentRes.left().value();
4783             if (value.isEmpty()) {
4784                 log.debug("Could not fetch component with type {} and uuid {}.", componentType, componentUuid);
4785                 ActionStatus status = componentType == ComponentTypeEnum.RESOURCE ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND;
4786                 throw new ByActionStatusComponentException(status);
4787             }
4788             else {
4789                 component = value.get(0);
4790             }
4791         }
4792         return component;
4793     }
4794
4795     private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, String parentId, ComponentTypeEnum componentType) {
4796         ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND;
4797         StorageOperationStatus storageStatus;
4798         ArtifactDefinition latestArtifact;
4799         List<ArtifactDefinition> artifacts;
4800         Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsRes = artifactToscaOperation.getArtifacts(parentId);
4801         if (getArtifactsRes.isRight()) {
4802             storageStatus = getArtifactsRes.right().value();
4803             log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType, parentId, storageStatus);
4804             if (storageStatus != StorageOperationStatus.NOT_FOUND) {
4805                 actionStatus = componentsUtils.convertFromStorageResponse(storageStatus);
4806             }
4807             throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4808         }
4809         artifacts = getArtifactsRes.left()
4810                 .value()
4811                 .values()
4812                 .stream()
4813                 .filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID()
4814                         .equals(artifactUUID))
4815                 .collect(Collectors.toList());
4816         if (artifacts == null || artifacts.isEmpty()) {
4817             log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType, parentId, actionStatus);
4818             throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4819         }
4820         latestArtifact = artifacts.stream().max((a1, a2) -> {
4821             int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion()));
4822             if (compareRes == 0) {
4823                 compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(), a2.getLastUpdateDate() == null ? 0 : a2
4824                         .getLastUpdateDate());
4825             }
4826             return compareRes;
4827         }).get();
4828         if (latestArtifact == null) {
4829             log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType, parentId, actionStatus);
4830             throw new ByActionStatusComponentException(actionStatus, artifactUUID);
4831         }
4832         return latestArtifact.getUniqueId();
4833     }
4834
4835     private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId) {
4836
4837         Component component = null;
4838         User modifier = userBusinessLogic.getUser(userId, false);
4839         LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout", LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API);
4840         Either<? extends Component, ResponseFormat> checkoutRes = lifecycleBusinessLogic.changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true);
4841         if (checkoutRes.isRight()) {
4842             log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType
4843                     .getNodeType(), parentId, checkoutRes.right().value().getStatus());
4844             throw new ByResponseFormatComponentException(checkoutRes.right().value());
4845         }
4846         return checkoutRes.left().value();
4847     }
4848
4849     private String buildJsonStringForCsarVfcArtifact(ArtifactDefinition artifact) {
4850         Map<String, Object> json = new HashMap<>();
4851         String artifactName = artifact.getArtifactName();
4852         json.put(Constants.ARTIFACT_NAME, artifactName);
4853         json.put(Constants.ARTIFACT_LABEL, artifact.getArtifactLabel());
4854         json.put(Constants.ARTIFACT_TYPE, artifact.getArtifactType());
4855         json.put(Constants.ARTIFACT_GROUP_TYPE, ArtifactGroupTypeEnum.DEPLOYMENT.getType());
4856         json.put(Constants.ARTIFACT_DESCRIPTION, artifact.getDescription());
4857         json.put(Constants.ARTIFACT_PAYLOAD_DATA, artifact.getPayloadData());
4858         json.put(Constants.ARTIFACT_DISPLAY_NAME, artifact.getArtifactDisplayName());
4859         return gson.toJson(json);
4860     }
4861
4862     @Autowired
4863     void setNodeTemplateOperation(NodeTemplateOperation nodeTemplateOperation) {
4864         this.nodeTemplateOperation = nodeTemplateOperation;
4865     }
4866
4867     public List<ArtifactConfiguration> getConfiguration() {
4868         return ConfigurationManager.getConfigurationManager().getConfiguration().getArtifacts();
4869     }
4870
4871 }
4872