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