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