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