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