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