Make Service base type optional
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ServiceBusinessLogic.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  * Modifications copyright (c) 2019 Nokia
20  * ================================================================================
21  */
22 package org.openecomp.sdc.be.components.impl;
23
24 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
25 import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.handleConsumptionInputMappedToCapabilityProperty;
26 import static org.openecomp.sdc.be.components.utils.ConsumptionUtils.isAssignedValueFromValidType;
27 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.getOperationOutputName;
28 import static org.openecomp.sdc.be.components.utils.InterfaceOperationUtils.isOperationInputMappedToOtherOperationOutput;
29 import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
30 import static org.openecomp.sdc.be.tosca.InterfacesOperationsConverter.SELF;
31 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.SERVICE_INPUT;
32 import static org.openecomp.sdc.be.types.ServiceConsumptionSource.STATIC;
33
34 import com.google.common.annotations.VisibleForTesting;
35 import com.google.common.base.Strings;
36 import com.google.gson.Gson;
37 import com.google.gson.GsonBuilder;
38 import fj.data.Either;
39 import java.nio.charset.StandardCharsets;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collection;
43 import java.util.Collections;
44 import java.util.Comparator;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Objects;
49 import java.util.Optional;
50 import java.util.Set;
51 import java.util.concurrent.Callable;
52 import java.util.function.Function;
53 import java.util.stream.Collectors;
54 import javax.servlet.ServletContext;
55 import javax.servlet.http.HttpServletRequest;
56 import lombok.Getter;
57 import org.apache.commons.collections.CollectionUtils;
58 import org.apache.commons.collections.MapUtils;
59 import org.apache.commons.collections4.ListUtils;
60 import org.apache.commons.lang3.StringUtils;
61 import org.apache.commons.lang3.tuple.ImmutablePair;
62 import org.openecomp.sdc.be.catalog.enums.ChangeTypeEnum;
63 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
64 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
65 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
66 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
67 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
68 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
69 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
70 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
71 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
72 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
73 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
74 import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator;
75 import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator;
76 import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator;
77 import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator;
78 import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator;
79 import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator;
80 import org.openecomp.sdc.be.components.validation.component.ComponentValidator;
81 import org.openecomp.sdc.be.components.validation.service.ServiceCategoryValidator;
82 import org.openecomp.sdc.be.components.validation.service.ServiceFunctionValidator;
83 import org.openecomp.sdc.be.components.validation.service.ServiceInstantiationTypeValidator;
84 import org.openecomp.sdc.be.components.validation.service.ServiceRoleValidator;
85 import org.openecomp.sdc.be.components.validation.service.ServiceTypeValidator;
86 import org.openecomp.sdc.be.components.validation.service.ServiceValidator;
87 import org.openecomp.sdc.be.config.BeEcompErrorManager;
88 import org.openecomp.sdc.be.config.ConfigurationManager;
89 import org.openecomp.sdc.be.dao.api.ActionStatus;
90 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
91 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
92 import org.openecomp.sdc.be.datamodel.ServiceRelations;
93 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
94 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
95 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
96 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
97 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
98 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
99 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
100 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
101 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
102 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
103 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
104 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
105 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
106 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
107 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
108 import org.openecomp.sdc.be.model.ArtifactDefinition;
109 import org.openecomp.sdc.be.model.CapabilityDefinition;
110 import org.openecomp.sdc.be.model.Component;
111 import org.openecomp.sdc.be.model.ComponentInstance;
112 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
113 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
114 import org.openecomp.sdc.be.model.ComponentParametersView;
115 import org.openecomp.sdc.be.model.DistributionStatusEnum;
116 import org.openecomp.sdc.be.model.GroupInstance;
117 import org.openecomp.sdc.be.model.GroupInstanceProperty;
118 import org.openecomp.sdc.be.model.InputDefinition;
119 import org.openecomp.sdc.be.model.InterfaceDefinition;
120 import org.openecomp.sdc.be.model.LifecycleStateEnum;
121 import org.openecomp.sdc.be.model.Operation;
122 import org.openecomp.sdc.be.model.PropertyDefinition;
123 import org.openecomp.sdc.be.model.Resource;
124 import org.openecomp.sdc.be.model.Service;
125 import org.openecomp.sdc.be.model.User;
126 import org.openecomp.sdc.be.model.category.CategoryDefinition;
127 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
128 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation;
129 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
130 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
131 import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation;
132 import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
133 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
134 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
135 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
136 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
137 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
138 import org.openecomp.sdc.be.plugins.ServiceCreationPlugin;
139 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
140 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
141 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
142 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
143 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
144 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
145 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
146 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
147 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
148 import org.openecomp.sdc.be.types.ServiceConsumptionData;
149 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
150 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
151 import org.openecomp.sdc.be.user.Role;
152 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
153 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
154 import org.openecomp.sdc.common.api.Constants;
155 import org.openecomp.sdc.common.datastructure.Wrapper;
156 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
157 import org.openecomp.sdc.common.log.wrappers.Logger;
158 import org.openecomp.sdc.common.util.GeneralUtility;
159 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
160 import org.openecomp.sdc.common.util.ValidationUtils;
161 import org.openecomp.sdc.exception.ResponseFormat;
162 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
163 import org.springframework.beans.factory.annotation.Autowired;
164 import org.springframework.http.HttpStatus;
165 import org.springframework.web.context.WebApplicationContext;
166
167 @org.springframework.stereotype.Component("serviceBusinessLogic")
168 public class ServiceBusinessLogic extends ComponentBusinessLogic {
169
170     static final String IS_VALID = "isValid";
171     private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
172     private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
173     private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
174     private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
175     private static final String INITIAL_VERSION = "0.1";
176     private static final String STATUS_SUCCESS_200 = "200";
177     private static final String STATUS_DEPLOYED = "DEPLOYED";
178     private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes";
179     private final IDistributionEngine distributionEngine;
180     private final ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
181     private final ServiceDistributionValidation serviceDistributionValidation;
182     private final ForwardingPathValidator forwardingPathValidator;
183     private final UiComponentDataConverter uiComponentDataConverter;
184     private ForwardingPathOperation forwardingPathOperation;
185     private AuditCassandraDao auditCassandraDao;
186     private ServiceTypeValidator serviceTypeValidator;
187     private List<ServiceCreationPlugin> serviceCreationPluginList;
188     private ServiceFunctionValidator serviceFunctionValidator;
189     @Autowired
190     private ServiceRoleValidator serviceRoleValidator;
191     @Autowired
192     private ServiceInstantiationTypeValidator serviceInstantiationTypeValidator;
193     @Autowired
194     private ServiceCategoryValidator serviceCategoryValidator;
195     @Autowired
196     private ServiceValidator serviceValidator;
197
198     @Autowired
199     public ServiceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
200                                 IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic, InterfaceOperation interfaceOperation,
201                                 InterfaceLifecycleOperation interfaceLifecycleTypeOperation, ArtifactsBusinessLogic artifactsBusinessLogic,
202                                 IDistributionEngine distributionEngine, ComponentInstanceBusinessLogic componentInstanceBusinessLogic,
203                                 ServiceDistributionValidation serviceDistributionValidation, ForwardingPathValidator forwardingPathValidator,
204                                 UiComponentDataConverter uiComponentDataConverter, ArtifactsOperations artifactToscaOperation,
205                                 ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator,
206                                 ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator,
207                                 ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator,
208                                 ComponentDescriptionValidator componentDescriptionValidator) {
209         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
210             interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
211             componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
212         this.distributionEngine = distributionEngine;
213         this.componentInstanceBusinessLogic = componentInstanceBusinessLogic;
214         this.serviceDistributionValidation = serviceDistributionValidation;
215         this.forwardingPathValidator = forwardingPathValidator;
216         this.uiComponentDataConverter = uiComponentDataConverter;
217     }
218
219     @Autowired
220     public void setServiceTypeValidator(ServiceTypeValidator serviceTypeValidator) {
221         this.serviceTypeValidator = serviceTypeValidator;
222     }
223
224     @Autowired
225     public void setServiceFunctionValidator(ServiceFunctionValidator serviceFunctionValidator) {
226         this.serviceFunctionValidator = serviceFunctionValidator;
227     }
228
229     public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
230         validateUserExists(userId);
231         Either<List<Map<String, Object>>, ActionStatus> result;
232         try {
233             // Certified Version
234             if (componentVersion.endsWith(".0")) {
235                 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
236                 if (eitherAuditingForCertified.isLeft()) {
237                     result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
238                 } else {
239                     result = Either.right(eitherAuditingForCertified.right().value());
240                 }
241             }
242             // Uncertified Version
243             else {
244                 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
245             }
246         } catch (Exception e) {
247             log.debug("get Audit Records failed with exception {}", e);
248             result = Either.right(ActionStatus.GENERAL_ERROR);
249         }
250         if (result.isRight()) {
251             return Either.right(componentsUtils.getResponseFormat(result.right().value()));
252         } else {
253             return Either.left(result.left().value());
254         }
255     }
256
257     public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId, String serviceInstanceId, String operationId,
258                                                                              List<ServiceConsumptionData> serviceConsumptionDataList, String userId) {
259         List<Operation> operationList = new ArrayList<>();
260         Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
261         if (serviceEither.isRight()) {
262             return Either.right(componentsUtils.getResponseFormat(serviceEither.right().value()));
263         }
264         Service service = serviceEither.left().value();
265         StorageOperationStatus storageOperationStatus = graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
266         if (storageOperationStatus != StorageOperationStatus.OK) {
267             return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
268         }
269         try {
270             for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
271                 Either<Operation, ResponseFormat> operationEither = addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId, userId,
272                     serviceConsumptionData);
273                 if (operationEither.isRight()) {
274                     return Either.right(operationEither.right().value());
275                 }
276                 operationList.add(operationEither.left().value());
277             }
278             janusGraphDao.commit();
279             return Either.left(operationList);
280         } catch (Exception e) {
281             janusGraphDao.rollback();
282             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
283         } finally {
284             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
285         }
286     }
287
288     public Either<Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId, String serviceInstanceId, String operationId,
289                                                                            String userId, ServiceConsumptionData serviceConsumptionData) {
290         validateUserExists(userId);
291         Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
292         if (serviceEither.isRight()) {
293             return Either.right(componentsUtils.getResponseFormat(serviceEither.right().value()));
294         }
295         Service parentService = serviceEither.left().value();
296         List<ComponentInstance> componentInstances = parentService.getComponentInstances();
297         if (CollectionUtils.isEmpty(componentInstances)) {
298             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
299         }
300         Optional<ComponentInstance> serviceInstanceCandidate = componentInstances.stream()
301             .filter(instance -> instance.getUniqueId().equals(serviceInstanceId)).findAny();
302         if (!serviceInstanceCandidate.isPresent()) {
303             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
304         }
305         Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces = parentService.getComponentInstancesInterfaces();
306         if (MapUtils.isEmpty(componentInstancesInterfaces)) {
307             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
308         }
309         List<InterfaceDefinition> interfaces = new ArrayList<>();
310         for (ComponentInstanceInterface componentInstanceInterface : componentInstancesInterfaces.get(serviceInstanceId)) {
311             interfaces.add(componentInstanceInterface);
312         }
313         ComponentInstance serviceInstance = serviceInstanceCandidate.get();
314         Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils.getInterfaceDefinitionFromOperationId(interfaces, operationId);
315         if (!interfaceCandidate.isPresent()) {
316             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
317         }
318         InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
319         Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
320         if (MapUtils.isEmpty(operations)) {
321             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
322         }
323         Operation operation = operations.get(operationId);
324         Either<Operation, ResponseFormat> operationEither = Either.left(operation);
325         ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
326         Optional<OperationInputDefinition> inputCandidate = getOperationInputByInputId(serviceConsumptionData, inputs);
327         if (!inputCandidate.isPresent()) {
328             return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
329         }
330         OperationInputDefinition operationInputDefinition = inputCandidate.get();
331         // add data to operation
332         if (Objects.nonNull(serviceConsumptionData.getValue())) {
333             operationEither = handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation, operationInputDefinition);
334         }
335         if (operationEither.isRight()) {
336             return Either.right(operationEither.right().value());
337         }
338         Operation updatedOperation = operationEither.left().value();
339         operations.remove(operationId);
340         operations.put(operationId, updatedOperation);
341         interfaceDefinition.setOperationsMap(operations);
342         parentService.getComponentInstances().remove(serviceInstance);
343         if (CollectionUtils.isEmpty(parentService.getComponentInstances())) {
344             parentService.setComponentInstances(new ArrayList<>());
345         }
346         Map<String, Object> instanceInterfaces =
347             MapUtils.isEmpty(serviceInstance.getInterfaces()) ? new HashMap<>() : serviceInstance.getInterfaces();
348         instanceInterfaces.remove(interfaceDefinition.getUniqueId());
349         instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
350         serviceInstance.setInterfaces(instanceInterfaces);
351         removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
352         componentInstancesInterfaces.get(serviceInstanceId)
353             .add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
354         parentService.getComponentInstances().add(serviceInstance);
355         StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
356         if (status != StorageOperationStatus.OK) {
357             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
358         }
359         return Either.left(operation);
360     }
361
362     private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove, List<ComponentInstanceInterface> instanceInterfaces) {
363         if (CollectionUtils.isEmpty(instanceInterfaces)) {
364             return;
365         }
366         Optional<ComponentInstanceInterface> interfaceToRemove = instanceInterfaces.stream()
367             .filter(instInterface -> instInterface.getUniqueId().equals(interfaceIdToRemove)).findAny();
368         if (interfaceToRemove.isPresent()) {
369             instanceInterfaces.remove(interfaceToRemove.get());
370         }
371     }
372
373     private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService, String serviceInstanceId,
374                                                                      ServiceConsumptionData serviceConsumptionData, Operation operation,
375                                                                      OperationInputDefinition operationInputDefinition) {
376         String source = serviceConsumptionData.getSource();
377         String consumptionValue = serviceConsumptionData.getValue();
378         String type = serviceConsumptionData.getType();
379         String operationIdentifier =
380             consumptionValue.contains(".") ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.')) : consumptionValue;
381         ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
382         if (STATIC.equals(sourceValue)) {
383             // Validate constraint on input value
384             Either<Boolean, ResponseFormat> constraintValidationResult = validateOperationInputConstraint(operationInputDefinition, consumptionValue,
385                 type, containerService.getModel());
386             if (constraintValidationResult.isRight()) {
387                 return Either.right(constraintValidationResult.right().value());
388             }
389             return handleConsumptionStaticValue(consumptionValue, type, operation, operationInputDefinition, containerService.getModel());
390         }
391         if (Objects.isNull(sourceValue)) {
392             List<PropertyDefinition> propertyDefinitions;
393             Map<String, List<CapabilityDefinition>> capabilities = null;
394             String componentName;
395             List<OperationOutputDefinition> outputs = null;
396             if (source.equals(containerService.getUniqueId())) {
397                 Either<Service, StorageOperationStatus> serviceToTakePropEither = toscaOperationFacade.getToscaElement(source);
398                 if (serviceToTakePropEither.isRight()) {
399                     return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
400                 }
401                 Service service = serviceToTakePropEither.left().value();
402                 operationInputDefinition.setSource(service.getUniqueId());
403                 sourceValue = SERVICE_INPUT;
404                 propertyDefinitions = service.getProperties();
405                 componentName = service.getName();
406                 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier, service.getInterfaces())
407                     .getListToscaDataDefinition();
408             } else {
409                 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
410                 if (!getComponentInstance.isPresent()) {
411                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
412                 }
413                 ComponentInstance componentInstance = getComponentInstance.get();
414                 operationInputDefinition.setSource(componentInstance.getUniqueId());
415                 propertyDefinitions = componentInstance.getProperties();
416                 capabilities = componentInstance.getCapabilities();
417                 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
418                 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
419                     Map<String, InterfaceDataDefinition> componentInstanceInterfaces = componentInstance.getInterfaces().entrySet().stream()
420                         .collect(Collectors.toMap((Map.Entry::getKey), (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
421                     outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier, componentInstanceInterfaces)
422                         .getListToscaDataDefinition();
423                 }
424             }
425             if (sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
426                 //The operation input in service consumption has been mapped to an input in the parent service
427                 return handleConsumptionInputValue(consumptionValue, containerService, operation, operationInputDefinition);
428             }
429             return handleConsumptionPropertyValue(operation, operationInputDefinition, serviceConsumptionData, propertyDefinitions, capabilities,
430                 outputs, componentName);
431         }
432         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
433         operationInputDefinition.setSource(source);
434         return Either.left(operation);
435     }
436
437     private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
438                                                                           ListDataDefinition<OperationInputDefinition> inputs) {
439         if (CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
440             return Optional.empty();
441         }
442         return inputs.getListToscaDataDefinition().stream()
443             .filter(operationInput -> operationInput.getInputId().equals(serviceConsumptionData.getInputId())).findAny();
444     }
445
446     private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(Operation operation, OperationInputDefinition operationInputDefinition,
447                                                                              ServiceConsumptionData serviceConsumptionData,
448                                                                              List<PropertyDefinition> properties,
449                                                                              Map<String, List<CapabilityDefinition>> capabilities,
450                                                                              List<OperationOutputDefinition> outputs, String componentName) {
451         if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
452             return Either.left(operation);
453         }
454         String consumptionValue = serviceConsumptionData.getValue();
455         if (CollectionUtils.isNotEmpty(outputs) && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
456             return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs, consumptionValue, componentName);
457         }
458         if (CollectionUtils.isNotEmpty(properties) && PropertiesUtils.isNodeProperty(consumptionValue, properties)) {
459             return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData, properties, componentName);
460         }
461         if (MapUtils.isNotEmpty(capabilities)) {
462             return handleConsumptionInputMappedToCapabilityProperty(operation, operationInputDefinition, serviceConsumptionData, capabilities,
463                 componentName);
464         }
465         return Either.left(operation);
466     }
467
468     private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
469                                                                                      OperationInputDefinition operationInputDefinition,
470                                                                                      ServiceConsumptionData serviceConsumptionData,
471                                                                                      List<PropertyDefinition> properties, String componentName) {
472         Optional<PropertyDefinition> servicePropertyCandidate = properties.stream()
473             .filter(property -> property.getName().equals(serviceConsumptionData.getValue())).findAny();
474         if (servicePropertyCandidate.isPresent()) {
475             boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(), servicePropertyCandidate.get());
476             if (!isInputTypeSimilarToOperation) {
477                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
478             }
479             addPropertyToInputValue(componentName, operation, operationInputDefinition, servicePropertyCandidate.get());
480         }
481         return Either.left(operation);
482     }
483
484     private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
485                                                                                             OperationInputDefinition operationInputDefinition,
486                                                                                             List<OperationOutputDefinition> outputs,
487                                                                                             String consumptionValue, String componentName) {
488         String outputName = getOperationOutputName(consumptionValue);
489         Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream().filter(output -> output.getName().equals(outputName))
490             .findAny();
491         if (servicePropertyOutputCandidate.isPresent()) {
492             boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(),
493                 servicePropertyOutputCandidate.get());
494             if (!isInputTypeSimilarToOperation) {
495                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
496             }
497             addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
498         }
499         return Either.left(operation);
500     }
501
502     private void addPropertyToInputValue(String componentName, Operation operation, OperationInputDefinition operationInputDefinition,
503                                          PropertyDefinition serviceProperty) {
504         Map<String, List<String>> getProperty = new HashMap<>();
505         List<String> getPropertyValues = new ArrayList<>();
506         getPropertyValues.add(componentName);
507         getPropertyValues.add(serviceProperty.getName());
508         getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
509         operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
510         operation.getInputs().delete(operationInputDefinition);
511         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY, getPropertyValues);
512         operationInputDefinition.setValue((new Gson()).toJson(getProperty));
513         operation.getInputs().add(operationInputDefinition);
514     }
515
516     private void addOutputToInputValue(String componentName, String consumptionValue, Operation operation,
517                                        OperationInputDefinition operationInputDefinition) {
518         Map<String, List<String>> getOperationOutput = InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
519         operation.getInputs().delete(operationInputDefinition);
520         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT, getOperationOutput);
521         operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
522         operation.getInputs().add(operationInputDefinition);
523     }
524
525     public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type, Operation operation,
526                                                                           OperationInputDefinition operationInputDefinition, String model) {
527         boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(type, value);
528         if (!isInputTypeSimilarToOperation) {
529             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, type));
530         }
531         //Validate Constraint and Value
532         Either<Boolean, ResponseFormat> constraintValidationResponse = validateOperationInputConstraint(operationInputDefinition, value, type, model);
533         if (constraintValidationResponse.isRight()) {
534             return Either.right(constraintValidationResponse.right().value());
535         }
536         addStaticValueToInputOperation(value, operation, operationInputDefinition);
537         return Either.left(operation);
538     }
539
540     private Either<Boolean, ResponseFormat> validateOperationInputConstraint(OperationInputDefinition operationInputDefinition, String value,
541                                                                              String type, String model) {
542         ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
543         propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
544         InputDefinition inputDefinition = new InputDefinition();
545         inputDefinition.setDefaultValue(value);
546         inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
547         inputDefinition.setType(type);
548         if (Objects.nonNull(operationInputDefinition.getParentPropertyType())) {
549             inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
550         }
551         return PropertyValueConstraintValidationUtil.getInstance().validatePropertyConstraints(Collections.singletonList(inputDefinition),
552             applicationDataTypeCache, model);
553     }
554
555     private void addStaticValueToInputOperation(String value, Operation operation, OperationInputDefinition operationInputDefinition) {
556         operation.getInputs().delete(operationInputDefinition);
557         operationInputDefinition.setSource(STATIC.getSource());
558         operationInputDefinition.setSourceProperty(null);
559         operationInputDefinition.setValue(value);
560         operation.getInputs().add(operationInputDefinition);
561     }
562
563     private Either<Operation, ResponseFormat> handleConsumptionInputValue(String inputId, Service service, Operation operation,
564                                                                           OperationInputDefinition operationInputDefinition) {
565         List<InputDefinition> serviceInputs = service.getInputs();
566         Optional<InputDefinition> inputForValue = serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
567         if (inputForValue.isPresent()) {
568             boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
569             if (!isInputTypeSimilarToOperation) {
570                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
571             }
572             addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
573         }
574         return Either.left(operation);
575     }
576
577     private void addGetInputValueToOperationInput(Operation operation, OperationInputDefinition operationInputDefinition,
578                                                   InputDefinition inputForValue) {
579         operation.getInputs().delete(operationInputDefinition);
580         Map<String, String> getInputMap = new HashMap<>();
581         getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
582         operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
583         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
584         operationInputDefinition.setValue(new Gson().toJson(getInputMap));
585         operation.getInputs().add(operationInputDefinition);
586     }
587
588     private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
589         // First Query
590         Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao
591             .getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
592         if (eitherprevVerAudit.isRight()) {
593             return Either.right(eitherprevVerAudit.right().value());
594         }
595         // Second Query
596         Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao
597             .getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
598         if (eitherCurrVerAudit.isRight()) {
599             return Either.right(eitherCurrVerAudit.right().value());
600         }
601         Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
602         if (eitherArchiveRestoreList.isRight()) {
603             return Either.right(eitherArchiveRestoreList.right().value());
604         }
605         List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
606         List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
607         List<Map<String, Object>> duplicateElements = new ArrayList<>();
608         duplicateElements.addAll(prevVerAuditList);
609         duplicateElements.retainAll(currVerAuditList);
610         List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
611         joinedNonDuplicatedList.addAll(prevVerAuditList);
612         joinedNonDuplicatedList.removeAll(duplicateElements);
613         joinedNonDuplicatedList.addAll(currVerAuditList);
614         joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
615         return Either.left(joinedNonDuplicatedList);
616     }
617
618     private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
619         // Archive Query
620         Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
621         if (eitherArchiveAudit.isRight()) {
622             return Either.right(eitherArchiveAudit.right().value());
623         }
624         // Restore Query
625         Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
626         if (eitherRestoreAudit.isRight()) {
627             return Either.right(eitherRestoreAudit.right().value());
628         }
629         List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
630         archiveAudit.addAll(eitherArchiveAudit.left().value());
631         archiveAudit.addAll(eitherRestoreAudit.left().value());
632         return Either.left(archiveAudit);
633     }
634
635     @VisibleForTesting
636     public void setServiceValidator(ServiceValidator serviceValidator) {
637         this.serviceValidator = serviceValidator;
638     }
639
640     @VisibleForTesting
641     public void setServiceCategoryValidator(ServiceCategoryValidator serviceCategoryValidator) {
642         this.serviceCategoryValidator = serviceCategoryValidator;
643     }
644
645     private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
646         List<Map<String, Object>> prevVerAudit = new ArrayList<>();
647         for (AuditingGenericEvent auditEvent : prevVerAuditList) {
648             auditEvent.fillFields();
649             prevVerAudit.add(auditEvent.getFields());
650         }
651         return prevVerAudit;
652     }
653
654     /**
655      * createService
656      *
657      * @param service - Service
658      * @param user    - modifier data (userId)
659      * @return Either<Service, responseFormat>
660      */
661     public Either<Service, ResponseFormat> createService(Service service, User user) {
662         // get user details
663         user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
664         log.debug("User returned from validation: " + user.toString());
665         // validate user role
666         validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
667         service.setCreatorUserId(user.getUserId());
668         // warn on overridden fields
669         checkFieldsForOverideAttampt(service);
670         // enrich object
671         log.debug("enrich service with version and state");
672         service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
673         service.setVersion(INITIAL_VERSION);
674         service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
675         service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
676         service.setComponentType(ComponentTypeEnum.SERVICE);
677         Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
678         if (createServiceResponse.isRight()) {
679             return createServiceResponse;
680         }
681         return createServiceByDao(service, user).left().bind(c -> updateCatalog(c, ChangeTypeEnum.LIFECYCLE).left().map(r -> (Service) r));
682     }
683
684     private void checkFieldsForOverideAttampt(Service service) {
685         checkComponentFieldsForOverrideAttempt(service);
686         if (service.getDistributionStatus() != null) {
687             log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
688         }
689     }
690
691     private Either<Service, ResponseFormat> createServiceByDao(final Service service, final User user) {
692         log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
693         Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
694         if (lockResult.isRight()) {
695             ResponseFormat responseFormat = lockResult.right().value();
696             componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
697             return Either.right(responseFormat);
698         }
699         log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
700         try {
701             createMandatoryArtifactsData(service, user);
702             createServiceApiArtifactsData(service, user);
703             setToscaArtifactsPlaceHolders(service, user);
704             if (service.isSubstituteCandidate()) {
705                 final Resource genericType = fetchAndSetDerivedFromGenericType(service);
706                 generatePropertiesFromGenericType(service, genericType);
707                 generateAndAddInputsFromGenericTypeProperties(service, genericType);
708             }
709             beforeCreate(service);
710             Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
711             if (dataModelResponse.isLeft()) {
712                 log.debug("Service '{}' created successfully", service.getName());
713                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
714                 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
715                 ASDCKpiApi.countCreatedServicesKPI();
716                 return Either.left(dataModelResponse.left().value());
717             }
718             ResponseFormat responseFormat = componentsUtils
719                 .getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service,
720                     ComponentTypeEnum.SERVICE);
721             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
722             componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
723             return Either.right(responseFormat);
724         } finally {
725             graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
726         }
727     }
728
729     private void beforeCreate(final Service service) {
730         if (CollectionUtils.isEmpty(serviceCreationPluginList)) {
731             return;
732         }
733         serviceCreationPluginList.stream().sorted(Comparator.comparingInt(ServiceCreationPlugin::getOrder)).forEach(serviceCreationPlugin -> {
734             try {
735                 serviceCreationPlugin.beforeCreate(service);
736             } catch (final Exception e) {
737                 log.error("An error has occurred while running the serviceCreationPlugin '{}'", serviceCreationPlugin.getClass(), e);
738             }
739         });
740     }
741
742     @SuppressWarnings("unchecked")
743     private void createServiceApiArtifactsData(Service service, User user) {
744         // create mandatory artifacts
745
746         // TODO it must be removed after that artifact uniqueId creation will be
747
748         // moved to ArtifactOperation
749         String serviceUniqueId = service.getUniqueId();
750         Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
751         if (artifactMap == null) {
752             artifactMap = new HashMap<>();
753         }
754         Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
755         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
756         List<CategoryDefinition> categories = service.getCategories();
757         boolean isCreateArtifact = true;
758         if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
759             for (String exlude : exludeServiceCategory) {
760                 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
761                     isCreateArtifact = false;
762                     break;
763                 }
764             }
765         }
766         if (serviceApiArtifacts != null && isCreateArtifact) {
767             Set<String> keys = serviceApiArtifacts.keySet();
768             for (String serviceApiArtifactName : keys) {
769                 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
770                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user,
771                     true);
772                 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
773                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
774             }
775             service.setServiceApiArtifacts(artifactMap);
776         }
777     }
778
779     @VisibleForTesting
780     protected Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
781         try {
782             serviceValidator.validate(user, service, actionEnum);
783         } catch (ComponentException exp) {
784             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exp);
785             componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
786             throw exp;
787         }
788         service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
789         service.setContactId(service.getContactId().toLowerCase());
790         // Generate invariant UUID - must be here and not in operation since it
791
792         // should stay constant during clone
793         String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
794         service.setInvariantUUID(invariantUUID);
795         return Either.left(service);
796     }
797
798     public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
799         validateUserExists(userId);
800         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
801             .validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
802         // DE242223
803         janusGraphDao.commit();
804         if (dataModelResponse.isLeft()) {
805             Map<String, Boolean> result = new HashMap<>();
806             result.put(IS_VALID, dataModelResponse.left().value());
807             log.debug("validation was successfully performed.");
808             return Either.left(result);
809         }
810         ResponseFormat responseFormat = componentsUtils
811             .getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
812         return Either.right(responseFormat);
813     }
814
815     public void setElementDao(IElementOperation elementDao) {
816         this.elementDao = elementDao;
817     }
818
819     @Autowired
820     public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
821         this.auditCassandraDao = auditingDao;
822     }
823
824     public ArtifactsBusinessLogic getArtifactBl() {
825         return artifactsBusinessLogic;
826     }
827
828     public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
829         this.artifactsBusinessLogic = artifactBl;
830     }
831
832     public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
833         user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
834         // validate user role
835         validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
836         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
837         if (storageStatus.isRight()) {
838             return Either.right(componentsUtils
839                 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
840         }
841         Service currentService = storageStatus.left().value();
842         if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
843             log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
844             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
845         }
846         Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
847         if (validationRsponse.isRight()) {
848             log.info("service update metadata: validations field.");
849             return validationRsponse;
850         }
851         Service serviceToUpdate = validationRsponse.left().value();
852         // lock resource
853         lockComponent(serviceId, currentService, "Update Service Metadata");
854         try {
855             return toscaOperationFacade.updateToscaElement(serviceToUpdate).right().map(rf -> {
856                 janusGraphDao.rollback();
857                 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
858                 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
859                 return (componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
860             }).left().bind(c -> updateCatalogAndCommit(c));
861         } finally {
862             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
863         }
864     }
865
866     private Either<Service, ResponseFormat> updateCatalogAndCommit(Service service) {
867         Either<Service, ResponseFormat> res = updateCatalog(service, ChangeTypeEnum.LIFECYCLE).left().map(s -> (Service) s);
868         janusGraphDao.commit();
869         return res;
870     }
871
872     public Set<String> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
873         Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
874         user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
875         // validate user role
876         validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
877         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
878         if (storageStatus.isRight()) {
879             throw new ByActionStatusComponentException(
880                 componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
881         }
882         Service service = storageStatus.left().value();
883         Either<Set<String>, StorageOperationStatus> result = null;
884         if (lock) {
885             try {
886                 lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
887             } catch (ComponentException e) {
888                 janusGraphDao.rollback();
889                 throw new ByActionStatusComponentException(
890                     componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
891             }
892         }
893         try {
894             result = forwardingPathOperation.deleteForwardingPath(service, pathIdsToDelete);
895             if (result.isRight()) {
896                 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
897                 janusGraphDao.rollback();
898                 throw new ByActionStatusComponentException(
899                     componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE));
900             }
901             janusGraphDao.commit();
902             log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
903         } catch (ComponentException e) {
904             log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
905             janusGraphDao.rollback();
906             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
907         } finally {
908             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
909         }
910         return result.left().value();
911     }
912
913     private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
914         Service serviceToDelete = new Service();
915         serviceToDelete.setUniqueId(serviceId);
916         serviceToDelete.setForwardingPaths(new HashMap<>());
917         pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
918         return serviceToDelete;
919     }
920
921     public Service updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
922         return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true, "updateForwardingPath", lock);
923     }
924
925     public Service createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
926         return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
927     }
928
929     private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path) {
930         ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
931         dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
932         dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
933         dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
934         dataDefinition.setUniqueId(path.getUniqueId());
935         dataDefinition.setPathElements(path.getPathElements());
936         dataDefinition.setDescription(path.getDescription());
937         dataDefinition.setToscaResourceName(path.getToscaResourceName());
938         return dataDefinition;
939     }
940
941     private Service createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext,
942                                                  boolean lock) {
943         validateUserAndRole(serviceUpdate, user, errorContext);
944         Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
945         Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths = forwardingPaths.entrySet().stream()
946             .collect(Collectors.toMap(Map.Entry::getKey, entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
947         forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(), serviceId, isUpdate);
948         Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
949         if (serviceStorageOperationStatusEither.isRight()) {
950             StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
951             log.debug("Failed to fetch service information by service id, error {}", errorStatus);
952             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
953         }
954         Service storedService = serviceStorageOperationStatusEither.left().value();
955         Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
956         Component component = getForwardingPathOriginComponent();
957         final String toscaResourceName;
958         if (component.getComponentType() == ComponentTypeEnum.RESOURCE) {
959             toscaResourceName = ((Resource) component).getToscaResourceName();
960         } else {
961             toscaResourceName = "";
962         }
963         if (lock) {
964             lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
965             log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
966         }
967         Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
968         try {
969             trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
970             populateForwardingPaths(serviceId, isUpdate, trimmedForwardingPaths, resultMap);
971             janusGraphDao.commit();
972         } finally {
973             if (lock) {
974                 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
975             }
976         }
977         return createServiceWithForwardingPathForResponse(serviceId, resultMap);
978     }
979
980     private Component getForwardingPathOriginComponent() {
981         Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade
982             .getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME, null);
983         if (forwardingPathOrigin.isRight()) {
984             StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
985             log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
986             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
987         }
988         return forwardingPathOrigin.left().value();
989     }
990
991     private void populateForwardingPaths(String serviceId, boolean isUpdate, Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths,
992                                          Map<String, ForwardingPathDataDefinition> resultMap) {
993         Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
994         try {
995             for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
996                 if (isUpdate) {
997                     result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
998                 } else {
999                     result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1000                 }
1001                 if (result.isRight()) {
1002                     janusGraphDao.rollback();
1003                     throw new ByResponseFormatComponentException(componentsUtils
1004                         .getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE), ""));
1005                 } else {
1006                     ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1007                     resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1008                 }
1009             }
1010         } catch (ComponentException e) {
1011             janusGraphDao.rollback();
1012             log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(), e);
1013             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1014         }
1015     }
1016
1017     private Service createServiceWithForwardingPathForResponse(String serviceId,
1018                                                                Map<String, ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1019         Service service = new Service();
1020         service.setUniqueId(serviceId);
1021         service.setForwardingPaths(forwardingPathDataDefinitionMap);
1022         return service;
1023     }
1024
1025     private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1026         user = validateUser(user, errorContext, serviceUpdate, null, false);
1027         validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1028     }
1029
1030     @VisibleForTesting
1031     Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1032         try {
1033             boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1034             Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified,
1035                 UPDATE_SERVICE_METADATA);
1036             if (response.isRight()) {
1037                 ResponseFormat errorResponse = response.right().value();
1038                 return Either.right(errorResponse);
1039             }
1040             verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1041             verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1042             verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1043             verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1044             response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1045             if (response.isRight()) {
1046                 return Either.right(response.right().value());
1047             }
1048             verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1049             if (serviceUpdate.getProjectCode() != null) {
1050                 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1051                 if (response.isRight()) {
1052                     return Either.right(response.right().value());
1053                 }
1054             }
1055             response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1056             if (response.isRight()) {
1057                 return Either.right(response.right().value());
1058             }
1059             verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1060             verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1061             response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1062             if (response.isRight()) {
1063                 return Either.right(response.right().value());
1064             }
1065             response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1066             if (response.isRight()) {
1067                 return Either.right(response.right().value());
1068             }
1069             response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1070             if (response.isRight()) {
1071                 return Either.right(response.right().value());
1072             }
1073             verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1074             verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1075             verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1076             verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1077             validateAndUpdateServiceType(currentService, serviceUpdate);
1078             validateAndUpdateServiceFunction(currentService, serviceUpdate);
1079             response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1080             if (response.isRight()) {
1081                 return Either.right(response.right().value());
1082             }
1083             response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1084             if (response.isRight()) {
1085                 return Either.right(response.right().value());
1086             }
1087             verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1088             validateAndUpdateEcompNaming(currentService, serviceUpdate);
1089             currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1090             currentService.setCategorySpecificMetadata(serviceUpdate.getCategorySpecificMetadata());
1091             return Either.left(currentService);
1092         } catch (ComponentException exception) {
1093             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1094             componentsUtils
1095                 .auditComponentAdmin(responseFormat, user, serviceUpdate, AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1096             return Either.right(responseFormat);
1097         }
1098     }
1099
1100     private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1101         if (updatedValue != null && !updatedValue.equals(originalValue)) {
1102             log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1103         }
1104     }
1105
1106     private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1107         Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1108         Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1109         if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1110             currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1111         }
1112         String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1113         if (currentService.isEcompGeneratedNaming() != null && currentService.isEcompGeneratedNaming()) {
1114             currentService.setNamingPolicy(namingPolicyUpdate);
1115         } else {
1116             if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1117                 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1118             }
1119             currentService.setNamingPolicy("");
1120         }
1121     }
1122
1123     private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate,
1124                                                                        AuditingActionEnum audatingAction) {
1125         String contactIdUpdated = serviceUpdate.getContactId();
1126         String contactIdCurrent = currentService.getContactId();
1127         if (!contactIdCurrent.equals(contactIdUpdated)) {
1128             componentContactIdValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1129             currentService.setContactId(contactIdUpdated.toLowerCase());
1130         }
1131         return Either.left(true);
1132     }
1133
1134     private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate,
1135                                                                   AuditingActionEnum audatingAction) {
1136         List<String> tagsUpdated = serviceUpdate.getTags();
1137         List<String> tagsCurrent = currentService.getTags();
1138         if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1139             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1140             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1141             return Either.right(responseFormat);
1142         }
1143         if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1144             componentTagsValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1145             currentService.setTags(tagsUpdated);
1146         }
1147         return Either.left(true);
1148     }
1149
1150     private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate,
1151                                                                          AuditingActionEnum audatingAction) {
1152         String descriptionUpdated = serviceUpdate.getDescription();
1153         String descriptionCurrent = currentService.getDescription();
1154         if (!descriptionCurrent.equals(descriptionUpdated)) {
1155             componentDescriptionValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1156             currentService.setDescription(serviceUpdate.getDescription());
1157         }
1158         return Either.left(true);
1159     }
1160
1161     private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate,
1162                                                                          AuditingActionEnum audatingAction) {
1163         String projectCodeUpdated = serviceUpdate.getProjectCode();
1164         String projectCodeCurrent = currentService.getProjectCode();
1165         if (StringUtils.isEmpty(projectCodeCurrent) || !projectCodeCurrent.equals(projectCodeUpdated)) {
1166             try {
1167                 componentProjectCodeValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1168             } catch (ComponentException exp) {
1169                 ResponseFormat errorRespons = exp.getResponseFormat();
1170                 return Either.right(errorRespons);
1171             }
1172             currentService.setProjectCode(projectCodeUpdated);
1173         }
1174         return Either.left(true);
1175     }
1176
1177     private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified,
1178                                                                   AuditingActionEnum audatingAction) {
1179         String iconUpdated = serviceUpdate.getIcon();
1180         String iconCurrent = currentService.getIcon();
1181         if (!iconCurrent.equals(iconUpdated)) {
1182             if (!hasBeenCertified) {
1183                 componentIconValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1184                 currentService.setIcon(iconUpdated);
1185             } else {
1186                 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1187                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1188                 return Either.right(errorResponse);
1189             }
1190         }
1191         return Either.left(true);
1192     }
1193
1194     private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate,
1195                                                                          boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1196         String serviceNameUpdated = serviceUpdate.getName();
1197         String serviceNameCurrent = currentService.getName();
1198         if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1199             if (!hasBeenCertified) {
1200                 componentNameValidator.validateAndCorrectField(user, serviceUpdate, auditingAction);
1201                 try {
1202                     componentNameValidator.validateComponentNameUnique(user, serviceUpdate, auditingAction);
1203                 } catch (ComponentException exp) {
1204                     return Either.right(exp.getResponseFormat());
1205                 }
1206                 currentService.setName(serviceNameUpdated);
1207                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1208                     .setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1209                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1210                     .setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1211             } else {
1212                 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1213                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1214                 return Either.right(errorResponse);
1215             }
1216         }
1217         return Either.left(true);
1218     }
1219
1220     private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1221         String updatedServiceType = updatedService.getServiceType();
1222         String currentServiceType = currentService.getServiceType();
1223         if (!currentServiceType.equals(updatedServiceType)) {
1224             serviceTypeValidator.validateAndCorrectField(null, updatedService, null);
1225             currentService.setServiceType(updatedServiceType);
1226         }
1227     }
1228
1229     private void validateAndUpdateServiceFunction(Service currentService, Service updatedService) {
1230         String updatedServiceFunction = updatedService.getServiceFunction();
1231         String currentServiceFunction = currentService.getServiceFunction();
1232         if (!currentServiceFunction.equals(updatedServiceFunction)) {
1233             serviceFunctionValidator.validateAndCorrectField(null, updatedService, null);
1234             currentService.setServiceFunction(updatedService.getServiceFunction());
1235         }
1236     }
1237
1238     private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService,
1239                                                                          AuditingActionEnum auditingAction) {
1240         String updatedServiceRole = updatedService.getServiceRole();
1241         String currentServiceRole = currentService.getServiceRole();
1242         if (!currentServiceRole.equals(updatedServiceRole)) {
1243             try {
1244                 serviceRoleValidator.validateAndCorrectField(user, updatedService, auditingAction);
1245             } catch (ComponentException exp) {
1246                 ResponseFormat errorResponse = exp.getResponseFormat();
1247                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1248                 return Either.right(errorResponse);
1249             }
1250             currentService.setServiceRole(updatedServiceRole);
1251         }
1252         return Either.left(true);
1253     }
1254
1255     private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService,
1256                                                                                     AuditingActionEnum auditingAction) {
1257         String updatedInstaType = updatedService.getInstantiationType();
1258         String currentInstaType = currentService.getInstantiationType();
1259         if (!currentInstaType.equals(updatedInstaType)) {
1260             try {
1261                 serviceInstantiationTypeValidator.validateAndCorrectField(user, updatedService, auditingAction);
1262             } catch (ComponentException exp) {
1263                 ResponseFormat errorResponse = exp.getResponseFormat();
1264                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1265                 return Either.right(errorResponse);
1266             }
1267             currentService.setInstantiationType(updatedInstaType);
1268         }
1269         return Either.left(true);
1270     }
1271
1272     private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate,
1273                                                                       boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1274         try {
1275             List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1276             List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1277             serviceCategoryValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1278             if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1279                 if (!hasBeenCertified) {
1280                     currentService.setCategories(categoryUpdated);
1281                 } else {
1282                     log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1283                     ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1284                     return Either.right(errorResponse);
1285                 }
1286             }
1287         } catch (ComponentException exp) {
1288             return Either.right(exp.getResponseFormat());
1289         }
1290         return Either.left(true);
1291     }
1292
1293     public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1294         Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1295         if (serviceResponseFormatEither.isRight()) {
1296             return Either.right(serviceResponseFormatEither.right().value());
1297         }
1298         final ServiceRelations serviceRelations = new ForwardingPathUtils()
1299             .convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1300         return Either.left(serviceRelations);
1301     }
1302
1303     public ResponseFormat deleteService(String serviceId, User user) {
1304         ResponseFormat responseFormat;
1305         validateUserExists(user);
1306         Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1307         if (serviceStatus.isRight()) {
1308             log.debug("failed to get service {}", serviceId);
1309             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1310         }
1311         Service service = serviceStatus.left().value();
1312         StorageOperationStatus result = StorageOperationStatus.OK;
1313         try {
1314             lockComponent(service, "Mark service to delete");
1315             result = markComponentToDelete(service);
1316             if (result == StorageOperationStatus.OK) {
1317                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1318             } else {
1319                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1320                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1321             }
1322             return responseFormat;
1323         } catch (ComponentException e) {
1324             return e.getResponseFormat();
1325         } finally {
1326             if (result == null || result != StorageOperationStatus.OK) {
1327                 log.warn("operation failed. do rollback");
1328                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1329                 janusGraphDao.rollback();
1330             } else {
1331                 log.debug("operation success. do commit");
1332                 janusGraphDao.commit();
1333             }
1334             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1335         }
1336     }
1337
1338     public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1339         ResponseFormat responseFormat;
1340         String ecompErrorContext = "delete service";
1341         validateUserNotEmpty(user, ecompErrorContext);
1342         user = validateUserExists(user);
1343         Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1344         if (getResult.isRight()) {
1345             return getResult.right().value();
1346         }
1347         Service service = getResult.left().value();
1348         StorageOperationStatus result = StorageOperationStatus.OK;
1349         try {
1350             lockComponent(service, "Mark service to delete");
1351             result = markComponentToDelete(service);
1352             if (result == StorageOperationStatus.OK) {
1353                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1354             } else {
1355                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1356                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1357             }
1358             return responseFormat;
1359         } catch (ComponentException e) {
1360             result = StorageOperationStatus.GENERAL_ERROR;
1361             return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1362         } finally {
1363             if (result == null || result != StorageOperationStatus.OK) {
1364                 log.warn("operation failed. do rollback");
1365                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1366                 janusGraphDao.rollback();
1367             } else {
1368                 log.debug("operation success. do commit");
1369                 janusGraphDao.commit();
1370             }
1371             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1372         }
1373     }
1374
1375     public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1376         String ecompErrorContext = "Get service";
1377         validateUserNotEmpty(user, ecompErrorContext);
1378         validateUserExists(user);
1379         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1380         if (storageStatus.isRight()) {
1381             log.debug("failed to get service by id {}", serviceId);
1382             return Either.right(componentsUtils
1383                 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1384         }
1385         if (!(storageStatus.left().value() instanceof Service)) {
1386             return Either
1387                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1388         }
1389         Service service = storageStatus.left().value();
1390         return Either.left(service);
1391     }
1392
1393     public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1394         validateUserExists(userId);
1395         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade
1396             .getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1397         if (storageStatus.isRight()) {
1398             log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1399             return Either.right(componentsUtils
1400                 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE),
1401                     serviceName));
1402         }
1403         Service service = storageStatus.left().value();
1404         return Either.left(service);
1405     }
1406
1407     @SuppressWarnings("unchecked")
1408     private void createMandatoryArtifactsData(Service service, User user) {
1409         // create mandatory artifacts
1410
1411         // TODO it must be removed after that artifact uniqueId creation will be
1412
1413         // moved to ArtifactOperation
1414         String serviceUniqueId = service.getUniqueId();
1415         Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1416         if (artifactMap == null) {
1417             artifactMap = new HashMap<>();
1418         }
1419         Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1420             .getInformationalServiceArtifacts();
1421         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1422         String category = service.getCategories().get(0).getName();
1423         boolean isCreateArtifact = true;
1424         if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1425             for (String exlude : exludeServiceCategory) {
1426                 if (exlude.equalsIgnoreCase(category)) {
1427                     isCreateArtifact = false;
1428                     break;
1429                 }
1430             }
1431         }
1432         if (informationalServiceArtifacts != null && isCreateArtifact) {
1433             Set<String> keys = informationalServiceArtifacts.keySet();
1434             for (String informationalServiceArtifactName : keys) {
1435                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1436                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap,
1437                     user, false);
1438                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1439             }
1440             service.setArtifacts(artifactMap);
1441         }
1442     }
1443
1444     private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
1445                                                         Boolean isServiceApi) {
1446         ArtifactDefinition artifactInfo = artifactsBusinessLogic
1447             .createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1448         if (isServiceApi) {
1449             artifactInfo.setMandatory(false);
1450             artifactInfo.setServiceApi(true);
1451         }
1452         return artifactInfo;
1453     }
1454
1455     private String getEnvNameFromConfiguration() {
1456         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1457         log.trace("Update environment name to be {}", configuredEnvName);
1458         return configuredEnvName;
1459     }
1460
1461     public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier,
1462                                                                              ServiceDistributionReqInfo data) {
1463         Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation
1464             .validateActivateServiceRequest(serviceId, envId, modifier, data);
1465         if (activationRequestInformationEither.isRight()) {
1466             return Either.right(activationRequestInformationEither.right().value());
1467         }
1468         ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1469         String did = ThreadLocalsHolder.getUuid();
1470         Service service = activationRequestInformation.getServiceToActivate();
1471         return buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1472     }
1473
1474     private Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext,
1475                                                                            User modifier) {
1476         String envName = getEnvNameFromConfiguration();
1477         INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1478         ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1479         if (notifyServiceResponse == ActionStatus.OK) {
1480             return Either.left(did);
1481         } else {
1482             BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1483             log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1484             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1485             return Either.right(error);
1486         }
1487     }
1488
1489     public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1490         User user = validateUserExists(modifier.getUserId());
1491         validateUserRole(user, Collections.singletonList(Role.DESIGNER));
1492         Either<Service, ResponseFormat> result;
1493         ResponseFormat response;
1494         Service updatedService;
1495         String did = ThreadLocalsHolder.getUuid();
1496         // DE194021
1497         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1498         if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1499             log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1500             envName = configuredEnvName;
1501         }
1502         // DE194021
1503         ServletContext servletContext = request.getSession().getServletContext();
1504         boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1505         if (!isDistributionEngineUp) {
1506             BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1507             log.debug("Distribution Engine is DOWN");
1508             response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1509             return Either.right(response);
1510         }
1511         Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1512         if (serviceRes.isRight()) {
1513             log.debug("failed retrieving service");
1514             response = componentsUtils
1515                 .getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1516             componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1517                 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), did);
1518             return Either.right(response);
1519         }
1520         Service service = serviceRes.left().value();
1521         if (service.isArchived()) {
1522             log.info("Component is archived. Component id: {}", serviceId);
1523             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName()));
1524         }
1525         if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1526             log.info("service {} is  not available for distribution. Should be in certified state", service.getUniqueId());
1527             ResponseFormat responseFormat = componentsUtils
1528                 .getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1529             return Either.right(responseFormat);
1530         }
1531         String dcurrStatus = service.getDistributionStatus().name();
1532         String updatedStatus = dcurrStatus;
1533         StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1534         if (readyForDistribution == StorageOperationStatus.OK) {
1535             INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1536             ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1537             if (notifyServiceResponse == ActionStatus.OK) {
1538                 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user,
1539                     DistributionStatusEnum.DISTRIBUTED);
1540                 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1541                     updatedService = updateStateRes.left().value();
1542                     updatedStatus = updatedService.getDistributionStatus().name();
1543                 } else {
1544                     // The response is not relevant
1545                     updatedService = service;
1546                 }
1547                 ASDCKpiApi.countActivatedDistribution();
1548                 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1549                 result = Either.left(updatedService);
1550             } else {
1551                 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1552                 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1553                 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1554                 result = Either.right(response);
1555             }
1556         } else {
1557             response = componentsUtils
1558                 .getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution, ComponentTypeEnum.SERVICE), envName);
1559             result = Either.right(response);
1560         }
1561         componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1562             new ResourceCommonInfo(service.getName(), ComponentTypeEnum.SERVICE.getValue()),
1563             ResourceVersionInfo.newBuilder().distributionStatus(dcurrStatus).build(),
1564             ResourceVersionInfo.newBuilder().distributionStatus(updatedStatus).build(), null, null, did);
1565         return result;
1566     }
1567
1568     // convert to private after deletion of temp url
1569     public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1570         validateUserExists(user.getUserId());
1571         String serviceId = service.getUniqueId();
1572         lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1573         try {
1574             Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1575             if (result.isRight()) {
1576                 janusGraphDao.rollback();
1577                 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1578                 log.debug("service {}  change distribution status failed", serviceId);
1579                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1580             }
1581             janusGraphDao.commit();
1582             updateCatalog(service, ChangeTypeEnum.LIFECYCLE);
1583             return Either.left(result.left().value());
1584         } finally {
1585             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1586         }
1587     }
1588
1589     public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1590         validateUserExists(user.getUserId());
1591         log.debug("mark distribution deployed");
1592         AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1593         Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1594         if (getServiceResponse.isRight()) {
1595             BeEcompErrorManager.getInstance()
1596                 .logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1597             log.debug("service {} not found", serviceId);
1598             ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null,
1599                 componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1600             return Either.right(responseFormat);
1601         }
1602         Service service = getServiceResponse.left().value();
1603         user = validateRoleForDeploy(did, user, auditAction, service);
1604         return checkDistributionAndDeploy(did, user, auditAction, service);
1605     }
1606
1607     public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1608         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1609             // Only one VF Module Artifact per instance - add it to a list of one
1610             buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1611         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1612     }
1613
1614     private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock,
1615                                                                              boolean inTransaction, ComponentInstance ri) {
1616         List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1617         if (ri.getOriginType() == OriginTypeEnum.VF) {
1618             asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
1619         }
1620         return asList;
1621     }
1622
1623     private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
1624         Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1625         if (currVF.getGroupInstances() != null) {
1626             currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1627         }
1628         return currVF.getGroupInstances();
1629     }
1630
1631     private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper,
1632                                                                       Wrapper<ResponseFormat> responseWrapper) {
1633         ArtifactDefinition vfModuleAertifact = null;
1634         if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1635             final Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream()
1636                 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType())).findAny();
1637             if (optionalVfModuleArtifact.isPresent()) {
1638                 vfModuleAertifact = optionalVfModuleArtifact.get();
1639             }
1640         }
1641         if (vfModuleAertifact == null) {
1642             Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service,
1643                 payloadWrapper.getInnerElement());
1644             if (createVfModuleArtifact.isLeft()) {
1645                 vfModuleAertifact = createVfModuleArtifact.left().value();
1646             } else {
1647                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1648             }
1649         }
1650         return vfModuleAertifact;
1651     }
1652
1653     private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1654         List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
1655         if (groupsForCurrVF != null) {
1656             for (GroupInstance groupInstance : groupsForCurrVF) {
1657                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1658                 vfModulePayloads.add(modulePayload);
1659             }
1660             vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
1661             final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1662             String vfModulePayloadString = gson.toJson(vfModulePayloads);
1663             payloadWrapper.setInnerElement(vfModulePayloadString);
1664         }
1665     }
1666
1667     private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance,
1668                                                                                         Service service, boolean shouldLock, boolean inTransaction) {
1669         ArtifactDefinition vfModuleArtifact = null;
1670         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1671         Wrapper<String> payloadWrapper = new Wrapper<>();
1672         List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
1673         if (responseWrapper.isEmpty()) {
1674             fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1675         }
1676         if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1677             vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
1678         }
1679         if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
1680             vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper,
1681                 responseWrapper, service);
1682         }
1683         Either<ArtifactDefinition, ResponseFormat> result;
1684         if (responseWrapper.isEmpty()) {
1685             result = Either.left(vfModuleArtifact);
1686         } else {
1687             result = Either.right(responseWrapper.getInnerElement());
1688         }
1689         return result;
1690     }
1691
1692     private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock,
1693                                                    boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper,
1694                                                    Service service) {
1695         ArtifactDefinition result = null;
1696         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic
1697             .generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock,
1698                 inTransaction, System::currentTimeMillis, () -> Either.left(
1699                     artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))),
1700                 currVF.getUniqueId());
1701         if (eitherPayload.isLeft()) {
1702             result = eitherPayload.left().value();
1703         } else {
1704             responseWrapper.setInnerElement(eitherPayload.right().value());
1705         }
1706         if (result == null) {
1707             result = vfModuleArtifact;
1708         }
1709         return result;
1710     }
1711
1712     private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service,
1713                                                                               String vfModulePayloadString) {
1714         ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
1715         String newCheckSum = null;
1716         vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
1717         vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
1718         vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
1719         vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
1720         vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
1721         vfModuleArtifactDefinition.setTimeout(0);
1722         vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
1723         vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
1724         if (vfModulePayloadString != null) {
1725             newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
1726         }
1727         vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
1728         Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation
1729             .addArtifactToComponent(vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
1730         Either<ArtifactDefinition, ResponseFormat> result;
1731         if (addArtifactToComponent.isLeft()) {
1732             result = Either.left(addArtifactToComponent.left().value());
1733         } else {
1734             result = Either
1735                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
1736         }
1737         return result;
1738     }
1739
1740     public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1741         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1742             // Get All Deployment Artifacts
1743             service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance)
1744                 .filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1745                 // Filter in Only Heat Env
1746                     filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1747                 // Create ArtifactGenerator from those Artifacts
1748                     map(
1749                     depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction,
1750                         resourceInstance.getUniqueId())).collect(Collectors.toList());
1751         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1752     }
1753
1754     private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service,
1755                                                                                   Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1756         // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1757
1758         // service
1759         if (service.getComponentInstances() != null) {
1760             List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream()
1761                 .flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1762             if (artifactGenList != null && !artifactGenList.isEmpty()) {
1763                 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
1764                 if (callRes != null) {
1765                     return callRes;
1766                 }
1767             }
1768         }
1769         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1770         if (storageStatus.isRight()) {
1771             return Either.right(componentsUtils
1772                 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1773         }
1774         Service currentService = storageStatus.left().value();
1775         return Either.left(currentService);
1776     }
1777
1778     private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
1779         for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1780             Either<CallVal, ResponseFormat> callRes;
1781             try {
1782                 callRes = entry.call();
1783                 if (callRes.isRight()) {
1784                     log.debug("Failed to generate artifact error : {}", callRes.right().value());
1785                     return Either.right(callRes.right().value());
1786                 }
1787             } catch (Exception e) {
1788                 log.debug("Failed to generate artifact exception : {}", e);
1789                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1790             }
1791         }
1792         return null;
1793     }
1794
1795     private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction,
1796                                                                                     Service service) {
1797         boolean isDeployed = isDistributionDeployed(distributionId);
1798         if (isDeployed) {
1799             return Either.left(service);
1800         }
1801         Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
1802         if (distributionSuccess.isRight()) {
1803             return Either.right(distributionSuccess.right().value());
1804         }
1805         log.debug("mark distribution {} as deployed - success", distributionId);
1806         componentsUtils
1807             .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK",
1808                 user);
1809         return Either.left(service);
1810     }
1811
1812     private boolean isDistributionDeployed(String distributionId) {
1813         Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao
1814             .getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1815         boolean isDeployed = false;
1816         if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1817             // already deployed
1818             log.debug("distribution {} is already deployed", distributionId);
1819             isDeployed = true;
1820         }
1821         return isDeployed;
1822     }
1823
1824     protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1825         log.trace("checkDistributionSuccess");
1826         // get all "DRequest" records for this distribution
1827         Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao
1828             .getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1829         if (distRequestsResponse.isRight()) {
1830             ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1831             return Either.right(error);
1832         }
1833         List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1834         if (distributionRequests.isEmpty()) {
1835             BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1836             log.info("distribution {} is not found", did);
1837             ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1838             return Either.right(error);
1839         }
1840         boolean isRequestSucceeded = false;
1841         for (ResourceAdminEvent event : distributionRequests) {
1842             String eventStatus = event.getStatus();
1843             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1844                 isRequestSucceeded = true;
1845                 break;
1846             }
1847         }
1848         // get all "DNotify" records for this distribution
1849         Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao
1850             .getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1851         if (distNotificationsResponse.isRight()) {
1852             ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1853             return Either.right(error);
1854         }
1855         List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1856         boolean isNotificationsSucceeded = false;
1857         for (DistributionNotificationEvent event : distributionNotifications) {
1858             String eventStatus = event.getStatus();
1859             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1860                 isNotificationsSucceeded = true;
1861                 break;
1862             }
1863         }
1864         // if request failed OR there are notifications that failed
1865         if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1866             log.info("distribution {} has failed", did);
1867             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1868             auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1869             return Either.right(error);
1870         }
1871         return Either.left(true);
1872     }
1873
1874     private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status,
1875                                             String... params) {
1876         ResponseFormat error = componentsUtils.getResponseFormat(status, params);
1877         String message = "";
1878         if (error.getMessageId() != null) {
1879             message = error.getMessageId() + ": ";
1880         }
1881         message += error.getFormattedMessage();
1882         if (service != null) {
1883             componentsUtils
1884                 .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(),
1885                     message, user);
1886         } else {
1887             componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
1888         }
1889         return error;
1890     }
1891
1892     private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
1893         user = userAdmin.getUser(user.getUserId());
1894         log.debug("validate user role");
1895         List<Role> roles = new ArrayList<>();
1896         roles.add(Role.ADMIN);
1897         roles.add(Role.DESIGNER);
1898         try {
1899             validateUserRole(user, service, roles, auditAction, null);
1900         } catch (ByActionStatusComponentException e) {
1901             log.info("role {} is not allowed to perform this action", user.getRole());
1902             auditDeployError(did, user, auditAction, service, e.getActionStatus());
1903             throw e;
1904         }
1905         return user;
1906     }
1907
1908     @Override
1909     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
1910         if (component instanceof Service) {
1911             Service service = (Service) component;
1912             Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
1913             if (artifactMap == null) {
1914                 artifactMap = new HashMap<>();
1915             }
1916             service.setDeploymentArtifacts(artifactMap);
1917         } else if (component instanceof Resource) {
1918             Resource resource = (Resource) component;
1919             Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
1920             if (artifactMap == null) {
1921                 artifactMap = new HashMap<>();
1922             }
1923             Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1924                 .getDeploymentResourceArtifacts();
1925             if (deploymentResourceArtifacts != null) {
1926                 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
1927                 deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
1928             }
1929             resource.setDeploymentArtifacts(artifactMap);
1930         }
1931     }
1932
1933     private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
1934         Map<String, Object> artifactDetails = (Map<String, Object>) v;
1935         Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
1936         if (object != null) {
1937             List<String> artifactTypes = (List<String>) object;
1938             if (!artifactTypes.contains(resource.getResourceType().name())) {
1939                 return;
1940             }
1941         } else {
1942             log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
1943         }
1944         if (artifactsBusinessLogic != null) {
1945             ArtifactDefinition artifactDefinition = artifactsBusinessLogic
1946                 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
1947             if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
1948                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1949             }
1950         }
1951     }
1952
1953     @Override
1954     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
1955         return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
1956     }
1957
1958     private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
1959         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
1960             .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
1961         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
1962         return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
1963     }
1964
1965     @Override
1966     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
1967         return componentInstanceBusinessLogic;
1968     }
1969
1970     @Override
1971     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
1972         validateUserExists(userId);
1973         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
1974         if (getComponentRes.isRight()) {
1975             ResponseFormat responseFormat = componentsUtils
1976                 .getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
1977             return Either.right(responseFormat);
1978         }
1979         List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
1980         return Either.left(componentInstances);
1981     }
1982
1983     @Autowired
1984     public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
1985         this.forwardingPathOperation = forwardingPathOperation;
1986     }
1987
1988     /**
1989      * updates group instance with new property values in case of successful update of group instance related component instance will be updated with
1990      * new modification time and related service will be updated with new last update date
1991      */
1992     public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId,
1993                                                                                                  String componentInstanceId, String groupInstanceId,
1994                                                                                                  List<GroupInstanceProperty> newProperties) {
1995         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
1996         Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
1997         Component component = null;
1998         Either<Boolean, ResponseFormat> lockResult = null;
1999         log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2000         try {
2001             validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2002             if (validateUserAndComponentRes.isRight()) {
2003                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
2004                 actionResult = Either.right(validateUserAndComponentRes.right().value());
2005             }
2006             if (actionResult == null) {
2007                 component = validateUserAndComponentRes.left().value().getKey();
2008                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2009                 if (lockResult.isRight()) {
2010                     log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2011                     actionResult = Either.right(lockResult.right().value());
2012                 } else {
2013                     log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2014                 }
2015             }
2016             if (actionResult == null) {
2017                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId,
2018                     newProperties);
2019                 if (actionResult.isRight()) {
2020                     log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ",
2021                         groupInstanceId, actionResult.right().value().getFormattedMessage());
2022                 }
2023             }
2024         } catch (Exception e) {
2025             log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2026             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2027         } finally {
2028             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2029                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2030             }
2031         }
2032         return actionResult;
2033     }
2034
2035     private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component,
2036                                                                                                                                  String componentInstanceId,
2037                                                                                                                                  String groupInstanceId,
2038                                                                                                                                  List<GroupInstanceProperty> newProperties) {
2039         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2040         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2041         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2042         ComponentInstance relatedComponentInstance = null;
2043         GroupInstance oldGroupInstance = null;
2044         Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2045         GroupInstance updatedGroupInstance = null;
2046         boolean inTransaction = true;
2047         findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2048         if (findGroupInstanceRes.isRight()) {
2049             log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2050             actionResult = Either.right(findGroupInstanceRes.right().value());
2051         }
2052         if (actionResult == null) {
2053             oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2054             relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2055             updateGroupInstanceResult = groupBusinessLogic
2056                 .validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2057             if (updateGroupInstanceResult.isRight()) {
2058                 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ",
2059                     oldGroupInstance.getName());
2060                 actionResult = Either.right(updateGroupInstanceResult.right().value());
2061             }
2062         }
2063         if (actionResult == null) {
2064             updatedGroupInstance = updateGroupInstanceResult.left().value();
2065             if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2066                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance,
2067                     updatedGroupInstance, inTransaction);
2068                 if (updateParentsModificationTimeRes.isRight()) {
2069                     log.debug(
2070                         "#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ",
2071                         oldGroupInstance.getName());
2072                     actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2073                 }
2074             }
2075         }
2076         if (actionResult == null) {
2077             actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2078         }
2079         return actionResult;
2080     }
2081
2082     private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(
2083         Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance, boolean inTranscation) {
2084         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2085         Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2086         Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic
2087             .updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2088                 updatedGroupInstance.getModificationTime(), inTranscation);
2089         if (updateComponentInstanceRes.isRight()) {
2090             log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(),
2091                 updatedGroupInstance.getName());
2092             actionResult = Either.right(updateComponentInstanceRes.right().value());
2093         } else {
2094             serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2095             if (serviceMetadataUpdateResult.isRight()) {
2096                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ",
2097                     component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2098                 actionResult = Either.right(
2099                     componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2100             } else {
2101                 actionResult = Either
2102                     .left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2103             }
2104         }
2105         return actionResult;
2106     }
2107
2108     private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2109         Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2110         User currUser = null;
2111         Component component = null;
2112         Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2113         if (validationUserResult.isRight()) {
2114             log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2115             result = Either.right(validationUserResult.right().value());
2116         }
2117         if (result == null) {
2118             currUser = validationUserResult.left().value();
2119             try {
2120                 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2121                 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2122                     log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(),
2123                         component.getCreatorUserId());
2124                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2125                 }
2126             } catch (ComponentException e) {
2127                 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2128                 result = Either.right(e.getResponseFormat());
2129             }
2130         }
2131         if (result == null) {
2132             result = Either.left(new ImmutablePair<>(component, currUser));
2133         }
2134         return result;
2135     }
2136
2137     private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component,
2138                                                                                                                                 String componentInstanceId,
2139                                                                                                                                 String groupInstanceId) {
2140         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2141         GroupInstance groupInstance = null;
2142         ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2143         if (foundComponentInstance == null) {
2144             log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2145             actionResult = Either.right(componentsUtils
2146                 .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service",
2147                     component.getName()));
2148         } else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2149             groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst()
2150                 .orElse(null);
2151             if (groupInstance == null) {
2152                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2153                 actionResult = Either.right(componentsUtils
2154                     .getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId,
2155                         foundComponentInstance.getName()));
2156             }
2157         }
2158         if (actionResult == null) {
2159             actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2160         }
2161         return actionResult;
2162     }
2163
2164     private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2165         ComponentInstance componentInstance = null;
2166         if (isNotEmpty(component.getComponentInstances())) {
2167             componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst()
2168                 .orElse(null);
2169         }
2170         return componentInstance;
2171     }
2172
2173     private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2174         User user = validateUser(modifier, ecompErrorContext, null, null, false);
2175         List<Role> roles = new ArrayList<>();
2176         roles.add(Role.ADMIN);
2177         roles.add(Role.DESIGNER);
2178         validateUserRole(user, roles);
2179         return Either.left(user);
2180     }
2181
2182     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId,
2183                                                                                                    List<String> dataParamsToReturn) {
2184         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2185         paramsToReturn.setIgnoreComponentInstancesProperties(false);
2186         Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2187         if (serviceResultEither.isRight()) {
2188             if (serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2189                 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2190                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2191             }
2192             log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2193             return Either.right(
2194                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2195         }
2196         Service service = serviceResultEither.left().value();
2197         if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2198             ListUtils.emptyIfNull(service.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
2199         }
2200         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2201         return Either.left(dataTransfer);
2202     }
2203
2204     @Autowired(required = false)
2205     public void setServiceCreationPluginList(List<ServiceCreationPlugin> serviceCreationPluginList) {
2206         this.serviceCreationPluginList = serviceCreationPluginList;
2207     }
2208
2209     public boolean isServiceExist(String serviceName) {
2210         Either<Service, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByServiceName(serviceName);
2211         return latestByName.isLeft();
2212     }
2213
2214     abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2215
2216     }
2217
2218     @Getter
2219     class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2220
2221         private ArtifactDefinition artifactDefinition;
2222         private Service service;
2223         private String resourceInstanceName;
2224         private User modifier;
2225         private String instanceId;
2226         private boolean shouldLock;
2227         private boolean inTransaction;
2228
2229         HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier,
2230                                  boolean shouldLock, boolean inTransaction, String instanceId) {
2231             this.artifactDefinition = artifactDefinition;
2232             this.service = service;
2233             this.resourceInstanceName = resourceInstanceName;
2234             this.modifier = modifier;
2235             this.shouldLock = shouldLock;
2236             this.instanceId = instanceId;
2237             this.inTransaction = inTransaction;
2238         }
2239
2240         @Override
2241         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2242             return artifactsBusinessLogic
2243                 .forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier,
2244                     shouldLock, inTransaction, instanceId);
2245         }
2246     }
2247
2248     class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2249
2250         boolean shouldLock;
2251         boolean inTransaction;
2252         private User user;
2253         private ComponentInstance componentInstance;
2254         private Service service;
2255
2256         private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock,
2257                                           boolean inTransaction) {
2258             super();
2259             this.user = user;
2260             this.componentInstance = componentInstance;
2261             this.service = service;
2262             this.shouldLock = shouldLock;
2263             this.inTransaction = inTransaction;
2264         }
2265
2266         @Override
2267         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2268             return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2269         }
2270     }
2271 }