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