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