21d27f3fa011738ae73bc0e39c3d1cabaaea5889
[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);
386             if (constraintValidationResult.isRight()) {
387                 return Either.right(constraintValidationResult.right().value());
388             }
389             return handleConsumptionStaticValue(consumptionValue, type, operation, operationInputDefinition);
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) {
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);
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) {
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()
552             .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
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             final Resource genericType = fetchAndSetDerivedFromGenericType(service);
705             generatePropertiesFromGenericType(service, genericType);
706             generateAndAddInputsFromGenericTypeProperties(service, genericType);
707             beforeCreate(service);
708             Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
709             if (dataModelResponse.isLeft()) {
710                 log.debug("Service '{}' created successfully", service.getName());
711                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
712                 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
713                 ASDCKpiApi.countCreatedServicesKPI();
714                 return Either.left(dataModelResponse.left().value());
715             }
716             ResponseFormat responseFormat = componentsUtils
717                 .getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service,
718                     ComponentTypeEnum.SERVICE);
719             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
720             componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
721             return Either.right(responseFormat);
722         } finally {
723             graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
724         }
725     }
726
727     private void beforeCreate(final Service service) {
728         if (CollectionUtils.isEmpty(serviceCreationPluginList)) {
729             return;
730         }
731         serviceCreationPluginList.stream().sorted(Comparator.comparingInt(ServiceCreationPlugin::getOrder)).forEach(serviceCreationPlugin -> {
732             try {
733                 serviceCreationPlugin.beforeCreate(service);
734             } catch (final Exception e) {
735                 log.error("An error has occurred while running the serviceCreationPlugin '{}'", serviceCreationPlugin.getClass(), e);
736             }
737         });
738     }
739
740     @SuppressWarnings("unchecked")
741     private void createServiceApiArtifactsData(Service service, User user) {
742         // create mandatory artifacts
743
744         // TODO it must be removed after that artifact uniqueId creation will be
745
746         // moved to ArtifactOperation
747         String serviceUniqueId = service.getUniqueId();
748         Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
749         if (artifactMap == null) {
750             artifactMap = new HashMap<>();
751         }
752         Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
753         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
754         List<CategoryDefinition> categories = service.getCategories();
755         boolean isCreateArtifact = true;
756         if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
757             for (String exlude : exludeServiceCategory) {
758                 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
759                     isCreateArtifact = false;
760                     break;
761                 }
762             }
763         }
764         if (serviceApiArtifacts != null && isCreateArtifact) {
765             Set<String> keys = serviceApiArtifacts.keySet();
766             for (String serviceApiArtifactName : keys) {
767                 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
768                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user,
769                     true);
770                 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
771                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
772             }
773             service.setServiceApiArtifacts(artifactMap);
774         }
775     }
776
777     @VisibleForTesting
778     protected Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
779         try {
780             serviceValidator.validate(user, service, actionEnum);
781         } catch (ComponentException exp) {
782             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exp);
783             componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
784             throw exp;
785         }
786         service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
787         service.setContactId(service.getContactId().toLowerCase());
788         // Generate invariant UUID - must be here and not in operation since it
789
790         // should stay constant during clone
791         String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
792         service.setInvariantUUID(invariantUUID);
793         return Either.left(service);
794     }
795
796     public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
797         validateUserExists(userId);
798         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade
799             .validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
800         // DE242223
801         janusGraphDao.commit();
802         if (dataModelResponse.isLeft()) {
803             Map<String, Boolean> result = new HashMap<>();
804             result.put(IS_VALID, dataModelResponse.left().value());
805             log.debug("validation was successfully performed.");
806             return Either.left(result);
807         }
808         ResponseFormat responseFormat = componentsUtils
809             .getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
810         return Either.right(responseFormat);
811     }
812
813     public void setElementDao(IElementOperation elementDao) {
814         this.elementDao = elementDao;
815     }
816
817     @Autowired
818     public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
819         this.auditCassandraDao = auditingDao;
820     }
821
822     public ArtifactsBusinessLogic getArtifactBl() {
823         return artifactsBusinessLogic;
824     }
825
826     public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
827         this.artifactsBusinessLogic = artifactBl;
828     }
829
830     public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
831         user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
832         // validate user role
833         validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
834         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
835         if (storageStatus.isRight()) {
836             return Either.right(componentsUtils
837                 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
838         }
839         Service currentService = storageStatus.left().value();
840         if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
841             log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
842             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
843         }
844         Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
845         if (validationRsponse.isRight()) {
846             log.info("service update metadata: validations field.");
847             return validationRsponse;
848         }
849         Service serviceToUpdate = validationRsponse.left().value();
850         // lock resource
851         lockComponent(serviceId, currentService, "Update Service Metadata");
852         try {
853             return toscaOperationFacade.updateToscaElement(serviceToUpdate).right().map(rf -> {
854                 janusGraphDao.rollback();
855                 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
856                 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
857                 return (componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
858             }).left().bind(c -> updateCatalogAndCommit(c));
859         } finally {
860             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
861         }
862     }
863
864     private Either<Service, ResponseFormat> updateCatalogAndCommit(Service service) {
865         Either<Service, ResponseFormat> res = updateCatalog(service, ChangeTypeEnum.LIFECYCLE).left().map(s -> (Service) s);
866         janusGraphDao.commit();
867         return res;
868     }
869
870     public Set<String> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
871         Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
872         user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
873         // validate user role
874         validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
875         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
876         if (storageStatus.isRight()) {
877             throw new ByActionStatusComponentException(
878                 componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
879         }
880         Service service = storageStatus.left().value();
881         Either<Set<String>, StorageOperationStatus> result = null;
882         if (lock) {
883             try {
884                 lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
885             } catch (ComponentException e) {
886                 janusGraphDao.rollback();
887                 throw new ByActionStatusComponentException(
888                     componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
889             }
890         }
891         try {
892             result = forwardingPathOperation.deleteForwardingPath(service, pathIdsToDelete);
893             if (result.isRight()) {
894                 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
895                 janusGraphDao.rollback();
896                 throw new ByActionStatusComponentException(
897                     componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE));
898             }
899             janusGraphDao.commit();
900             log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
901         } catch (ComponentException e) {
902             log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
903             janusGraphDao.rollback();
904             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
905         } finally {
906             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
907         }
908         return result.left().value();
909     }
910
911     private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
912         Service serviceToDelete = new Service();
913         serviceToDelete.setUniqueId(serviceId);
914         serviceToDelete.setForwardingPaths(new HashMap<>());
915         pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
916         return serviceToDelete;
917     }
918
919     public Service updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
920         return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true, "updateForwardingPath", lock);
921     }
922
923     public Service createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
924         return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
925     }
926
927     private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path) {
928         ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
929         dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
930         dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
931         dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
932         dataDefinition.setUniqueId(path.getUniqueId());
933         dataDefinition.setPathElements(path.getPathElements());
934         dataDefinition.setDescription(path.getDescription());
935         dataDefinition.setToscaResourceName(path.getToscaResourceName());
936         return dataDefinition;
937     }
938
939     private Service createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext,
940                                                  boolean lock) {
941         validateUserAndRole(serviceUpdate, user, errorContext);
942         Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
943         Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths = forwardingPaths.entrySet().stream()
944             .collect(Collectors.toMap(Map.Entry::getKey, entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
945         forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(), serviceId, isUpdate);
946         Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
947         if (serviceStorageOperationStatusEither.isRight()) {
948             StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
949             log.debug("Failed to fetch service information by service id, error {}", errorStatus);
950             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
951         }
952         Service storedService = serviceStorageOperationStatusEither.left().value();
953         Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
954         Component component = getForwardingPathOriginComponent();
955         final String toscaResourceName;
956         if (component.getComponentType() == ComponentTypeEnum.RESOURCE) {
957             toscaResourceName = ((Resource) component).getToscaResourceName();
958         } else {
959             toscaResourceName = "";
960         }
961         if (lock) {
962             lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
963             log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
964         }
965         Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
966         try {
967             trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
968             populateForwardingPaths(serviceId, isUpdate, trimmedForwardingPaths, resultMap);
969             janusGraphDao.commit();
970         } finally {
971             if (lock) {
972                 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
973             }
974         }
975         return createServiceWithForwardingPathForResponse(serviceId, resultMap);
976     }
977
978     private Component getForwardingPathOriginComponent() {
979         Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade
980             .getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME, null);
981         if (forwardingPathOrigin.isRight()) {
982             StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
983             log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
984             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
985         }
986         return forwardingPathOrigin.left().value();
987     }
988
989     private void populateForwardingPaths(String serviceId, boolean isUpdate, Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths,
990                                          Map<String, ForwardingPathDataDefinition> resultMap) {
991         Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
992         try {
993             for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
994                 if (isUpdate) {
995                     result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
996                 } else {
997                     result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
998                 }
999                 if (result.isRight()) {
1000                     janusGraphDao.rollback();
1001                     throw new ByResponseFormatComponentException(componentsUtils
1002                         .getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE), ""));
1003                 } else {
1004                     ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1005                     resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1006                 }
1007             }
1008         } catch (ComponentException e) {
1009             janusGraphDao.rollback();
1010             log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(), e);
1011             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1012         }
1013     }
1014
1015     private Service createServiceWithForwardingPathForResponse(String serviceId,
1016                                                                Map<String, ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1017         Service service = new Service();
1018         service.setUniqueId(serviceId);
1019         service.setForwardingPaths(forwardingPathDataDefinitionMap);
1020         return service;
1021     }
1022
1023     private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1024         user = validateUser(user, errorContext, serviceUpdate, null, false);
1025         validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1026     }
1027
1028     @VisibleForTesting
1029     Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1030         try {
1031             boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1032             Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified,
1033                 UPDATE_SERVICE_METADATA);
1034             if (response.isRight()) {
1035                 ResponseFormat errorResponse = response.right().value();
1036                 return Either.right(errorResponse);
1037             }
1038             verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1039             verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1040             verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1041             verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1042             response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1043             if (response.isRight()) {
1044                 return Either.right(response.right().value());
1045             }
1046             verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1047             if (serviceUpdate.getProjectCode() != null) {
1048                 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1049                 if (response.isRight()) {
1050                     return Either.right(response.right().value());
1051                 }
1052             }
1053             response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1054             if (response.isRight()) {
1055                 return Either.right(response.right().value());
1056             }
1057             verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1058             verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1059             response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1060             if (response.isRight()) {
1061                 return Either.right(response.right().value());
1062             }
1063             response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1064             if (response.isRight()) {
1065                 return Either.right(response.right().value());
1066             }
1067             response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1068             if (response.isRight()) {
1069                 return Either.right(response.right().value());
1070             }
1071             verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1072             verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1073             verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1074             verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1075             validateAndUpdateServiceType(currentService, serviceUpdate);
1076             validateAndUpdateServiceFunction(currentService, serviceUpdate);
1077             response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1078             if (response.isRight()) {
1079                 return Either.right(response.right().value());
1080             }
1081             response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1082             if (response.isRight()) {
1083                 return Either.right(response.right().value());
1084             }
1085             verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1086             validateAndUpdateEcompNaming(currentService, serviceUpdate);
1087             currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1088             currentService.setCategorySpecificMetadata(serviceUpdate.getCategorySpecificMetadata());
1089             return Either.left(currentService);
1090         } catch (ComponentException exception) {
1091             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1092             componentsUtils
1093                 .auditComponentAdmin(responseFormat, user, serviceUpdate, AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1094             return Either.right(responseFormat);
1095         }
1096     }
1097
1098     private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1099         if (updatedValue != null && !updatedValue.equals(originalValue)) {
1100             log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1101         }
1102     }
1103
1104     private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1105         Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1106         Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1107         if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1108             currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1109         }
1110         String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1111         if (currentService.isEcompGeneratedNaming() != null && currentService.isEcompGeneratedNaming()) {
1112             currentService.setNamingPolicy(namingPolicyUpdate);
1113         } else {
1114             if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1115                 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1116             }
1117             currentService.setNamingPolicy("");
1118         }
1119     }
1120
1121     private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate,
1122                                                                        AuditingActionEnum audatingAction) {
1123         String contactIdUpdated = serviceUpdate.getContactId();
1124         String contactIdCurrent = currentService.getContactId();
1125         if (!contactIdCurrent.equals(contactIdUpdated)) {
1126             componentContactIdValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1127             currentService.setContactId(contactIdUpdated.toLowerCase());
1128         }
1129         return Either.left(true);
1130     }
1131
1132     private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate,
1133                                                                   AuditingActionEnum audatingAction) {
1134         List<String> tagsUpdated = serviceUpdate.getTags();
1135         List<String> tagsCurrent = currentService.getTags();
1136         if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1137             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1138             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1139             return Either.right(responseFormat);
1140         }
1141         if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1142             componentTagsValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1143             currentService.setTags(tagsUpdated);
1144         }
1145         return Either.left(true);
1146     }
1147
1148     private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate,
1149                                                                          AuditingActionEnum audatingAction) {
1150         String descriptionUpdated = serviceUpdate.getDescription();
1151         String descriptionCurrent = currentService.getDescription();
1152         if (!descriptionCurrent.equals(descriptionUpdated)) {
1153             componentDescriptionValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1154             currentService.setDescription(serviceUpdate.getDescription());
1155         }
1156         return Either.left(true);
1157     }
1158
1159     private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate,
1160                                                                          AuditingActionEnum audatingAction) {
1161         String projectCodeUpdated = serviceUpdate.getProjectCode();
1162         String projectCodeCurrent = currentService.getProjectCode();
1163         if (StringUtils.isEmpty(projectCodeCurrent) || !projectCodeCurrent.equals(projectCodeUpdated)) {
1164             try {
1165                 componentProjectCodeValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1166             } catch (ComponentException exp) {
1167                 ResponseFormat errorRespons = exp.getResponseFormat();
1168                 return Either.right(errorRespons);
1169             }
1170             currentService.setProjectCode(projectCodeUpdated);
1171         }
1172         return Either.left(true);
1173     }
1174
1175     private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified,
1176                                                                   AuditingActionEnum audatingAction) {
1177         String iconUpdated = serviceUpdate.getIcon();
1178         String iconCurrent = currentService.getIcon();
1179         if (!iconCurrent.equals(iconUpdated)) {
1180             if (!hasBeenCertified) {
1181                 componentIconValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1182                 currentService.setIcon(iconUpdated);
1183             } else {
1184                 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1185                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1186                 return Either.right(errorResponse);
1187             }
1188         }
1189         return Either.left(true);
1190     }
1191
1192     private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate,
1193                                                                          boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1194         String serviceNameUpdated = serviceUpdate.getName();
1195         String serviceNameCurrent = currentService.getName();
1196         if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1197             if (!hasBeenCertified) {
1198                 componentNameValidator.validateAndCorrectField(user, serviceUpdate, auditingAction);
1199                 try {
1200                     componentNameValidator.validateComponentNameUnique(user, serviceUpdate, auditingAction);
1201                 } catch (ComponentException exp) {
1202                     return Either.right(exp.getResponseFormat());
1203                 }
1204                 currentService.setName(serviceNameUpdated);
1205                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1206                     .setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1207                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition()
1208                     .setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1209             } else {
1210                 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1211                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1212                 return Either.right(errorResponse);
1213             }
1214         }
1215         return Either.left(true);
1216     }
1217
1218     private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1219         String updatedServiceType = updatedService.getServiceType();
1220         String currentServiceType = currentService.getServiceType();
1221         if (!currentServiceType.equals(updatedServiceType)) {
1222             serviceTypeValidator.validateAndCorrectField(null, updatedService, null);
1223             currentService.setServiceType(updatedServiceType);
1224         }
1225     }
1226
1227     private void validateAndUpdateServiceFunction(Service currentService, Service updatedService) {
1228         String updatedServiceFunction = updatedService.getServiceFunction();
1229         String currentServiceFunction = currentService.getServiceFunction();
1230         if (!currentServiceFunction.equals(updatedServiceFunction)) {
1231             serviceFunctionValidator.validateAndCorrectField(null, updatedService, null);
1232             currentService.setServiceFunction(updatedService.getServiceFunction());
1233         }
1234     }
1235
1236     private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService,
1237                                                                          AuditingActionEnum auditingAction) {
1238         String updatedServiceRole = updatedService.getServiceRole();
1239         String currentServiceRole = currentService.getServiceRole();
1240         if (!currentServiceRole.equals(updatedServiceRole)) {
1241             try {
1242                 serviceRoleValidator.validateAndCorrectField(user, updatedService, auditingAction);
1243             } catch (ComponentException exp) {
1244                 ResponseFormat errorResponse = exp.getResponseFormat();
1245                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1246                 return Either.right(errorResponse);
1247             }
1248             currentService.setServiceRole(updatedServiceRole);
1249         }
1250         return Either.left(true);
1251     }
1252
1253     private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService,
1254                                                                                     AuditingActionEnum auditingAction) {
1255         String updatedInstaType = updatedService.getInstantiationType();
1256         String currentInstaType = currentService.getInstantiationType();
1257         if (!currentInstaType.equals(updatedInstaType)) {
1258             try {
1259                 serviceInstantiationTypeValidator.validateAndCorrectField(user, updatedService, auditingAction);
1260             } catch (ComponentException exp) {
1261                 ResponseFormat errorResponse = exp.getResponseFormat();
1262                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1263                 return Either.right(errorResponse);
1264             }
1265             currentService.setInstantiationType(updatedInstaType);
1266         }
1267         return Either.left(true);
1268     }
1269
1270     private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate,
1271                                                                       boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1272         try {
1273             List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1274             List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1275             serviceCategoryValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1276             if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1277                 if (!hasBeenCertified) {
1278                     currentService.setCategories(categoryUpdated);
1279                 } else {
1280                     log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1281                     ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1282                     return Either.right(errorResponse);
1283                 }
1284             }
1285         } catch (ComponentException exp) {
1286             return Either.right(exp.getResponseFormat());
1287         }
1288         return Either.left(true);
1289     }
1290
1291     public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1292         Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1293         if (serviceResponseFormatEither.isRight()) {
1294             return Either.right(serviceResponseFormatEither.right().value());
1295         }
1296         final ServiceRelations serviceRelations = new ForwardingPathUtils()
1297             .convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1298         return Either.left(serviceRelations);
1299     }
1300
1301     public ResponseFormat deleteService(String serviceId, User user) {
1302         ResponseFormat responseFormat;
1303         validateUserExists(user);
1304         Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1305         if (serviceStatus.isRight()) {
1306             log.debug("failed to get service {}", serviceId);
1307             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1308         }
1309         Service service = serviceStatus.left().value();
1310         StorageOperationStatus result = StorageOperationStatus.OK;
1311         try {
1312             lockComponent(service, "Mark service to delete");
1313             result = markComponentToDelete(service);
1314             if (result == StorageOperationStatus.OK) {
1315                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1316             } else {
1317                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1318                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1319             }
1320             return responseFormat;
1321         } catch (ComponentException e) {
1322             return e.getResponseFormat();
1323         } finally {
1324             if (result == null || result != StorageOperationStatus.OK) {
1325                 log.warn("operation failed. do rollback");
1326                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1327                 janusGraphDao.rollback();
1328             } else {
1329                 log.debug("operation success. do commit");
1330                 janusGraphDao.commit();
1331             }
1332             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1333         }
1334     }
1335
1336     public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1337         ResponseFormat responseFormat;
1338         String ecompErrorContext = "delete service";
1339         validateUserNotEmpty(user, ecompErrorContext);
1340         user = validateUserExists(user);
1341         Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1342         if (getResult.isRight()) {
1343             return getResult.right().value();
1344         }
1345         Service service = getResult.left().value();
1346         StorageOperationStatus result = StorageOperationStatus.OK;
1347         try {
1348             lockComponent(service, "Mark service to delete");
1349             result = markComponentToDelete(service);
1350             if (result == StorageOperationStatus.OK) {
1351                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1352             } else {
1353                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1354                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1355             }
1356             return responseFormat;
1357         } catch (ComponentException e) {
1358             result = StorageOperationStatus.GENERAL_ERROR;
1359             return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1360         } finally {
1361             if (result == null || result != StorageOperationStatus.OK) {
1362                 log.warn("operation failed. do rollback");
1363                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1364                 janusGraphDao.rollback();
1365             } else {
1366                 log.debug("operation success. do commit");
1367                 janusGraphDao.commit();
1368             }
1369             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1370         }
1371     }
1372
1373     public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1374         String ecompErrorContext = "Get service";
1375         validateUserNotEmpty(user, ecompErrorContext);
1376         validateUserExists(user);
1377         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1378         if (storageStatus.isRight()) {
1379             log.debug("failed to get service by id {}", serviceId);
1380             return Either.right(componentsUtils
1381                 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1382         }
1383         if (!(storageStatus.left().value() instanceof Service)) {
1384             return Either
1385                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1386         }
1387         Service service = storageStatus.left().value();
1388         return Either.left(service);
1389     }
1390
1391     public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1392         validateUserExists(userId);
1393         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade
1394             .getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1395         if (storageStatus.isRight()) {
1396             log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1397             return Either.right(componentsUtils
1398                 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE),
1399                     serviceName));
1400         }
1401         Service service = storageStatus.left().value();
1402         return Either.left(service);
1403     }
1404
1405     @SuppressWarnings("unchecked")
1406     private void createMandatoryArtifactsData(Service service, User user) {
1407         // create mandatory artifacts
1408
1409         // TODO it must be removed after that artifact uniqueId creation will be
1410
1411         // moved to ArtifactOperation
1412         String serviceUniqueId = service.getUniqueId();
1413         Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1414         if (artifactMap == null) {
1415             artifactMap = new HashMap<>();
1416         }
1417         Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1418             .getInformationalServiceArtifacts();
1419         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1420         String category = service.getCategories().get(0).getName();
1421         boolean isCreateArtifact = true;
1422         if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1423             for (String exlude : exludeServiceCategory) {
1424                 if (exlude.equalsIgnoreCase(category)) {
1425                     isCreateArtifact = false;
1426                     break;
1427                 }
1428             }
1429         }
1430         if (informationalServiceArtifacts != null && isCreateArtifact) {
1431             Set<String> keys = informationalServiceArtifacts.keySet();
1432             for (String informationalServiceArtifactName : keys) {
1433                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1434                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap,
1435                     user, false);
1436                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1437             }
1438             service.setArtifacts(artifactMap);
1439         }
1440     }
1441
1442     private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user,
1443                                                         Boolean isServiceApi) {
1444         ArtifactDefinition artifactInfo = artifactsBusinessLogic
1445             .createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1446         if (isServiceApi) {
1447             artifactInfo.setMandatory(false);
1448             artifactInfo.setServiceApi(true);
1449         }
1450         return artifactInfo;
1451     }
1452
1453     private String getEnvNameFromConfiguration() {
1454         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1455         log.trace("Update environment name to be {}", configuredEnvName);
1456         return configuredEnvName;
1457     }
1458
1459     public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier,
1460                                                                              ServiceDistributionReqInfo data) {
1461         Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation
1462             .validateActivateServiceRequest(serviceId, envId, modifier, data);
1463         if (activationRequestInformationEither.isRight()) {
1464             return Either.right(activationRequestInformationEither.right().value());
1465         }
1466         ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1467         String did = ThreadLocalsHolder.getUuid();
1468         Service service = activationRequestInformation.getServiceToActivate();
1469         return buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1470     }
1471
1472     private Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext,
1473                                                                            User modifier) {
1474         String envName = getEnvNameFromConfiguration();
1475         INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1476         ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1477         if (notifyServiceResponse == ActionStatus.OK) {
1478             return Either.left(did);
1479         } else {
1480             BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1481             log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1482             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1483             return Either.right(error);
1484         }
1485     }
1486
1487     public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1488         User user = validateUserExists(modifier.getUserId());
1489         validateUserRole(user, Collections.singletonList(Role.DESIGNER));
1490         Either<Service, ResponseFormat> result;
1491         ResponseFormat response;
1492         Service updatedService;
1493         String did = ThreadLocalsHolder.getUuid();
1494         // DE194021
1495         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1496         if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1497             log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1498             envName = configuredEnvName;
1499         }
1500         // DE194021
1501         ServletContext servletContext = request.getSession().getServletContext();
1502         boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1503         if (!isDistributionEngineUp) {
1504             BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1505             log.debug("Distribution Engine is DOWN");
1506             response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1507             return Either.right(response);
1508         }
1509         Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1510         if (serviceRes.isRight()) {
1511             log.debug("failed retrieving service");
1512             response = componentsUtils
1513                 .getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1514             componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1515                 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), did);
1516             return Either.right(response);
1517         }
1518         Service service = serviceRes.left().value();
1519         if (service.isArchived()) {
1520             log.info("Component is archived. Component id: {}", serviceId);
1521             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName()));
1522         }
1523         if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1524             log.info("service {} is  not available for distribution. Should be in certified state", service.getUniqueId());
1525             ResponseFormat responseFormat = componentsUtils
1526                 .getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1527             return Either.right(responseFormat);
1528         }
1529         String dcurrStatus = service.getDistributionStatus().name();
1530         String updatedStatus = dcurrStatus;
1531         StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1532         if (readyForDistribution == StorageOperationStatus.OK) {
1533             INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1534             ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1535             if (notifyServiceResponse == ActionStatus.OK) {
1536                 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user,
1537                     DistributionStatusEnum.DISTRIBUTED);
1538                 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1539                     updatedService = updateStateRes.left().value();
1540                     updatedStatus = updatedService.getDistributionStatus().name();
1541                 } else {
1542                     // The response is not relevant
1543                     updatedService = service;
1544                 }
1545                 ASDCKpiApi.countActivatedDistribution();
1546                 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1547                 result = Either.left(updatedService);
1548             } else {
1549                 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1550                 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1551                 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1552                 result = Either.right(response);
1553             }
1554         } else {
1555             response = componentsUtils
1556                 .getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution, ComponentTypeEnum.SERVICE), envName);
1557             result = Either.right(response);
1558         }
1559         componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1560             new ResourceCommonInfo(service.getName(), ComponentTypeEnum.SERVICE.getValue()),
1561             ResourceVersionInfo.newBuilder().distributionStatus(dcurrStatus).build(),
1562             ResourceVersionInfo.newBuilder().distributionStatus(updatedStatus).build(), null, null, did);
1563         return result;
1564     }
1565
1566     // convert to private after deletion of temp url
1567     public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1568         validateUserExists(user.getUserId());
1569         String serviceId = service.getUniqueId();
1570         lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1571         try {
1572             Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1573             if (result.isRight()) {
1574                 janusGraphDao.rollback();
1575                 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1576                 log.debug("service {}  change distribution status failed", serviceId);
1577                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1578             }
1579             janusGraphDao.commit();
1580             updateCatalog(service, ChangeTypeEnum.LIFECYCLE);
1581             return Either.left(result.left().value());
1582         } finally {
1583             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1584         }
1585     }
1586
1587     public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1588         validateUserExists(user.getUserId());
1589         log.debug("mark distribution deployed");
1590         AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1591         Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1592         if (getServiceResponse.isRight()) {
1593             BeEcompErrorManager.getInstance()
1594                 .logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1595             log.debug("service {} not found", serviceId);
1596             ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null,
1597                 componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1598             return Either.right(responseFormat);
1599         }
1600         Service service = getServiceResponse.left().value();
1601         user = validateRoleForDeploy(did, user, auditAction, service);
1602         return checkDistributionAndDeploy(did, user, auditAction, service);
1603     }
1604
1605     public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1606         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1607             // Only one VF Module Artifact per instance - add it to a list of one
1608             buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1609         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1610     }
1611
1612     private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock,
1613                                                                              boolean inTransaction, ComponentInstance ri) {
1614         List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1615         if (ri.getOriginType() == OriginTypeEnum.VF) {
1616             asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
1617         }
1618         return asList;
1619     }
1620
1621     private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
1622         Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1623         if (currVF.getGroupInstances() != null) {
1624             currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1625         }
1626         return currVF.getGroupInstances();
1627     }
1628
1629     private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper,
1630                                                                       Wrapper<ResponseFormat> responseWrapper) {
1631         ArtifactDefinition vfModuleAertifact = null;
1632         if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1633             final Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream()
1634                 .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType())).findAny();
1635             if (optionalVfModuleArtifact.isPresent()) {
1636                 vfModuleAertifact = optionalVfModuleArtifact.get();
1637             }
1638         }
1639         if (vfModuleAertifact == null) {
1640             Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service,
1641                 payloadWrapper.getInnerElement());
1642             if (createVfModuleArtifact.isLeft()) {
1643                 vfModuleAertifact = createVfModuleArtifact.left().value();
1644             } else {
1645                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1646             }
1647         }
1648         return vfModuleAertifact;
1649     }
1650
1651     private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1652         List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
1653         if (groupsForCurrVF != null) {
1654             for (GroupInstance groupInstance : groupsForCurrVF) {
1655                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1656                 vfModulePayloads.add(modulePayload);
1657             }
1658             vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
1659             final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1660             String vfModulePayloadString = gson.toJson(vfModulePayloads);
1661             payloadWrapper.setInnerElement(vfModulePayloadString);
1662         }
1663     }
1664
1665     private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance,
1666                                                                                         Service service, boolean shouldLock, boolean inTransaction) {
1667         ArtifactDefinition vfModuleArtifact = null;
1668         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1669         Wrapper<String> payloadWrapper = new Wrapper<>();
1670         List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
1671         if (responseWrapper.isEmpty()) {
1672             fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1673         }
1674         if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1675             vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
1676         }
1677         if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
1678             vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper,
1679                 responseWrapper, service);
1680         }
1681         Either<ArtifactDefinition, ResponseFormat> result;
1682         if (responseWrapper.isEmpty()) {
1683             result = Either.left(vfModuleArtifact);
1684         } else {
1685             result = Either.right(responseWrapper.getInnerElement());
1686         }
1687         return result;
1688     }
1689
1690     private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock,
1691                                                    boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper,
1692                                                    Service service) {
1693         ArtifactDefinition result = null;
1694         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic
1695             .generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock,
1696                 inTransaction, System::currentTimeMillis, () -> Either.left(
1697                     artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))),
1698                 currVF.getUniqueId());
1699         if (eitherPayload.isLeft()) {
1700             result = eitherPayload.left().value();
1701         } else {
1702             responseWrapper.setInnerElement(eitherPayload.right().value());
1703         }
1704         if (result == null) {
1705             result = vfModuleArtifact;
1706         }
1707         return result;
1708     }
1709
1710     private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service,
1711                                                                               String vfModulePayloadString) {
1712         ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
1713         String newCheckSum = null;
1714         vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
1715         vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
1716         vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
1717         vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
1718         vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
1719         vfModuleArtifactDefinition.setTimeout(0);
1720         vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
1721         vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
1722         if (vfModulePayloadString != null) {
1723             newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
1724         }
1725         vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
1726         Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation
1727             .addArtifactToComponent(vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
1728         Either<ArtifactDefinition, ResponseFormat> result;
1729         if (addArtifactToComponent.isLeft()) {
1730             result = Either.left(addArtifactToComponent.left().value());
1731         } else {
1732             result = Either
1733                 .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
1734         }
1735         return result;
1736     }
1737
1738     public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1739         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1740             // Get All Deployment Artifacts
1741             service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance)
1742                 .filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1743                 // Filter in Only Heat Env
1744                     filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1745                 // Create ArtifactGenerator from those Artifacts
1746                     map(
1747                     depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction,
1748                         resourceInstance.getUniqueId())).collect(Collectors.toList());
1749         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1750     }
1751
1752     private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service,
1753                                                                                   Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1754         // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1755
1756         // service
1757         if (service.getComponentInstances() != null) {
1758             List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream()
1759                 .flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1760             if (artifactGenList != null && !artifactGenList.isEmpty()) {
1761                 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
1762                 if (callRes != null) {
1763                     return callRes;
1764                 }
1765             }
1766         }
1767         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1768         if (storageStatus.isRight()) {
1769             return Either.right(componentsUtils
1770                 .getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1771         }
1772         Service currentService = storageStatus.left().value();
1773         return Either.left(currentService);
1774     }
1775
1776     private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
1777         for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1778             Either<CallVal, ResponseFormat> callRes;
1779             try {
1780                 callRes = entry.call();
1781                 if (callRes.isRight()) {
1782                     log.debug("Failed to generate artifact error : {}", callRes.right().value());
1783                     return Either.right(callRes.right().value());
1784                 }
1785             } catch (Exception e) {
1786                 log.debug("Failed to generate artifact exception : {}", e);
1787                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1788             }
1789         }
1790         return null;
1791     }
1792
1793     private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction,
1794                                                                                     Service service) {
1795         boolean isDeployed = isDistributionDeployed(distributionId);
1796         if (isDeployed) {
1797             return Either.left(service);
1798         }
1799         Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
1800         if (distributionSuccess.isRight()) {
1801             return Either.right(distributionSuccess.right().value());
1802         }
1803         log.debug("mark distribution {} as deployed - success", distributionId);
1804         componentsUtils
1805             .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK",
1806                 user);
1807         return Either.left(service);
1808     }
1809
1810     private boolean isDistributionDeployed(String distributionId) {
1811         Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao
1812             .getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1813         boolean isDeployed = false;
1814         if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1815             // already deployed
1816             log.debug("distribution {} is already deployed", distributionId);
1817             isDeployed = true;
1818         }
1819         return isDeployed;
1820     }
1821
1822     protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1823         log.trace("checkDistributionSuccess");
1824         // get all "DRequest" records for this distribution
1825         Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao
1826             .getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1827         if (distRequestsResponse.isRight()) {
1828             ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1829             return Either.right(error);
1830         }
1831         List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1832         if (distributionRequests.isEmpty()) {
1833             BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1834             log.info("distribution {} is not found", did);
1835             ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1836             return Either.right(error);
1837         }
1838         boolean isRequestSucceeded = false;
1839         for (ResourceAdminEvent event : distributionRequests) {
1840             String eventStatus = event.getStatus();
1841             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1842                 isRequestSucceeded = true;
1843                 break;
1844             }
1845         }
1846         // get all "DNotify" records for this distribution
1847         Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao
1848             .getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1849         if (distNotificationsResponse.isRight()) {
1850             ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1851             return Either.right(error);
1852         }
1853         List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1854         boolean isNotificationsSucceeded = false;
1855         for (DistributionNotificationEvent event : distributionNotifications) {
1856             String eventStatus = event.getStatus();
1857             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1858                 isNotificationsSucceeded = true;
1859                 break;
1860             }
1861         }
1862         // if request failed OR there are notifications that failed
1863         if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1864             log.info("distribution {} has failed", did);
1865             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1866             auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1867             return Either.right(error);
1868         }
1869         return Either.left(true);
1870     }
1871
1872     private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status,
1873                                             String... params) {
1874         ResponseFormat error = componentsUtils.getResponseFormat(status, params);
1875         String message = "";
1876         if (error.getMessageId() != null) {
1877             message = error.getMessageId() + ": ";
1878         }
1879         message += error.getFormattedMessage();
1880         if (service != null) {
1881             componentsUtils
1882                 .auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(),
1883                     message, user);
1884         } else {
1885             componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
1886         }
1887         return error;
1888     }
1889
1890     private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
1891         user = userAdmin.getUser(user.getUserId());
1892         log.debug("validate user role");
1893         List<Role> roles = new ArrayList<>();
1894         roles.add(Role.ADMIN);
1895         roles.add(Role.DESIGNER);
1896         try {
1897             validateUserRole(user, service, roles, auditAction, null);
1898         } catch (ByActionStatusComponentException e) {
1899             log.info("role {} is not allowed to perform this action", user.getRole());
1900             auditDeployError(did, user, auditAction, service, e.getActionStatus());
1901             throw e;
1902         }
1903         return user;
1904     }
1905
1906     @Override
1907     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
1908         if (component instanceof Service) {
1909             Service service = (Service) component;
1910             Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
1911             if (artifactMap == null) {
1912                 artifactMap = new HashMap<>();
1913             }
1914             service.setDeploymentArtifacts(artifactMap);
1915         } else if (component instanceof Resource) {
1916             Resource resource = (Resource) component;
1917             Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
1918             if (artifactMap == null) {
1919                 artifactMap = new HashMap<>();
1920             }
1921             Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration()
1922                 .getDeploymentResourceArtifacts();
1923             if (deploymentResourceArtifacts != null) {
1924                 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
1925                 deploymentResourceArtifacts.forEach((k, v) -> processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k, v));
1926             }
1927             resource.setDeploymentArtifacts(artifactMap);
1928         }
1929     }
1930
1931     private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
1932         Map<String, Object> artifactDetails = (Map<String, Object>) v;
1933         Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
1934         if (object != null) {
1935             List<String> artifactTypes = (List<String>) object;
1936             if (!artifactTypes.contains(resource.getResourceType().name())) {
1937                 return;
1938             }
1939         } else {
1940             log.info("resource types for artifact placeholder {} were not defined. default is all resources", k);
1941         }
1942         if (artifactsBusinessLogic != null) {
1943             ArtifactDefinition artifactDefinition = artifactsBusinessLogic
1944                 .createArtifactPlaceHolderInfo(resource.getUniqueId(), k, (Map<String, Object>) v, user, ArtifactGroupTypeEnum.DEPLOYMENT);
1945             if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
1946                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1947             }
1948         }
1949     }
1950
1951     @Override
1952     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
1953         return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
1954     }
1955
1956     private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
1957         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context
1958             .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
1959         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
1960         return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
1961     }
1962
1963     @Override
1964     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
1965         return componentInstanceBusinessLogic;
1966     }
1967
1968     @Override
1969     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
1970         validateUserExists(userId);
1971         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
1972         if (getComponentRes.isRight()) {
1973             ResponseFormat responseFormat = componentsUtils
1974                 .getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
1975             return Either.right(responseFormat);
1976         }
1977         List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
1978         return Either.left(componentInstances);
1979     }
1980
1981     @Autowired
1982     public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
1983         this.forwardingPathOperation = forwardingPathOperation;
1984     }
1985
1986     /**
1987      * updates group instance with new property values in case of successful update of group instance related component instance will be updated with
1988      * new modification time and related service will be updated with new last update date
1989      */
1990     public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId,
1991                                                                                                  String componentInstanceId, String groupInstanceId,
1992                                                                                                  List<GroupInstanceProperty> newProperties) {
1993         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
1994         Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
1995         Component component = null;
1996         Either<Boolean, ResponseFormat> lockResult = null;
1997         log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
1998         try {
1999             validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2000             if (validateUserAndComponentRes.isRight()) {
2001                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
2002                 actionResult = Either.right(validateUserAndComponentRes.right().value());
2003             }
2004             if (actionResult == null) {
2005                 component = validateUserAndComponentRes.left().value().getKey();
2006                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2007                 if (lockResult.isRight()) {
2008                     log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2009                     actionResult = Either.right(lockResult.right().value());
2010                 } else {
2011                     log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2012                 }
2013             }
2014             if (actionResult == null) {
2015                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId,
2016                     newProperties);
2017                 if (actionResult.isRight()) {
2018                     log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ",
2019                         groupInstanceId, actionResult.right().value().getFormattedMessage());
2020                 }
2021             }
2022         } catch (Exception e) {
2023             log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2024             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2025         } finally {
2026             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2027                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2028             }
2029         }
2030         return actionResult;
2031     }
2032
2033     private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component,
2034                                                                                                                                  String componentInstanceId,
2035                                                                                                                                  String groupInstanceId,
2036                                                                                                                                  List<GroupInstanceProperty> newProperties) {
2037         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2038         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2039         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2040         ComponentInstance relatedComponentInstance = null;
2041         GroupInstance oldGroupInstance = null;
2042         Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2043         GroupInstance updatedGroupInstance = null;
2044         boolean inTransaction = true;
2045         findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2046         if (findGroupInstanceRes.isRight()) {
2047             log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2048             actionResult = Either.right(findGroupInstanceRes.right().value());
2049         }
2050         if (actionResult == null) {
2051             oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2052             relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2053             updateGroupInstanceResult = groupBusinessLogic
2054                 .validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2055             if (updateGroupInstanceResult.isRight()) {
2056                 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ",
2057                     oldGroupInstance.getName());
2058                 actionResult = Either.right(updateGroupInstanceResult.right().value());
2059             }
2060         }
2061         if (actionResult == null) {
2062             updatedGroupInstance = updateGroupInstanceResult.left().value();
2063             if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2064                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance,
2065                     updatedGroupInstance, inTransaction);
2066                 if (updateParentsModificationTimeRes.isRight()) {
2067                     log.debug(
2068                         "#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ",
2069                         oldGroupInstance.getName());
2070                     actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2071                 }
2072             }
2073         }
2074         if (actionResult == null) {
2075             actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2076         }
2077         return actionResult;
2078     }
2079
2080     private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(
2081         Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance, boolean inTranscation) {
2082         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2083         Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2084         Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic
2085             .updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2086                 updatedGroupInstance.getModificationTime(), inTranscation);
2087         if (updateComponentInstanceRes.isRight()) {
2088             log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(),
2089                 updatedGroupInstance.getName());
2090             actionResult = Either.right(updateComponentInstanceRes.right().value());
2091         } else {
2092             serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2093             if (serviceMetadataUpdateResult.isRight()) {
2094                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ",
2095                     component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2096                 actionResult = Either.right(
2097                     componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2098             } else {
2099                 actionResult = Either
2100                     .left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2101             }
2102         }
2103         return actionResult;
2104     }
2105
2106     private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2107         Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2108         User currUser = null;
2109         Component component = null;
2110         Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2111         if (validationUserResult.isRight()) {
2112             log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2113             result = Either.right(validationUserResult.right().value());
2114         }
2115         if (result == null) {
2116             currUser = validationUserResult.left().value();
2117             try {
2118                 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2119                 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2120                     log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(),
2121                         component.getCreatorUserId());
2122                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2123                 }
2124             } catch (ComponentException e) {
2125                 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2126                 result = Either.right(e.getResponseFormat());
2127             }
2128         }
2129         if (result == null) {
2130             result = Either.left(new ImmutablePair<>(component, currUser));
2131         }
2132         return result;
2133     }
2134
2135     private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component,
2136                                                                                                                                 String componentInstanceId,
2137                                                                                                                                 String groupInstanceId) {
2138         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2139         GroupInstance groupInstance = null;
2140         ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2141         if (foundComponentInstance == null) {
2142             log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2143             actionResult = Either.right(componentsUtils
2144                 .getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service",
2145                     component.getName()));
2146         } else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2147             groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst()
2148                 .orElse(null);
2149             if (groupInstance == null) {
2150                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2151                 actionResult = Either.right(componentsUtils
2152                     .getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId,
2153                         foundComponentInstance.getName()));
2154             }
2155         }
2156         if (actionResult == null) {
2157             actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2158         }
2159         return actionResult;
2160     }
2161
2162     private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2163         ComponentInstance componentInstance = null;
2164         if (isNotEmpty(component.getComponentInstances())) {
2165             componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst()
2166                 .orElse(null);
2167         }
2168         return componentInstance;
2169     }
2170
2171     private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2172         User user = validateUser(modifier, ecompErrorContext, null, null, false);
2173         List<Role> roles = new ArrayList<>();
2174         roles.add(Role.ADMIN);
2175         roles.add(Role.DESIGNER);
2176         validateUserRole(user, roles);
2177         return Either.left(user);
2178     }
2179
2180     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId,
2181                                                                                                    List<String> dataParamsToReturn) {
2182         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2183         paramsToReturn.setIgnoreComponentInstancesProperties(false);
2184         Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2185         if (serviceResultEither.isRight()) {
2186             if (serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2187                 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2188                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2189             }
2190             log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2191             return Either.right(
2192                 componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2193         }
2194         Service service = serviceResultEither.left().value();
2195         if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2196             ListUtils.emptyIfNull(service.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
2197         }
2198         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2199         return Either.left(dataTransfer);
2200     }
2201
2202     @Autowired(required = false)
2203     public void setServiceCreationPluginList(List<ServiceCreationPlugin> serviceCreationPluginList) {
2204         this.serviceCreationPluginList = serviceCreationPluginList;
2205     }
2206
2207     public boolean isServiceExist(String serviceName) {
2208         Either<Service, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByServiceName(serviceName);
2209         return latestByName.isLeft();
2210     }
2211
2212     abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2213
2214     }
2215
2216     @Getter
2217     class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2218
2219         private ArtifactDefinition artifactDefinition;
2220         private Service service;
2221         private String resourceInstanceName;
2222         private User modifier;
2223         private String instanceId;
2224         private boolean shouldLock;
2225         private boolean inTransaction;
2226
2227         HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier,
2228                                  boolean shouldLock, boolean inTransaction, String instanceId) {
2229             this.artifactDefinition = artifactDefinition;
2230             this.service = service;
2231             this.resourceInstanceName = resourceInstanceName;
2232             this.modifier = modifier;
2233             this.shouldLock = shouldLock;
2234             this.instanceId = instanceId;
2235             this.inTransaction = inTransaction;
2236         }
2237
2238         @Override
2239         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2240             return artifactsBusinessLogic
2241                 .forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier,
2242                     shouldLock, inTransaction, instanceId);
2243         }
2244     }
2245
2246     class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2247
2248         boolean shouldLock;
2249         boolean inTransaction;
2250         private User user;
2251         private ComponentInstance componentInstance;
2252         private Service service;
2253
2254         private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock,
2255                                           boolean inTransaction) {
2256             super();
2257             this.user = user;
2258             this.componentInstance = componentInstance;
2259             this.service = service;
2260             this.shouldLock = shouldLock;
2261             this.inTransaction = inTransaction;
2262         }
2263
2264         @Override
2265         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2266             return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2267         }
2268     }
2269 }