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