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