Support Capability Properties
[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  */
20
21 package org.openecomp.sdc.be.components.impl;
22
23 import static org.apache.commons.collections.CollectionUtils.isEmpty;
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.utils.InterfacesOperationsToscaUtil.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
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.HashMap;
45 import java.util.List;
46 import java.util.Map;
47 import java.util.Objects;
48 import java.util.Optional;
49 import java.util.Set;
50 import java.util.concurrent.Callable;
51 import java.util.function.Function;
52 import java.util.stream.Collectors;
53
54 import fj.data.Either;
55 import org.apache.commons.collections.CollectionUtils;
56 import org.apache.commons.collections.MapUtils;
57 import org.apache.commons.collections4.ListUtils;
58 import org.apache.commons.lang3.StringUtils;
59 import org.apache.commons.lang3.tuple.ImmutablePair;
60 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
61 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
62 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
63 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
64 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
65 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
66 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
67 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
68 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
69 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
70 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
71 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
72 import org.openecomp.sdc.be.config.BeEcompErrorManager;
73 import org.openecomp.sdc.be.config.ConfigurationManager;
74 import org.openecomp.sdc.be.dao.api.ActionStatus;
75 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
76 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
77 import org.openecomp.sdc.be.datamodel.ServiceRelations;
78 import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil;
79 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
80 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
81 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
82 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
83 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
84 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
85 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
86 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
87 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
88 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
89 import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
90 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
91 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
92 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
93 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
94 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
95 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
96 import org.openecomp.sdc.be.model.ArtifactDefinition;
97 import org.openecomp.sdc.be.model.CapabilityDefinition;
98 import org.openecomp.sdc.be.model.Component;
99 import org.openecomp.sdc.be.model.ComponentInstance;
100 import org.openecomp.sdc.be.model.ComponentInstanceInterface;
101 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
102 import org.openecomp.sdc.be.model.ComponentParametersView;
103 import org.openecomp.sdc.be.model.DistributionStatusEnum;
104 import org.openecomp.sdc.be.model.DistributionTransitionEnum;
105 import org.openecomp.sdc.be.model.GroupInstance;
106 import org.openecomp.sdc.be.model.GroupInstanceProperty;
107 import org.openecomp.sdc.be.model.InputDefinition;
108 import org.openecomp.sdc.be.model.InterfaceDefinition;
109 import org.openecomp.sdc.be.model.LifecycleStateEnum;
110 import org.openecomp.sdc.be.model.Operation;
111 import org.openecomp.sdc.be.model.PropertyDefinition;
112 import org.openecomp.sdc.be.model.Resource;
113 import org.openecomp.sdc.be.model.Service;
114 import org.openecomp.sdc.be.model.User;
115 import org.openecomp.sdc.be.model.category.CategoryDefinition;
116 import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
117 import org.openecomp.sdc.be.model.jsontitan.operations.NodeFilterOperation;
118 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
119 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
120 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
121 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
122 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
123 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
124 import org.openecomp.sdc.be.model.tosca.ToscaFunctions;
125 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
126 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
127 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
128 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
129 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
130 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
131 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
132 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
133 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
134 import org.openecomp.sdc.be.types.ServiceConsumptionData;
135 import org.openecomp.sdc.be.types.ServiceConsumptionSource;
136 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
137 import org.openecomp.sdc.be.user.Role;
138 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
139 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
140 import org.openecomp.sdc.common.api.Constants;
141 import org.openecomp.sdc.common.datastructure.Wrapper;
142 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
143 import org.openecomp.sdc.common.log.wrappers.Logger;
144 import org.openecomp.sdc.common.util.GeneralUtility;
145 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
146 import org.openecomp.sdc.common.util.ValidationUtils;
147 import org.openecomp.sdc.exception.ResponseFormat;
148 import org.springframework.beans.factory.annotation.Autowired;
149 import org.springframework.http.HttpStatus;
150 import org.springframework.web.context.WebApplicationContext;
151
152 import javax.servlet.ServletContext;
153 import javax.servlet.http.HttpServletRequest;
154
155 @org.springframework.stereotype.Component("serviceBusinessLogic")
156 public class ServiceBusinessLogic extends ComponentBusinessLogic {
157
158     private static final String CHANGE_SERVICE_DISTRIBUTION = "Change Service Distribution";
159         private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
160         private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
161         private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
162         private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
163     private static final String INITIAL_VERSION = "0.1";
164     private static final String STATUS_SUCCESS_200 = "200";
165         private static final String STATUS_DEPLOYED = "DEPLOYED";
166     @Autowired
167     private IDistributionEngine distributionEngine;
168     @Autowired
169     private AuditCassandraDao auditCassandraDao;
170     @Autowired
171     private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
172     @Autowired
173     private ICacheMangerOperation cacheManagerOperation;
174     @Autowired
175     private ServiceDistributionValidation serviceDistributionValidation;
176
177     @Autowired
178     private ForwardingPathOperation forwardingPathOperation;
179     @Autowired
180     private ForwardingPathValidator forwardingPathValidator;
181     @Autowired
182     private UiComponentDataConverter uiComponentDataConverter;
183     @Autowired
184     private NodeFilterOperation serviceFilterOperation;
185     @Autowired
186     private NodeFilterValidator serviceFilterValidator;
187
188     public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
189
190         validateUserExists(user.getUserId(), "change Service Distribution State", false);
191
192         log.debug("check request state");
193         Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state);
194         if (validateEnum.isRight()) {
195             return Either.right(validateEnum.right().value());
196         }
197         DistributionTransitionEnum distributionTransition = validateEnum.left().value();
198         AuditingActionEnum auditAction = distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT;
199         Either<String, ResponseFormat> commentResponse = validateComment(commentObj);
200         if (commentResponse.isRight()) {
201             return Either.right(commentResponse.right().value());
202         }
203         String comment = commentResponse.left().value();
204
205         Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
206         if (validateService.isRight()) {
207             return Either.right(validateService.right().value());
208         }
209         Service service = validateService.left().value();
210         Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
211         if (validateUser.isRight()) {
212             return Either.right(validateUser.right().value());
213         }
214         user = validateUser.left().value();
215
216         // lock resource
217
218         Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
219         if (lockResult.isRight()) {
220             ResponseFormat responseFormat = lockResult.right().value();
221             createAudit(user, auditAction, comment, service, responseFormat);
222             return Either.right(responseFormat);
223         }
224
225         try {
226
227             DistributionStatusEnum newState;
228             if (distributionTransition == DistributionTransitionEnum.APPROVE) {
229                 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
230             } else {
231                 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
232             }
233             Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
234             if (result.isRight()) {
235                 titanDao.rollback();
236                 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
237                 log.debug("service {} is  change destribuation status failed", service.getUniqueId());
238                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
239                 createAudit(user, auditAction, comment, service, responseFormat);
240                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
241             }
242             titanDao.commit();
243             Service updatedService = result.left().value();
244             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
245             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
246             componentsUtils.auditComponent(responseFormat, user, updatedService, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), comment);
247             return Either.left(result.left().value());
248         } finally {
249             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
250         }
251
252     }
253
254     public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
255         validateUserExists(userId, "get Component Audit Records", false);
256         Either<List<Map<String, Object>>, ActionStatus> result;
257         try {
258
259             // Certified Version
260             if (componentVersion.endsWith(".0")) {
261                 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
262                 if (eitherAuditingForCertified.isLeft()) {
263                     result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
264                 } else {
265                     result = Either.right(eitherAuditingForCertified.right().value());
266                 }
267             }
268             // Uncertified Version
269             else {
270                 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
271             }
272         } catch (Exception e) {
273             log.debug("get Audit Records failed with exception {}", e);
274             result = Either.right(ActionStatus.GENERAL_ERROR);
275         }
276
277         if (result.isRight()) {
278             return Either.right(componentsUtils.getResponseFormat(result.right().value()));
279         } else {
280             return Either.left(result.left().value());
281         }
282
283     }
284
285     public Either<List<Operation>, ResponseFormat> addServiceConsumptionData(String serviceId,
286                                                                              String serviceInstanceId,
287                                                                              String operationId,
288                                                                              List<ServiceConsumptionData> serviceConsumptionDataList,
289                                                                              String userId) {
290         List<Operation> operationList = new ArrayList<>();
291
292         Either<Service, StorageOperationStatus> serviceEither =
293                 toscaOperationFacade.getToscaElement(serviceId);
294         if(serviceEither.isRight()) {
295             return Either.right(componentsUtils.getResponseFormat
296                     (serviceEither.right().value()));
297         }
298
299         Service service = serviceEither.left().value();
300
301
302         StorageOperationStatus storageOperationStatus =
303                 graphLockOperation.lockComponent(service.getUniqueId(), NodeTypeEnum.Service);
304         if (storageOperationStatus != StorageOperationStatus.OK) {
305             return Either.right(componentsUtils.getResponseFormat(storageOperationStatus));
306         }
307
308         try {
309             for (ServiceConsumptionData serviceConsumptionData : serviceConsumptionDataList) {
310                 Either<Operation, ResponseFormat> operationEither =
311                         addPropertyServiceConsumption(serviceId, serviceInstanceId, operationId,
312                                 userId, serviceConsumptionData);
313
314                 if (operationEither.isRight()) {
315                     return Either.right(operationEither.right().value());
316                 }
317
318                 operationList.add(operationEither.left().value());
319             }
320
321             titanDao.commit();
322             return Either.left(operationList);
323         } catch (Exception e) {
324             titanDao.rollback();
325             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
326
327         } finally {
328             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
329
330         }
331     }
332
333     public Either <Operation, ResponseFormat> addPropertyServiceConsumption(String serviceId,
334                                                                             String serviceInstanceId,
335                                                                             String operationId,
336                                                                             String userId,
337                                                                             ServiceConsumptionData serviceConsumptionData) {
338         validateUserExists(userId, "create Property", false);
339
340         Either<Service, StorageOperationStatus> serviceEither =
341                 toscaOperationFacade.getToscaElement(serviceId);
342         if(serviceEither.isRight()) {
343             return Either.right(componentsUtils.getResponseFormat(serviceEither.right
344                     ().value()));
345         }
346
347         Service parentService = serviceEither.left().value();
348
349         List<ComponentInstance> componentInstances = parentService.getComponentInstances();
350         if(CollectionUtils.isEmpty(componentInstances)) {
351             return Either.right(componentsUtils.getResponseFormat(ActionStatus
352                     .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
353         }
354
355         Optional<ComponentInstance> serviceInstanceCandidate =
356                 componentInstances.stream().filter(instance -> instance.getUniqueId().equals
357                         (serviceInstanceId)).findAny();
358
359         if(!serviceInstanceCandidate.isPresent()) {
360             return Either.right(componentsUtils.getResponseFormat(ActionStatus
361                     .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
362         }
363
364         Map<String, List<ComponentInstanceInterface>> componentInstancesInterfaces =
365                 parentService.getComponentInstancesInterfaces();
366         if(MapUtils.isEmpty(componentInstancesInterfaces)) {
367             return Either.right(componentsUtils.getResponseFormat(ActionStatus
368                     .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
369         }
370
371         List<InterfaceDefinition> interfaces = new ArrayList<>();
372         for(ComponentInstanceInterface componentInstanceInterface :
373                 componentInstancesInterfaces.get(serviceInstanceId)) {
374             interfaces.add(componentInstanceInterface);
375         }
376
377         ComponentInstance serviceInstance = serviceInstanceCandidate.get();
378         Optional<InterfaceDefinition> interfaceCandidate = InterfaceOperationUtils
379                 .getInterfaceDefinitionFromOperationId(interfaces, operationId);
380
381         if(!interfaceCandidate.isPresent()) {
382             return Either.right(componentsUtils.getResponseFormat(ActionStatus
383                     .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
384         }
385
386         InterfaceDefinition interfaceDefinition = interfaceCandidate.get();
387         Map<String, Operation> operations = interfaceDefinition.getOperationsMap();
388         if(MapUtils.isEmpty(operations)) {
389             return Either.right(componentsUtils.getResponseFormat(ActionStatus
390                     .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
391         }
392
393         Operation operation = operations.get(operationId);
394         Either<Operation, ResponseFormat> operationEither = Either.left(operation);
395
396         ListDataDefinition<OperationInputDefinition> inputs = operation.getInputs();
397         Optional<OperationInputDefinition> inputCandidate =
398                 getOperationInputByInputId(serviceConsumptionData, inputs);
399
400         if(!inputCandidate.isPresent()) {
401             return Either.right(new ResponseFormat(HttpStatus.NOT_FOUND.value()));
402         }
403
404         OperationInputDefinition operationInputDefinition = inputCandidate.get();
405         // add data to operation
406
407         if(Objects.nonNull(serviceConsumptionData.getValue()))  {
408             operationEither =
409                     handleConsumptionValue(parentService, serviceInstanceId, serviceConsumptionData, operation,
410                             operationInputDefinition);
411         }
412
413         if(operationEither.isRight()) {
414             return Either.right(operationEither.right().value());
415         }
416
417         Operation updatedOperation = operationEither.left().value();
418         operations.remove(operationId);
419         operations.put(operationId, updatedOperation);
420         interfaceDefinition.setOperationsMap(operations);
421
422         parentService.getComponentInstances().remove(serviceInstance);
423         if(CollectionUtils.isEmpty(parentService.getComponentInstances())) {
424             parentService.setComponentInstances(new ArrayList<>());
425         }
426
427         Map<String, Object> instanceInterfaces =
428                 MapUtils.isEmpty(serviceInstance.getInterfaces())? new HashMap<>() : serviceInstance.getInterfaces();
429         instanceInterfaces.remove(interfaceDefinition.getUniqueId());
430         instanceInterfaces.put(interfaceDefinition.getUniqueId(), interfaceDefinition);
431         serviceInstance.setInterfaces(instanceInterfaces);
432
433         removeComponentInstanceInterfaceByInterfaceId(interfaceDefinition.getUniqueId(), componentInstancesInterfaces.get(serviceInstanceId));
434         componentInstancesInterfaces.get(serviceInstanceId).add(new ComponentInstanceInterface(interfaceDefinition.getUniqueId(), interfaceDefinition));
435
436         parentService.getComponentInstances().add(serviceInstance);
437
438         StorageOperationStatus status = toscaOperationFacade.updateComponentInstanceInterfaces(parentService, serviceInstanceId);
439
440         if(status != StorageOperationStatus.OK) {
441             return Either.right(componentsUtils.getResponseFormat(ActionStatus
442                     .INTERFACE_OPERATION_NOT_FOUND, serviceInstanceId));
443         }
444
445         return Either.left(operation);
446     }
447
448     private void removeComponentInstanceInterfaceByInterfaceId(String interfaceIdToRemove,
449                                                                List<ComponentInstanceInterface> instanceInterfaces) {
450         if(CollectionUtils.isEmpty(instanceInterfaces)) {
451             return;
452         }
453
454         Optional<ComponentInstanceInterface> interfaceToRemove =
455                 instanceInterfaces.stream().filter(instInterface -> instInterface.getUniqueId().equals
456                         (interfaceIdToRemove)).findAny();
457
458         if(interfaceToRemove.isPresent()) {
459             instanceInterfaces.remove(interfaceToRemove.get());
460         }
461
462     }
463
464     private Either<Operation, ResponseFormat> handleConsumptionValue(Service containerService,
465                                                                      String serviceInstanceId,
466                                                                      ServiceConsumptionData serviceConsumptionData,
467                                                                      Operation operation,
468                                                                      OperationInputDefinition
469                                                                              operationInputDefinition) {
470         String source = serviceConsumptionData.getSource();
471         String consumptionValue = serviceConsumptionData.getValue();
472         String type = serviceConsumptionData.getType();
473         String operationIdentifier = consumptionValue.contains(".")
474                 ? consumptionValue.substring(0, consumptionValue.lastIndexOf('.'))
475                 : consumptionValue;
476
477         ServiceConsumptionSource sourceValue = ServiceConsumptionSource.getSourceValue(source);
478
479         if(STATIC.equals(sourceValue)) {
480             // Validate constraint on input value
481             Either<Boolean, ResponseFormat> constraintValidationResult =
482                     validateOperationInputConstraint(operationInputDefinition, consumptionValue, type);
483
484             if (constraintValidationResult.isRight()) {
485                 return Either.right(constraintValidationResult.right().value());
486             }
487             return handleConsumptionStaticValue(consumptionValue, type, operation,
488                     operationInputDefinition);
489         }
490
491         if (Objects.isNull(sourceValue)) {
492             List<PropertyDefinition> propertyDefinitions;
493             Map<String, List<CapabilityDefinition>> capabilities = null;
494             String componentName;
495             List<OperationOutputDefinition> outputs = null;
496             if (source.equals(containerService.getUniqueId())) {
497                 Either<Service, StorageOperationStatus> serviceToTakePropEither =
498                         toscaOperationFacade.getToscaElement(source);
499                 if (serviceToTakePropEither.isRight()) {
500                     return Either.right(componentsUtils.getResponseFormat(serviceToTakePropEither.right().value()));
501                 }
502                 Service service = serviceToTakePropEither.left().value();
503                 operationInputDefinition.setSource(service.getUniqueId());
504                 sourceValue = SERVICE_INPUT;
505                 propertyDefinitions = service.getProperties();
506                 componentName = service.getName();
507                 outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
508                         service.getInterfaces()).getListToscaDataDefinition();
509             } else {
510                 Optional<ComponentInstance> getComponentInstance = containerService.getComponentInstanceById(source);
511                 if(!getComponentInstance.isPresent()){
512                     return Either.right(componentsUtils.getResponseFormat(
513                             ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, source));
514                 }
515                 ComponentInstance componentInstance = getComponentInstance.get();
516                 operationInputDefinition.setSource(componentInstance.getUniqueId());
517                 propertyDefinitions = componentInstance.getProperties();
518                 capabilities = componentInstance.getCapabilities();
519                 componentName = source.equals(serviceInstanceId) ? SELF : componentInstance.getName();
520                 if (MapUtils.isNotEmpty(componentInstance.getInterfaces())) {
521                     Map<String, InterfaceDataDefinition> componentInstanceInterfaces =
522                             componentInstance.getInterfaces().entrySet().stream()
523                                     .collect(Collectors.toMap((Map.Entry::getKey),
524                                             (interfaceEntry -> (InterfaceDataDefinition) interfaceEntry.getValue())));
525                     outputs = InterfaceOperationUtils.getOtherOperationOutputsOfComponent(operationIdentifier,
526                             componentInstanceInterfaces).getListToscaDataDefinition();
527                 }
528             }
529
530             if(sourceValue == ServiceConsumptionSource.SERVICE_INPUT) {
531                 //The operation input in service consumption has been mapped to an input in the parent service
532                 return handleConsumptionInputValue(consumptionValue, containerService, operation,
533                         operationInputDefinition);
534             }
535             return handleConsumptionPropertyValue(operation, operationInputDefinition,
536                     serviceConsumptionData, propertyDefinitions, capabilities, outputs, componentName);
537         }
538
539         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.SOURCE, source);
540         operationInputDefinition.setSource(source);
541
542         return Either.left(operation);
543     }
544
545     private Optional<OperationInputDefinition> getOperationInputByInputId(ServiceConsumptionData serviceConsumptionData,
546                                                                           ListDataDefinition<OperationInputDefinition> inputs) {
547
548         if(CollectionUtils.isEmpty(inputs.getListToscaDataDefinition())) {
549             return Optional.empty();
550         }
551
552         return inputs.getListToscaDataDefinition().stream().filter(operationInput -> operationInput.getInputId().equals
553                 (serviceConsumptionData.getInputId()))
554                 .findAny();
555     }
556
557     private Either<Operation, ResponseFormat> handleConsumptionPropertyValue(
558             Operation operation, OperationInputDefinition operationInputDefinition,
559             ServiceConsumptionData serviceConsumptionData, List<PropertyDefinition> properties,Map<String,
560             List<CapabilityDefinition>> capabilities,
561             List<OperationOutputDefinition> outputs,  String componentName) {
562
563         if (CollectionUtils.isEmpty(properties) && CollectionUtils.isEmpty(outputs)) {
564             return Either.left(operation);
565         }
566         String consumptionValue = serviceConsumptionData.getValue();
567
568         if (CollectionUtils.isNotEmpty(outputs)
569                 && isOperationInputMappedToOtherOperationOutput(getOperationOutputName(consumptionValue), outputs)) {
570             return handleConsumptionInputMappedToOperationOutput(operation, operationInputDefinition, outputs,
571                     consumptionValue, componentName);
572         }
573
574         if (CollectionUtils.isNotEmpty(properties) && PropertiesUtils.isNodeProperty(consumptionValue, properties)) {
575             return handleConsumptionInputMappedToProperty(operation, operationInputDefinition, serviceConsumptionData,
576                     properties, componentName);
577         }
578
579         if (MapUtils.isNotEmpty(capabilities)) {
580             return handleConsumptionInputMappedToCapabilityProperty(operation, operationInputDefinition,
581                     serviceConsumptionData, capabilities, componentName);
582         }
583
584         return Either.left(operation);
585     }
586
587     private Either<Operation, ResponseFormat> handleConsumptionInputMappedToProperty(Operation operation,
588                                                                                      OperationInputDefinition operationInputDefinition, ServiceConsumptionData serviceConsumptionData,
589                                                                                      List<PropertyDefinition> properties, String componentName) {
590         Optional<PropertyDefinition> servicePropertyCandidate =
591                 properties.stream().filter(property -> property.getName()
592                         .equals(serviceConsumptionData.getValue())).findAny();
593
594         if (servicePropertyCandidate.isPresent()) {
595             boolean isInputTypeSimilarToOperation =
596                     isAssignedValueFromValidType(operationInputDefinition.getType(),
597                             servicePropertyCandidate.get());
598
599             if (!isInputTypeSimilarToOperation) {
600                 return Either.right(componentsUtils.getResponseFormat(
601                         ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
602             }
603
604             addPropertyToInputValue(componentName, operation, operationInputDefinition,
605                     servicePropertyCandidate.get());
606         }
607         return Either.left(operation);
608     }
609
610     private Either<Operation, ResponseFormat> handleConsumptionInputMappedToOperationOutput(Operation operation,
611                                                                                             OperationInputDefinition operationInputDefinition, List<OperationOutputDefinition> outputs,
612                                                                                             String consumptionValue, String componentName) {
613         String outputName = getOperationOutputName(consumptionValue);
614         Optional<OperationOutputDefinition> servicePropertyOutputCandidate = outputs.stream()
615                 .filter(output -> output.getName().equals(outputName)).findAny();
616         if (servicePropertyOutputCandidate.isPresent()) {
617             boolean isInputTypeSimilarToOperation =
618                     isAssignedValueFromValidType(operationInputDefinition.getType(),
619                             servicePropertyOutputCandidate.get());
620             if (!isInputTypeSimilarToOperation) {
621                 return Either.right(componentsUtils.getResponseFormat(
622                         ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
623             }
624             addOutputToInputValue(componentName, consumptionValue, operation, operationInputDefinition);
625         }
626         return Either.left(operation);
627     }
628
629     private void addPropertyToInputValue(String componentName, Operation operation,
630                                          OperationInputDefinition operationInputDefinition,
631                                          PropertyDefinition serviceProperty) {
632         Map<String, List<String>> getProperty = new HashMap<>();
633         List<String> getPropertyValues = new ArrayList<>();
634         getPropertyValues.add(componentName);
635         getPropertyValues.add(serviceProperty.getName());
636         getProperty.put(ToscaFunctions.GET_PROPERTY.getFunctionName(), getPropertyValues);
637
638         operationInputDefinition.setSourceProperty(serviceProperty.getUniqueId());
639         operation.getInputs().delete(operationInputDefinition);
640         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_PROPERTY,
641                 getPropertyValues);
642         operationInputDefinition.setValue((new Gson()).toJson(getProperty));
643         operation.getInputs().add(operationInputDefinition);
644     }
645
646     private void addOutputToInputValue(String componentName, String consumptionValue,
647                                        Operation operation, OperationInputDefinition operationInputDefinition) {
648         Map<String, List<String>> getOperationOutput =
649                 InterfaceOperationUtils.createMappedOutputDefaultValue(componentName, consumptionValue);
650         operation.getInputs().delete(operationInputDefinition);
651         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_OPERATION_OUTPUT,
652                 getOperationOutput);
653         operationInputDefinition.setValue((new Gson()).toJson(getOperationOutput));
654         operation.getInputs().add(operationInputDefinition);
655     }
656
657     public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type,
658                                                                           Operation operation,
659                                                                           OperationInputDefinition
660                                                                                   operationInputDefinition) {
661         boolean isInputTypeSimilarToOperation =
662                 isAssignedValueFromValidType(type, value);
663
664         if(!isInputTypeSimilarToOperation) {
665             return Either.right(componentsUtils.getResponseFormat(
666                     ActionStatus.INVALID_CONSUMPTION_TYPE, type));
667         }
668
669                 //Validate Constraint and Value
670                 Either<Boolean, ResponseFormat> constraintValidationResponse =
671                                 validateOperationInputConstraint(operationInputDefinition, value, type);
672                 if(constraintValidationResponse.isRight()) {
673                         return Either.right(constraintValidationResponse.right().value());
674                 }
675
676         addStaticValueToInputOperation(value, operation, operationInputDefinition);
677
678         return Either.left(operation);
679     }
680
681         private Either<Boolean, ResponseFormat> validateOperationInputConstraint(
682                         OperationInputDefinition operationInputDefinition, String value, String type) {
683
684                 if (Objects.nonNull(operationInputDefinition.getParentPropertyType())
685                                 && !operationInputDefinition.getParentPropertyType().equals(operationInputDefinition.getType())) {
686                         InputDefinition inputDefinition = new InputDefinition();
687                         inputDefinition.setDefaultValue(value);
688                         inputDefinition.setInputPath(operationInputDefinition.getSubPropertyInputPath());
689                         inputDefinition.setName(operationInputDefinition.getName());
690                         inputDefinition.setType(type);
691
692                         ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
693                         propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
694             if (operationInputDefinition.getParentPropertyType() != null) {
695                 inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
696             }
697
698                         return PropertyValueConstraintValidationUtil.getInstance()
699                                         .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
700                 } else {
701                         PropertyDefinition propertyDefinition = new PropertyDefinition();
702                         propertyDefinition.setType(operationInputDefinition.getType());
703                         propertyDefinition.setValue(value);
704                         propertyDefinition.setName(operationInputDefinition.getName());
705
706                         return PropertyValueConstraintValidationUtil.getInstance()
707                                         .validatePropertyConstraints(Collections.singletonList(propertyDefinition), applicationDataTypeCache);
708                 }
709         }
710
711         private void addStaticValueToInputOperation(String value, Operation operation,
712                                                 OperationInputDefinition operationInputDefinition) {
713         operation.getInputs().delete(operationInputDefinition);
714         operationInputDefinition.setSource(STATIC.getSource());
715         operationInputDefinition.setSourceProperty(null);
716         operationInputDefinition.setValue(value);
717         operation.getInputs().add(operationInputDefinition);
718     }
719
720     private Either<Operation, ResponseFormat>  handleConsumptionInputValue(String inputId,
721                                                                            Service service,
722                                                                            Operation operation,
723                                                                            OperationInputDefinition
724                                                                                    operationInputDefinition) {
725         List<InputDefinition> serviceInputs = service.getInputs();
726         Optional<InputDefinition> inputForValue =
727                 serviceInputs.stream().filter(input -> input.getUniqueId().contains(inputId)).findAny();
728
729         if(inputForValue.isPresent()) {
730             boolean isInputTypeSimilarToOperation =
731                     isAssignedValueFromValidType(operationInputDefinition.getType(), inputForValue.get());
732
733             if(!isInputTypeSimilarToOperation) {
734                 return Either.right(componentsUtils.getResponseFormat(
735                         ActionStatus.INVALID_CONSUMPTION_TYPE, operationInputDefinition.getType()));
736             }
737             addGetInputValueToOperationInput(operation, operationInputDefinition, inputForValue.get());
738         }
739
740         return Either.left(operation);
741     }
742
743     private void addGetInputValueToOperationInput(Operation operation,
744                                                   OperationInputDefinition operationInputDefinition,
745                                                   InputDefinition inputForValue) {
746         operation.getInputs().delete(operationInputDefinition);
747         Map<String, String> getInputMap = new HashMap<>();
748         getInputMap.put(ToscaFunctions.GET_INPUT.getFunctionName(), inputForValue.getName());
749         operationInputDefinition.setSourceProperty(inputForValue.getUniqueId());
750         operationInputDefinition.setToscaPresentationValue(JsonPresentationFields.GET_INPUT, getInputMap);
751         operationInputDefinition.setValue(new Gson().toJson(getInputMap));
752         operation.getInputs().add(operationInputDefinition);
753     }
754
755     private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
756         // First Query
757         Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
758
759         if (eitherprevVerAudit.isRight()) {
760             return Either.right(eitherprevVerAudit.right().value());
761         }
762
763         // Second Query
764         Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
765         if (eitherCurrVerAudit.isRight()) {
766             return Either.right(eitherCurrVerAudit.right().value());
767         }
768
769
770         Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
771         if (eitherArchiveRestoreList.isRight()) {
772             return Either.right(eitherArchiveRestoreList.right().value());
773         }
774
775         List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
776         List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
777
778         List<Map<String, Object>> duplicateElements = new ArrayList<>();
779         duplicateElements.addAll(prevVerAuditList);
780         duplicateElements.retainAll(currVerAuditList);
781
782         List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
783         joinedNonDuplicatedList.addAll(prevVerAuditList);
784         joinedNonDuplicatedList.removeAll(duplicateElements);
785         joinedNonDuplicatedList.addAll(currVerAuditList);
786         joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
787
788
789         return Either.left(joinedNonDuplicatedList);
790     }
791
792     private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
793         // Archive Query
794         Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
795         if (eitherArchiveAudit.isRight()) {
796             return Either.right(eitherArchiveAudit.right().value());
797         }
798
799         // Restore Query
800         Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
801         if (eitherRestoreAudit.isRight()) {
802             return Either.right(eitherRestoreAudit.right().value());
803         }
804
805         List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
806         archiveAudit.addAll(eitherArchiveAudit.left().value());
807         archiveAudit.addAll(eitherRestoreAudit.left().value());
808
809         return Either.left(archiveAudit);
810     }
811
812     private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
813
814         List<Map<String, Object>> prevVerAudit = new ArrayList<>();
815         for (AuditingGenericEvent auditEvent : prevVerAuditList) {
816             auditEvent.fillFields();
817             prevVerAudit.add(auditEvent.getFields());
818         }
819         return prevVerAudit;
820     }
821
822     /**
823      * createService
824      *
825      * @param service
826      *            - Service
827      * @param user
828      *            - modifier data (userId)
829      * @return Either<Service, responseFormat>
830      */
831     public Either<Service, ResponseFormat> createService(Service service, User user) {
832
833         // get user details
834         user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
835         // validate user role
836         validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
837         service.setCreatorUserId(user.getUserId());
838         // warn on overridden fields
839         checkFieldsForOverideAttampt(service);
840         // enrich object
841         log.debug("enrich service with version and state");
842         service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
843         service.setVersion(INITIAL_VERSION);
844         service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
845         service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
846
847         Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
848         if (createServiceResponse.isRight()) {
849             return createServiceResponse;
850         }
851         return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
852     }
853
854     private void checkFieldsForOverideAttampt(Service service) {
855         checkComponentFieldsForOverrideAttempt(service);
856         if (service.getDistributionStatus() != null) {
857             log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
858         }
859     }
860
861     private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
862         log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
863
864         Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
865         if (lockResult.isRight()) {
866             ResponseFormat responseFormat = lockResult.right().value();
867             componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
868             return Either.right(responseFormat);
869         }
870
871         log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
872
873         try {
874
875             createMandatoryArtifactsData(service, user);
876             createServiceApiArtifactsData(service, user);
877             setToscaArtifactsPlaceHolders(service, user);
878             generateAndAddInputsFromGenericTypeProperties(service, fetchAndSetDerivedFromGenericType(service));
879
880             Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
881
882             // service created successfully!!!
883             if (dataModelResponse.isLeft()) {
884                 log.debug("Service created successfully!!!");
885                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
886                 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
887                 ASDCKpiApi.countCreatedServicesKPI();
888                 return Either.left(dataModelResponse.left().value());
889             }
890
891             ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
892             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
893             componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
894             return Either.right(responseFormat);
895
896         } finally {
897             graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
898         }
899     }
900
901     @SuppressWarnings("unchecked")
902     private void createServiceApiArtifactsData(Service service, User user) {
903         // create mandatory artifacts
904
905         // TODO it must be removed after that artifact uniqueId creation will be
906         // moved to ArtifactOperation
907         String serviceUniqueId = service.getUniqueId();
908         Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
909         if (artifactMap == null)
910             artifactMap = new HashMap<>();
911
912         Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
913         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
914
915         List<CategoryDefinition> categories = service.getCategories();
916         boolean isCreateArtifact = true;
917         if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
918             for (String exlude : exludeServiceCategory) {
919                 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
920                     isCreateArtifact = false;
921                     break;
922                 }
923             }
924
925         }
926
927         if (serviceApiArtifacts != null && isCreateArtifact) {
928             Set<String> keys = serviceApiArtifacts.keySet();
929             for (String serviceApiArtifactName : keys) {
930                 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
931                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
932                 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
933                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
934             }
935
936             service.setServiceApiArtifacts(artifactMap);
937         }
938     }
939
940     private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
941
942         Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
943         if (validationResponse.isRight()) {
944             return Either.right(validationResponse.right().value());
945         }
946         service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
947         service.setContactId(service.getContactId().toLowerCase());
948
949         // Generate invariant UUID - must be here and not in operation since it
950         // should stay constant during clone
951         String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
952         service.setInvariantUUID(invariantUUID);
953
954         return Either.left(service);
955     }
956
957
958
959     private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
960         try {
961             validateComponentFieldsBeforeCreate(user, service, actionEnum);
962
963             Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
964             if (serviceNameUniquenessValidation.isRight()) {
965                 throw new ComponentException(serviceNameUniquenessValidation.right().value());
966             }
967             Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
968             if (categoryValidation.isRight()) {
969                 return categoryValidation;
970             }
971             Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
972             if (projectCodeValidation.isRight()) {
973                 return projectCodeValidation;
974             }
975             validateServiceTypeAndCleanup(service);
976
977             Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
978             if (serviceRoleValidation.isRight()) {
979                 return serviceRoleValidation;
980             }
981             return validateInstantiationTypeValue(user, service, actionEnum);
982         } catch (ComponentException exception) {
983             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
984             componentsUtils.auditComponentAdmin(responseFormat, user, service,
985                     AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
986             return Either.right(responseFormat);
987         }
988     }
989
990     private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
991         log.debug("validate Service category");
992         if (isEmpty(service.getCategories())) {
993             ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
994             componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
995             return Either.right(errorResponse);
996         }
997         Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
998         if (validatCategory.isRight()) {
999             ResponseFormat responseFormat = validatCategory.right().value();
1000             componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1001             return Either.right(responseFormat);
1002         }
1003         return Either.left(true);
1004     }
1005
1006     public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
1007         validateUserExists(userId, "validate Service Name Exists", false);
1008
1009         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
1010         // DE242223
1011         titanDao.commit();
1012
1013         if (dataModelResponse.isLeft()) {
1014             Map<String, Boolean> result = new HashMap<>();
1015             result.put("isValid", dataModelResponse.left().value());
1016             log.debug("validation was successfully performed.");
1017             return Either.left(result);
1018         }
1019         ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
1020         return Either.right(responseFormat);
1021     }
1022
1023     public void setElementDao(IElementOperation elementDao) {
1024         this.elementDao = elementDao;
1025     }
1026
1027     public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
1028         this.auditCassandraDao = auditingDao;
1029     }
1030
1031     public ArtifactsBusinessLogic getArtifactBl() {
1032         return artifactsBusinessLogic;
1033     }
1034
1035     public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
1036         this.artifactsBusinessLogic = artifactBl;
1037     }
1038
1039     public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
1040         user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
1041         // validate user role
1042         validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1043
1044         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1045         if (storageStatus.isRight()) {
1046             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1047         }
1048
1049         Service currentService = storageStatus.left().value();
1050
1051         if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
1052             log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
1053             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1054         }
1055
1056         Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
1057         if (validationRsponse.isRight()) {
1058             log.info("service update metadata: validations field.");
1059             return validationRsponse;
1060         }
1061         Service serviceToUpdate = validationRsponse.left().value();
1062         // lock resource
1063
1064         Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
1065         if (lockResult.isRight()) {
1066             return Either.right(lockResult.right().value());
1067         }
1068         try {
1069             Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
1070             if (updateResponse.isRight()) {
1071                 titanDao.rollback();
1072                 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
1073                 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
1074                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1075             }
1076             titanDao.commit();
1077             return Either.left(updateResponse.left().value());
1078         } finally {
1079             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1080         }
1081     }
1082
1083     public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
1084         Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
1085         user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
1086         // validate user role
1087         validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
1088         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1089         if (storageStatus.isRight()) {
1090             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1091         }
1092         Service service = storageStatus.left().value();
1093         Either<Set<String>, StorageOperationStatus> result = null;
1094         if (lock) {
1095             Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
1096             if (lockResult.isRight()) {
1097                 titanDao.rollback();
1098                 return Either.right(componentsUtils.getResponseFormat(componentsUtils
1099                     .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1100             }
1101         }
1102         try{
1103             result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
1104             if (result.isRight()) {
1105                 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
1106                 titanDao.rollback();
1107                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
1108             }
1109             titanDao.commit();
1110             log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
1111
1112         } catch (Exception e){
1113             log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
1114             titanDao.rollback();
1115             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1116         } finally {
1117               graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1118         }
1119         return Either.left(result.left().value());
1120     }
1121
1122     private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
1123         Service serviceToDelete = new Service();
1124         serviceToDelete.setUniqueId(serviceId);
1125         serviceToDelete.setForwardingPaths(new HashMap<>());
1126         pathIdsToDelete.forEach(pathIdToDelete ->  serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
1127         return serviceToDelete;
1128     }
1129
1130     public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1131         return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
1132     }
1133
1134     public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1135         return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
1136     }
1137
1138     private ForwardingPathDataDefinition  getTrimmedValues(ForwardingPathDataDefinition path){
1139         ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
1140         dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
1141         dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
1142         dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
1143         dataDefinition.setUniqueId(path.getUniqueId());
1144         dataDefinition.setPathElements(path.getPathElements());
1145         dataDefinition.setDescription(path.getDescription());
1146         dataDefinition.setToscaResourceName(path.getToscaResourceName());
1147         return  dataDefinition;
1148     }
1149
1150     private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
1151         validateUserAndRole(serviceUpdate, user, errorContext);
1152
1153         Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
1154
1155         Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
1156                 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
1157                         entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
1158
1159         Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
1160                 serviceId, isUpdate);
1161         if(booleanResponseFormatEither.isRight()){
1162             return Either.right(booleanResponseFormatEither.right().value());
1163         }
1164
1165         Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
1166
1167         if(serviceStorageOperationStatusEither.isRight()){
1168             StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
1169             log.debug("Failed to fetch service information by service id, error {}", errorStatus);
1170             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1171         }
1172         Service storedService = serviceStorageOperationStatusEither.left().value();
1173
1174         Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1175         Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
1176         if (forwardingPathOrigin.isRight()) {
1177             StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1178             log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1179             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
1180         }
1181         Component component = forwardingPathOrigin.left().value();
1182         final String toscaResourceName;
1183         if (  component.getComponentType() == ComponentTypeEnum.RESOURCE) {
1184             toscaResourceName = ((Resource) component).getToscaResourceName();
1185         } else {
1186             toscaResourceName = "";
1187         }
1188         Either<Boolean, ResponseFormat> lockResult = null;
1189         if (lock) {
1190             lockResult =
1191                 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
1192             if (lockResult.isRight()) {
1193                 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, storedService.getName(),
1194                     lockResult.right().value().getFormattedMessage());
1195                 return Either.right(lockResult.right().value());
1196             } else {
1197                 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1198             }
1199         }
1200         Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1201         try {
1202             trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1203
1204             try {
1205                 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1206                     if (isUpdate) {
1207                         result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1208                     } else {
1209                         result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1210                     }
1211                     if (result.isRight()) {
1212                         titanDao.rollback();
1213                         return Either.right(componentsUtils.getResponseFormat(
1214                             componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
1215                             ""));
1216                     } else {
1217                         ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1218                         resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1219                     }
1220                 }
1221
1222             } catch (Exception e) {
1223                 titanDao.rollback();
1224                 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
1225                     e);
1226                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1227             }
1228             titanDao.commit();
1229         } finally {
1230             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1231                 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1232             }
1233         }
1234         Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
1235         return Either.left(service);
1236     }
1237
1238     private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1239         Service service = new Service();
1240         service.setUniqueId(serviceId);
1241         service.setForwardingPaths(forwardingPathDataDefinitionMap);
1242         return service;
1243     }
1244
1245     private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1246         user = validateUser(user, errorContext, serviceUpdate, null, false);
1247         validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1248
1249     }
1250
1251     @VisibleForTesting
1252     Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1253
1254         try {
1255             boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1256             Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1257             if (response.isRight()) {
1258                 ResponseFormat errorResponse = response.right().value();
1259                 return Either.right(errorResponse);
1260             }
1261
1262             verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1263             verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1264             verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1265             verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1266
1267             response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1268             if (response.isRight()) {
1269                 return Either.right(response.right().value());
1270             }
1271
1272             verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1273
1274             if (serviceUpdate.getProjectCode() != null) {
1275                 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1276                 if (response.isRight()) {
1277                     return Either.right(response.right().value());
1278                 }
1279             }
1280
1281             response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1282             if (response.isRight()) {
1283                 return Either.right(response.right().value());
1284             }
1285
1286             verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1287             verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1288
1289             response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1290             if (response.isRight()) {
1291                 return Either.right(response.right().value());
1292             }
1293
1294             response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1295             if (response.isRight()) {
1296                 return Either.right(response.right().value());
1297             }
1298
1299             response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1300             if (response.isRight()) {
1301                 return Either.right(response.right().value());
1302             }
1303
1304             verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1305             verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1306             verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1307             verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1308
1309             validateAndUpdateServiceType(currentService, serviceUpdate);
1310
1311             response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1312             if (response.isRight()) {
1313                 return Either.right(response.right().value());
1314             }
1315
1316             response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1317             if (response.isRight()) {
1318                 return Either.right(response.right().value());
1319             }
1320
1321             verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1322
1323             validateAndUpdateEcompNaming(currentService, serviceUpdate);
1324
1325             currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1326             return Either.left(currentService);
1327
1328         } catch (ComponentException exception) {
1329             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1330             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
1331                     AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1332             return Either.right(responseFormat);
1333         }
1334     }
1335
1336     private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1337         if (updatedValue != null && !updatedValue.equals(originalValue)) {
1338             log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1339         }
1340     }
1341
1342     private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1343         Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1344         Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1345         if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1346             currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1347         }
1348         String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1349         if (currentService.isEcompGeneratedNaming()) {
1350             currentService.setNamingPolicy(namingPolicyUpdate);
1351         } else {
1352             if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1353                 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1354             }
1355             currentService.setNamingPolicy("");
1356         }
1357     }
1358
1359     private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1360         String contactIdUpdated = serviceUpdate.getContactId();
1361         String contactIdCurrent = currentService.getContactId();
1362         if (!contactIdCurrent.equals(contactIdUpdated)) {
1363            validateContactId(user, serviceUpdate, audatingAction);
1364             currentService.setContactId(contactIdUpdated.toLowerCase());
1365         }
1366         return Either.left(true);
1367     }
1368
1369     private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1370         List<String> tagsUpdated = serviceUpdate.getTags();
1371         List<String> tagsCurrent = currentService.getTags();
1372         if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1373             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1374             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1375             return Either.right(responseFormat);
1376         }
1377
1378         if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1379             validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
1380             currentService.setTags(tagsUpdated);
1381         }
1382         return Either.left(true);
1383     }
1384
1385     private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1386         String descriptionUpdated = serviceUpdate.getDescription();
1387         String descriptionCurrent = currentService.getDescription();
1388         if (!descriptionCurrent.equals(descriptionUpdated)) {
1389             validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
1390             currentService.setDescription(serviceUpdate.getDescription());
1391         }
1392         return Either.left(true);
1393     }
1394
1395     private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1396         String projectCodeUpdated = serviceUpdate.getProjectCode();
1397         String projectCodeCurrent = currentService.getProjectCode();
1398         if (!projectCodeCurrent.equals(projectCodeUpdated)) {
1399
1400             Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
1401             if (validatProjectCodeResponse.isRight()) {
1402                 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
1403                 return Either.right(errorRespons);
1404             }
1405             currentService.setProjectCode(projectCodeUpdated);
1406
1407         }
1408         return Either.left(true);
1409     }
1410
1411     private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1412         String iconUpdated = serviceUpdate.getIcon();
1413         String iconCurrent = currentService.getIcon();
1414         if (!iconCurrent.equals(iconUpdated)) {
1415             if (!hasBeenCertified) {
1416                 validateIcon(user, serviceUpdate, audatingAction);
1417                 currentService.setIcon(iconUpdated);
1418             } else {
1419                 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1420                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1421                 return Either.right(errorResponse);
1422             }
1423         }
1424         return Either.left(true);
1425     }
1426
1427     private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1428         String serviceNameUpdated = serviceUpdate.getName();
1429         String serviceNameCurrent = currentService.getName();
1430         if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1431             if (!hasBeenCertified) {
1432                 validateComponentName(user, serviceUpdate, auditingAction);
1433                 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
1434                 if (serviceNameUniquenessValidation.isRight()) {
1435                     return serviceNameUniquenessValidation;
1436                 }
1437                 currentService.setName(serviceNameUpdated);
1438                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1439                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1440
1441             } else {
1442                 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1443                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1444                 return Either.right(errorResponse);
1445             }
1446         }
1447         return Either.left(true);
1448     }
1449
1450     private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1451         String updatedServiceType = updatedService.getServiceType();
1452         String currentServiceType = currentService.getServiceType();
1453         if (!currentServiceType.equals(updatedServiceType)) {
1454             validateServiceTypeAndCleanup(updatedService);
1455             currentService.setServiceType(updatedServiceType);
1456         }
1457     }
1458
1459     private void validateServiceTypeAndCleanup(Component component) {
1460         log.debug("validate service type");
1461         String serviceType = ((Service)component).getServiceType();
1462         if (serviceType == null) {
1463             log.info("service type is not valid.");
1464             throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1465         }
1466         serviceType = cleanUpText(serviceType);
1467         validateServiceType(serviceType);
1468     }
1469
1470
1471     private void validateServiceType(String serviceType) {
1472         if (serviceType.isEmpty()) {
1473             return;
1474         }
1475         if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
1476             log.info("service type exceeds limit.");
1477             throw new ComponentException(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
1478         }
1479         if (!ValidationUtils.validateIsEnglish(serviceType)) {
1480             log.info("service type is not valid.");
1481             throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
1482         }
1483     }
1484
1485     private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1486         String updatedServiceRole = updatedService.getServiceRole();
1487         String currentServiceRole = currentService.getServiceRole();
1488         if (!currentServiceRole.equals(updatedServiceRole)) {
1489             Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
1490             if (validateServiceRole.isRight()) {
1491                 ResponseFormat errorResponse = validateServiceRole.right().value();
1492                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1493                 return Either.right(errorResponse);
1494             }
1495             currentService.setServiceRole(updatedServiceRole);
1496         }
1497         return Either.left(true);
1498     }
1499
1500     protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1501         log.debug("validate service role");
1502         String serviceRole = ((Service)component).getServiceRole();
1503         if (serviceRole != null){
1504             serviceRole = cleanUpText(serviceRole);
1505
1506             Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
1507             if (validateServiceRole.isRight()) {
1508                 ResponseFormat responseFormat = validateServiceRole.right().value();
1509                 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1510                 return Either.right(responseFormat);
1511             }
1512             return Either.left(true);
1513         } else {
1514             return Either.left(false);
1515         }
1516     }
1517
1518     private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1519         String updatedInstaType= updatedService.getInstantiationType();
1520         String currentInstaType = currentService.getInstantiationType();
1521         if (!currentInstaType.equals(updatedInstaType)) {
1522             Either<Boolean, ResponseFormat> validateInstantiationType = validateInstantiationTypeValue(user, updatedService , auditingAction);
1523             if (validateInstantiationType.isRight()) {
1524                 ResponseFormat errorResponse = validateInstantiationType.right().value();
1525                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1526                 return Either.right(errorResponse);
1527             }
1528             currentService.setInstantiationType(updatedInstaType);
1529         }
1530         return Either.left(true);
1531     }
1532
1533     private Either<Boolean, ResponseFormat> validateInstantiationTypeValue(User user, Service service, AuditingActionEnum actionEnum) {
1534         log.debug("validate instantiation type");
1535         String instantiationType = service.getInstantiationType();
1536         if (!InstantiationTypes.containsName(instantiationType) || instantiationType == null){
1537                         log.error("Recieved Instantiation type {} is not valid.", instantiationType);
1538                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_INSTANTIATION_TYPE);
1539                         componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1540                         return Either.right(errorResponse);
1541                 }
1542                 return Either.left(true);
1543     }
1544
1545     private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1546         if (serviceRole.equals("")){
1547             return Either.left(true);
1548         } else {
1549             if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1550                 log.info("service role exceeds limit.");
1551                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1552                 return Either.right(errorResponse);
1553             }
1554
1555             if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1556                 log.info("service role is not valid.");
1557                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1558                 return Either.right(errorResponse);
1559             }
1560             return Either.left(true);
1561         }
1562     }
1563
1564     private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1565         List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1566         List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1567         Either<Boolean, ResponseFormat> validateCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1568         if (validateCategoryResponse.isRight()) {
1569             return Either.right(validateCategoryResponse.right().value());
1570         }
1571         if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1572             if (!hasBeenCertified) {
1573                 currentService.setCategories(categoryUpdated);
1574             } else {
1575                 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1576                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1577                 return Either.right(errorResponse);
1578             }
1579         }
1580         return Either.left(true);
1581
1582     }
1583
1584     private Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1585         if (list != null) {
1586             if (list.size() > 1) {
1587                 log.debug("Must be only one category for service");
1588                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1589                 return Either.right(responseFormat);
1590             }
1591             CategoryDefinition category = list.get(0);
1592             if (category.getSubcategories() != null) {
1593                 log.debug("Subcategories cannot be defined for service");
1594                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1595                 return Either.right(responseFormat);
1596             }
1597             if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1598                 log.debug("Resource category is empty");
1599                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1600                 return Either.right(responseFormat);
1601             }
1602
1603             log.debug("validating service category {} against valid categories list", list);
1604             Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1605             if (categorys.isRight()) {
1606                 log.debug("failed to retrieve service categories from Titan");
1607                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1608                 return Either.right(responseFormat);
1609             }
1610             List<CategoryDefinition> categoryList = categorys.left().value();
1611             for (CategoryDefinition value : categoryList) {
1612                 if (value.getName().equals(category.getName())) {
1613                     return Either.left(true);
1614                 }
1615             }
1616             log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1617             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1618         }
1619         return Either.left(false);
1620     }
1621
1622     public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1623         Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1624         if (serviceResponseFormatEither.isRight()){
1625             return Either.right(serviceResponseFormatEither.right().value());
1626         }
1627         final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1628         return Either.left(serviceRelations);
1629
1630
1631     }
1632
1633     public ResponseFormat deleteService(String serviceId, User user) {
1634         ResponseFormat responseFormat;
1635         String ecompErrorContext = "delete service";
1636
1637         validateUserExists(user, ecompErrorContext, false);
1638         Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1639         if (serviceStatus.isRight()) {
1640             log.debug("failed to get service {}", serviceId);
1641             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1642         }
1643
1644         Service service = serviceStatus.left().value();
1645
1646         StorageOperationStatus result = StorageOperationStatus.OK;
1647         Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1648         if (lockResult.isRight()) {
1649             return lockResult.right().value();
1650         }
1651         try {
1652             result = markComponentToDelete(service);
1653             if (result.equals(StorageOperationStatus.OK)) {
1654                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1655             } else {
1656                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1657                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1658             }
1659             return responseFormat;
1660         } finally {
1661             if (result == null || !result.equals(StorageOperationStatus.OK)) {
1662                 log.warn("operation failed. do rollback");
1663                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1664                 titanDao.rollback();
1665             } else {
1666                 log.debug("operation success. do commit");
1667                 titanDao.commit();
1668             }
1669             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1670         }
1671     }
1672
1673     public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1674         ResponseFormat responseFormat;
1675         String ecompErrorContext = "delete service";
1676         validateUserNotEmpty(user, ecompErrorContext);
1677         user = validateUserExists(user, ecompErrorContext, false);
1678
1679         Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1680         if (getResult.isRight()) {
1681             return getResult.right().value();
1682         }
1683         Service service = getResult.left().value();
1684
1685         StorageOperationStatus result = StorageOperationStatus.OK;
1686         Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1687         if (lockResult.isRight()) {
1688             result = StorageOperationStatus.GENERAL_ERROR;
1689             return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1690         }
1691
1692         try {
1693             result = markComponentToDelete(service);
1694             if (result.equals(StorageOperationStatus.OK)) {
1695                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1696             } else {
1697                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1698                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1699             }
1700             return responseFormat;
1701
1702         } finally {
1703             if (result == null || !result.equals(StorageOperationStatus.OK)) {
1704                 log.warn("operation failed. do rollback");
1705                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1706                 titanDao.rollback();
1707             } else {
1708                 log.debug("operation success. do commit");
1709                 titanDao.commit();
1710             }
1711             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1712         }
1713     }
1714
1715     public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1716         String ecompErrorContext = "Get service";
1717         validateUserNotEmpty(user, ecompErrorContext);
1718         validateUserExists(user, ecompErrorContext, false);
1719
1720         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1721         if (storageStatus.isRight()) {
1722             log.debug("failed to get service by id {}", serviceId);
1723             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1724         }
1725
1726         if(!(storageStatus.left().value() instanceof Service)){
1727             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1728         }
1729         Service service = storageStatus.left().value();
1730         return Either.left(service);
1731
1732
1733
1734
1735     }
1736
1737     public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1738         validateUserExists(userId, "get Service By Name And Version", false);
1739         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1740         if (storageStatus.isRight()) {
1741             log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1742             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1743         }
1744         Service service = storageStatus.left().value();
1745         return Either.left(service);
1746     }
1747
1748     @SuppressWarnings("unchecked")
1749     private void createMandatoryArtifactsData(Service service, User user) {
1750         // create mandatory artifacts
1751
1752         // TODO it must be removed after that artifact uniqueId creation will be
1753         // moved to ArtifactOperation
1754         String serviceUniqueId = service.getUniqueId();
1755         Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1756         if (artifactMap == null)
1757             artifactMap = new HashMap<>();
1758
1759         Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1760         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1761
1762         String category = service.getCategories().get(0).getName();
1763         boolean isCreateArtifact = true;
1764         if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1765             for (String exlude : exludeServiceCategory) {
1766                 if (exlude.equalsIgnoreCase(category)) {
1767                     isCreateArtifact = false;
1768                     break;
1769                 }
1770             }
1771
1772         }
1773
1774         if (informationalServiceArtifacts != null && isCreateArtifact) {
1775             Set<String> keys = informationalServiceArtifacts.keySet();
1776             for (String informationalServiceArtifactName : keys) {
1777                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1778                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1779                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1780
1781             }
1782
1783             service.setArtifacts(artifactMap);
1784         }
1785     }
1786
1787     private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1788
1789         ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1790
1791         if (isServiceApi) {
1792             artifactInfo.setMandatory(false);
1793             artifactInfo.setServiceApi(true);
1794         }
1795         return artifactInfo;
1796     }
1797
1798     private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition) {
1799         DistributionTransitionEnum transitionEnum = null;
1800
1801         transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1802         if (transitionEnum == null) {
1803             BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1804             log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1805             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1806             return Either.right(error);
1807         }
1808
1809         return Either.left(transitionEnum);
1810     }
1811
1812     private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment) {
1813         String data = comment.getUserRemarks();
1814
1815         if (data == null || data.trim().isEmpty()) {
1816             BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1817             log.debug("user comment cannot be empty or null.");
1818             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1819         }
1820         data = ValidationUtils.removeNoneUtf8Chars(data);
1821         data = ValidationUtils.removeHtmlTags(data);
1822         data = ValidationUtils.normaliseWhitespace(data);
1823         data = ValidationUtils.stripOctets(data);
1824
1825         if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1826             BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1827             log.debug("user comment exceeds limit.");
1828             return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1829         }
1830         if (!ValidationUtils.validateIsEnglish(data)) {
1831             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1832         }
1833         return Either.left(data);
1834     }
1835
1836     private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1837         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1838         if (storageStatus.isRight()) {
1839             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1840             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1841             componentsUtils.auditComponent(responseFormat, user, auditAction, new ResourceCommonInfo(serviceId, ComponentTypeEnum.SERVICE.getValue()), comment);
1842             return Either.right(responseFormat);
1843         }
1844         Service service = storageStatus.left().value();
1845
1846         if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1847             log.info("service {} is  not available for distribution. Should be in certified state", service.getUniqueId());
1848             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1849             createAudit(user, auditAction, comment, service, responseFormat);
1850             return Either.right(responseFormat);
1851         }
1852         return Either.left(service);
1853     }
1854
1855     private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1856         log.debug("get user from DB");
1857
1858         // get user details
1859         user = validateUser(user, "Activate Distribution", service, auditAction, false);
1860         // validate user role
1861         List<Role> roles = new ArrayList<>();
1862         roles.add(Role.ADMIN);
1863         roles.add(Role.GOVERNOR);
1864         roles.add(Role.OPS);
1865         validateUserRole(user, service, roles, auditAction, comment);
1866         return Either.left(user);
1867     }
1868
1869     private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1870         log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1871         componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1872                 ResourceVersionInfo.newBuilder()
1873                         .state(component.getLifecycleState().name())
1874                         .version(component.getVersion())
1875                         .build(),
1876                 comment);
1877     }
1878
1879     private String getEnvNameFromConfiguration() {
1880         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1881         log.trace("Update environment name to be {}", configuredEnvName);
1882         return configuredEnvName;
1883     }
1884
1885     public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1886
1887         Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1888         if (activationRequestInformationEither.isRight()) {
1889             return Either.right(activationRequestInformationEither.right().value());
1890         }
1891
1892         ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1893
1894         Either<String, ResponseFormat> result = null;
1895         String did = ThreadLocalsHolder.getUuid();
1896         Service service = activationRequestInformation.getServiceToActivate();
1897         result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1898         return result;
1899     }
1900
1901     public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1902         String envName = getEnvNameFromConfiguration();
1903         INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1904         ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1905         if (notifyServiceResponse == ActionStatus.OK) {
1906             return Either.left(did);
1907         } else {
1908             BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1909             log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1910             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1911             return Either.right(error);
1912         }
1913     }
1914
1915     public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1916
1917         User user = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1918         Either<Service, ResponseFormat> result = null;
1919         ResponseFormat response = null;
1920         Service updatedService = null;
1921         String did = ThreadLocalsHolder.getUuid();
1922          // DE194021
1923         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1924         if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1925             log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1926             envName = configuredEnvName;
1927         }
1928         // DE194021
1929
1930         ServletContext servletContext = request.getSession().getServletContext();
1931         boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1932         if (!isDistributionEngineUp) {
1933             BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1934             log.debug("Distribution Engine is DOWN");
1935             response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1936             return Either.right(response);
1937         }
1938
1939         Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1940         if (serviceRes.isRight()) {
1941             log.debug("failed retrieving service");
1942             response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1943             componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1944                     new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1945                     ResourceVersionInfo.newBuilder()
1946                             .build(),
1947                     did);
1948             return Either.right(response);
1949         }
1950         Service service = serviceRes.left().value();
1951         String dcurrStatus = service.getDistributionStatus().name();
1952         String updatedStatus = dcurrStatus;
1953         StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1954         if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1955             INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1956             ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1957             if (notifyServiceResponse == ActionStatus.OK) {
1958                 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1959                 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1960                     updatedService = updateStateRes.left().value();
1961                     updatedStatus = updatedService.getDistributionStatus().name();
1962                 } else {
1963                     // The response is not relevant
1964                     updatedService = service;
1965                 }
1966                 ASDCKpiApi.countActivatedDistribution();
1967                 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1968                 result = Either.left(updatedService);
1969             } else {
1970                 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1971                 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1972                 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1973                 result = Either.right(response);
1974             }
1975         } else {
1976             response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), envName);
1977             result = Either.right(response);
1978         }
1979         componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1980                 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1981                 ResourceVersionInfo.newBuilder()
1982                         .distributionStatus(dcurrStatus)
1983                         .build(),
1984                 ResourceVersionInfo.newBuilder()
1985                         .distributionStatus(updatedStatus)
1986                         .build(),
1987                 null, null, did);
1988         return result;
1989     }
1990
1991     // convert to private after deletion of temp url
1992     public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1993
1994         validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1995
1996         String serviceId = service.getUniqueId();
1997         Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1998         if (lockResult.isRight()) {
1999             return Either.right(lockResult.right().value());
2000         }
2001         try {
2002             Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
2003             if (result.isRight()) {
2004                 titanDao.rollback();
2005                 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
2006                 log.debug("service {}  change distribution status failed", serviceId);
2007                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2008             }
2009             titanDao.commit();
2010             return Either.left(result.left().value());
2011         } finally {
2012             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
2013         }
2014     }
2015
2016     public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
2017
2018         validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
2019         log.debug("mark distribution deployed");
2020
2021         AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
2022         Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
2023         if (getServiceResponse.isRight()) {
2024             BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
2025             log.debug("service {} not found", serviceId);
2026             ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
2027
2028             return Either.right(responseFormat);
2029         }
2030
2031         Service service = getServiceResponse.left().value();
2032         user = validateRoleForDeploy(did, user, auditAction, service);
2033         return checkDistributionAndDeploy(did, user, auditAction, service);
2034
2035     }
2036
2037     public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2038         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
2039                 // Only one VF Module Artifact per instance - add it to a list of one
2040                 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
2041
2042         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2043
2044     }
2045
2046     private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
2047         List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
2048
2049         if (ri.getOriginType() == OriginTypeEnum.VF) {
2050             asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
2051         }
2052         return asList;
2053     }
2054
2055     private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
2056         Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
2057         if(currVF.getGroupInstances() != null){
2058             currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
2059         }
2060         return currVF.getGroupInstances();
2061     }
2062
2063     private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
2064         ArtifactDefinition vfModuleAertifact = null;
2065         if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
2066             Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
2067             if (optionalVfModuleArtifact.isPresent()) {
2068                 vfModuleAertifact = optionalVfModuleArtifact.get();
2069             }
2070         }
2071         if (vfModuleAertifact == null) {
2072             Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
2073             if (createVfModuleArtifact.isLeft()) {
2074                 vfModuleAertifact = createVfModuleArtifact.left().value();
2075             } else {
2076                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
2077             }
2078         }
2079         return vfModuleAertifact;
2080     }
2081
2082     private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
2083         List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
2084         if (groupsForCurrVF != null) {
2085             for (GroupInstance groupInstance : groupsForCurrVF) {
2086                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
2087                 vfModulePayloads.add(modulePayload);
2088             }
2089             vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
2090
2091             final Gson gson = new GsonBuilder().setPrettyPrinting().create();
2092
2093             String vfModulePayloadString = gson.toJson(vfModulePayloads);
2094             payloadWrapper.setInnerElement(vfModulePayloadString);
2095         }
2096
2097     }
2098
2099     private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
2100         ArtifactDefinition vfModuleArtifact = null;
2101         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
2102         Wrapper<String> payloadWrapper = new Wrapper<>();
2103         List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
2104         if (responseWrapper.isEmpty()) {
2105             fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
2106         }
2107         if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
2108             vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
2109         }
2110         if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
2111             vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
2112         }
2113
2114         Either<ArtifactDefinition, ResponseFormat> result;
2115         if (responseWrapper.isEmpty()) {
2116             result = Either.left(vfModuleArtifact);
2117         } else {
2118             result = Either.right(responseWrapper.getInnerElement());
2119         }
2120
2121         return result;
2122     }
2123
2124     private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2125         ArtifactDefinition result = null;
2126         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2127                 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2128         if (eitherPayload.isLeft()) {
2129             result = eitherPayload.left().value();
2130         } else {
2131             responseWrapper.setInnerElement(eitherPayload.right().value());
2132         }
2133         if (result == null) {
2134             result = vfModuleArtifact;
2135         }
2136
2137         return result;
2138     }
2139
2140     private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2141
2142         ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2143         String newCheckSum = null;
2144
2145         vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2146         vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2147         vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2148         vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2149         vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2150         vfModuleArtifactDefinition.setTimeout(0);
2151         vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2152         vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2153         if (vfModulePayloadString != null) {
2154             newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2155         }
2156         vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2157
2158         Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2159
2160         Either<ArtifactDefinition, ResponseFormat> result;
2161         if (addArifactToComponent.isLeft()) {
2162             result = Either.left(addArifactToComponent.left().value());
2163         } else {
2164             result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
2165         }
2166
2167         return result;
2168     }
2169
2170     public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2171
2172         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2173                 // Get All Deployment Artifacts
2174                 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2175                         // Filter in Only Heat Env
2176                                 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2177                         // Create ArtifactGenerator from those Artifacts
2178                                 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2179
2180         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2181
2182     }
2183
2184     private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2185
2186         // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2187         // service
2188         if (service.getComponentInstances() != null) {
2189             List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2190             if (artifactGenList != null && !artifactGenList.isEmpty()) {
2191                 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2192                     Either<CallVal, ResponseFormat> callRes;
2193                     try {
2194                         callRes = entry.call();
2195                         if (callRes.isRight()) {
2196                             log.debug("Failed to generate artifact error : {}", callRes.right().value());
2197                             return Either.right(callRes.right().value());
2198                         }
2199                     } catch (Exception e) {
2200                         log.debug("Failed to generate artifact exception : {}", e);
2201                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2202                     }
2203                 }
2204             }
2205         }
2206         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2207         if (storageStatus.isRight()) {
2208             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2209         }
2210
2211         Service currentService = storageStatus.left().value();
2212
2213         return Either.left(currentService);
2214
2215     }
2216
2217     abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2218
2219     }
2220
2221     class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2222         ArtifactDefinition artifactDefinition;
2223         Service service;
2224         String resourceInstanceName;
2225         User modifier;
2226         String instanceId;
2227         boolean shouldLock;
2228         boolean inTransaction;
2229
2230         HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2231             this.artifactDefinition = artifactDefinition;
2232             this.service = service;
2233             this.resourceInstanceName = resourceInstanceName;
2234             this.modifier = modifier;
2235             this.shouldLock = shouldLock;
2236             this.instanceId = instanceId;
2237             this.inTransaction = inTransaction;
2238         }
2239
2240         @Override
2241         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2242             return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2243         }
2244
2245         public ArtifactDefinition getArtifactDefinition() {
2246             return artifactDefinition;
2247         }
2248
2249     }
2250
2251     class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2252         private User user;
2253         private ComponentInstance componentInstance;
2254         private Service service;
2255         boolean shouldLock;
2256         boolean inTransaction;
2257
2258         @Override
2259         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2260             return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2261         }
2262
2263         private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2264             super();
2265             this.user = user;
2266             this.componentInstance = componentInstance;
2267             this.service = service;
2268             this.shouldLock = shouldLock;
2269             this.inTransaction = inTransaction;
2270         }
2271
2272     }
2273
2274     private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2275         boolean isDeployed = isDistributionDeployed(distributionId);
2276         if (isDeployed) {
2277             return Either.left(service);
2278         }
2279         Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2280         if (distributionSuccess.isRight()) {
2281             return Either.right(distributionSuccess.right().value());
2282         }
2283
2284         log.debug("mark distribution {} as deployed - success", distributionId);
2285         componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2286         return Either.left(service);
2287     }
2288
2289     private boolean isDistributionDeployed(String distributionId) {
2290         Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2291
2292         boolean isDeployed = false;
2293         if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2294             // already deployed
2295             log.debug("distribution {} is already deployed", distributionId);
2296             isDeployed = true;
2297         }
2298         return isDeployed;
2299     }
2300
2301     protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2302
2303         log.trace("checkDistributionSuccess");
2304         // get all "DRequest" records for this distribution
2305
2306         Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2307         if (distRequestsResponse.isRight()) {
2308             ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2309             return Either.right(error);
2310         }
2311
2312         List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2313         if (distributionRequests.isEmpty()) {
2314             BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2315             log.info("distribution {} is not found", did);
2316             ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2317             return Either.right(error);
2318         }
2319         boolean isRequestSucceeded = false;
2320         for (ResourceAdminEvent event : distributionRequests) {
2321             String eventStatus = event.getStatus();
2322             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2323                 isRequestSucceeded = true;
2324                 break;
2325             }
2326         }
2327
2328         // get all "DNotify" records for this distribution
2329         Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2330         if (distNotificationsResponse.isRight()) {
2331             ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2332             return Either.right(error);
2333         }
2334
2335         List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2336         boolean isNotificationsSucceeded = false;
2337         for (DistributionNotificationEvent event : distributionNotifications) {
2338             String eventStatus = event.getStatus();
2339             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2340                 isNotificationsSucceeded = true;
2341                 break;
2342             }
2343         }
2344
2345         // if request failed OR there are notifications that failed
2346         if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2347
2348             log.info("distribution {} has failed", did);
2349             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2350             auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2351             return Either.right(error);
2352         }
2353         return Either.left(true);
2354     }
2355
2356     private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2357
2358         ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2359         String message = "";
2360         if (error.getMessageId() != null) {
2361             message = error.getMessageId() + ": ";
2362         }
2363         message += error.getFormattedMessage();
2364
2365         if (service != null) {
2366             componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2367         } else {
2368             componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2369         }
2370         return error;
2371     }
2372
2373     private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2374         Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
2375         if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
2376             BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
2377             log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
2378             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
2379             auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
2380             throw new ComponentException(ActionStatus.USER_NOT_FOUND, user.getUserId());
2381         }
2382         user = eitherCreator.left().value();
2383         log.debug("validate user role");
2384         List<Role> roles = new ArrayList<>();
2385         roles.add(Role.ADMIN);
2386         roles.add(Role.OPS);
2387         try{
2388             validateUserRole(user, service, roles, auditAction, null);
2389         } catch (ComponentException e){
2390             log.info("role {} is not allowed to perform this action", user.getRole());
2391             auditDeployError(did, user, auditAction, service, e.getActionStatus());
2392             throw e;
2393         }
2394         return user;
2395     }
2396
2397     @Override
2398     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2399         Service service = (Service) component;
2400         Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2401         if (artifactMap == null) {
2402             artifactMap = new HashMap<>();
2403         }
2404         service.setDeploymentArtifacts(artifactMap);
2405     }
2406
2407     @Override
2408     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2409         return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2410     }
2411
2412     private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2413         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2414         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2415         return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2416     }
2417
2418     @Override
2419     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2420         return componentInstanceBusinessLogic;
2421     }
2422
2423     @Override
2424     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2425
2426         validateUserExists(userId, "Get Component Instances", false);
2427         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2428         if (getComponentRes.isRight()) {
2429             ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2430             return Either.right(responseFormat);
2431         }
2432
2433         List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2434
2435         return Either.left(componentInstances);
2436     }
2437
2438     public ICacheMangerOperation getCacheManagerOperation() {
2439         return cacheManagerOperation;
2440     }
2441
2442     public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
2443         this.cacheManagerOperation = cacheManagerOperation;
2444     }
2445
2446     public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2447         this.forwardingPathOperation = forwardingPathOperation;
2448     }
2449
2450     @Override
2451     public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
2452         this.toscaOperationFacade = toscaOperationFacade;
2453     }/**
2454      * updates group instance with new property values in case of successful update of group instance related component instance will be updated with new modification time and related service will be updated with new last update date
2455      *
2456      */
2457     public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2458
2459         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2460         Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2461         Component component = null;
2462         Either<Boolean, ResponseFormat> lockResult = null;
2463         log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2464         try {
2465             validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2466             if (validateUserAndComponentRes.isRight()) {
2467                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
2468                 actionResult = Either.right(validateUserAndComponentRes.right().value());
2469             }
2470             if (actionResult == null) {
2471                 component = validateUserAndComponentRes.left().value().getKey();
2472                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2473                 if (lockResult.isRight()) {
2474                     log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2475                     actionResult = Either.right(lockResult.right().value());
2476                 } else {
2477                     log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2478                 }
2479             }
2480             if (actionResult == null) {
2481                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2482                 if (actionResult.isRight()) {
2483                     log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2484                 }
2485             }
2486         } catch (Exception e) {
2487             log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2488             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2489         } finally {
2490             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2491                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2492             }
2493         }
2494         return actionResult;
2495     }
2496
2497     private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2498
2499         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2500         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2501         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2502         ComponentInstance relatedComponentInstance = null;
2503         GroupInstance oldGroupInstance = null;
2504         Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2505         GroupInstance updatedGroupInstance = null;
2506         boolean inTransaction = true;
2507         findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2508         if (findGroupInstanceRes.isRight()) {
2509             log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2510             actionResult = Either.right(findGroupInstanceRes.right().value());
2511         }
2512         if (actionResult == null) {
2513             oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2514             relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2515             updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2516             if (updateGroupInstanceResult.isRight()) {
2517                 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2518                 actionResult = Either.right(updateGroupInstanceResult.right().value());
2519             }
2520         }
2521         if (actionResult == null) {
2522             updatedGroupInstance = updateGroupInstanceResult.left().value();
2523             if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2524                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2525                 if (updateParentsModificationTimeRes.isRight()) {
2526                     log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2527                     actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2528                 }
2529             }
2530         }
2531         if (actionResult == null) {
2532             actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2533         }
2534         return actionResult;
2535     }
2536
2537     private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2538                                                                                                                                                   boolean inTranscation) {
2539
2540         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2541         Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2542         Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2543                 updatedGroupInstance.getModificationTime(), inTranscation);
2544         if (updateComponentInstanceRes.isRight()) {
2545             log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2546             actionResult = Either.right(updateComponentInstanceRes.right().value());
2547         } else {
2548             serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2549             if (serviceMetadataUpdateResult.isRight()) {
2550                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2551                 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2552             } else {
2553                 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2554             }
2555         }
2556         return actionResult;
2557     }
2558
2559     private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2560
2561         Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2562         Either<Component, ResponseFormat> validateComponentExistsRes = null;
2563         User currUser = null;
2564         Component component = null;
2565         Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2566         if (validationUserResult.isRight()) {
2567             log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2568             result = Either.right(validationUserResult.right().value());
2569         }
2570         if (result == null) {
2571             currUser = validationUserResult.left().value();
2572             validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2573             if (validateComponentExistsRes.isRight()) {
2574                 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2575                 result = Either.right(validateComponentExistsRes.right().value());
2576             }
2577         }
2578         if (result == null) {
2579             component = validateComponentExistsRes.left().value();
2580             if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2581                 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2582                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2583             }
2584         }
2585         if (result == null) {
2586             result = Either.left(new ImmutablePair<>(component, currUser));
2587         }
2588         return result;
2589     }
2590
2591     private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2592
2593         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2594         GroupInstance groupInstance = null;
2595         ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2596         if (foundComponentInstance == null) {
2597             log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2598             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2599         }
2600         else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2601             groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2602             if (groupInstance == null) {
2603                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2604                 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2605             }
2606         }
2607         if (actionResult == null) {
2608             actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2609         }
2610         return actionResult;
2611     }
2612
2613     private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2614         ComponentInstance componentInstance = null;
2615         if (isNotEmpty(component.getComponentInstances())) {
2616             componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2617         }
2618         return componentInstance;
2619     }
2620
2621     private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2622         User user = validateUser(modifier, ecompErrorContext, null, null, false);
2623         List<Role> roles = new ArrayList<>();
2624         roles.add(Role.ADMIN);
2625         roles.add(Role.DESIGNER);
2626         validateUserRole(user, roles);
2627         return Either.left(user);
2628     }
2629
2630     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2631
2632         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2633         paramsToReturn.setIgnoreComponentInstancesProperties(false);
2634         Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2635
2636         if (serviceResultEither.isRight()) {
2637             if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2638                 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2639                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2640             }
2641
2642             log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2643             return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2644         }
2645
2646         Service service = serviceResultEither.left().value();
2647                 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2648                         ListUtils.emptyIfNull(service.getInputs())
2649                                         .forEach(input -> input.setConstraints(setInputConstraint(input)));
2650                 }
2651
2652         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2653         return Either.left(dataTransfer);
2654     }
2655
2656     public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
2657         Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
2658         User user = validateUserExists(userId, "Create service Filter", false);
2659
2660         user =
2661                 validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
2662
2663          Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
2664         if (storageStatus.isRight()) {
2665             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2666         }
2667         Service service = storageStatus.left().value();
2668
2669         Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
2670         if (storageStatus.isRight()) {
2671             return Either.right(response.right().value());
2672         }
2673         final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
2674         if (!optionalComponentInstance.isPresent() ){
2675             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2676         }
2677         CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
2678         if (nodeFilter == null){
2679             return Either.left(resourceId);
2680         }
2681
2682         Either<String, StorageOperationStatus> result;
2683         if (lock) {
2684             Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
2685             if (lockResult.isRight()) {
2686                 titanDao.rollback();
2687                 return Either.right(componentsUtils.getResponseFormat(componentsUtils
2688                                                                               .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2689             }
2690         }
2691         try{
2692             result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
2693             if (result.isRight()) {
2694                 log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
2695                 titanDao.rollback();
2696                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
2697             }
2698             titanDao.commit();
2699             log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
2700
2701         } catch (Exception e){
2702             log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
2703             titanDao.rollback();
2704             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2705         } finally {
2706             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2707         }
2708         return Either.left(result.left().value());
2709     }
2710
2711
2712     private Service initServiceToDeleteServiceFilter(String serviceId) {
2713         Service serviceToDelete = new Service();
2714         serviceToDelete.setUniqueId(serviceId);
2715         return serviceToDelete;
2716     }
2717
2718
2719     public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
2720         String errorContext =  "createIfNotAlreadyExistServiceFilter";
2721         User user = validateUserExists(userId, "Create service Filter", false);
2722
2723         Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
2724         if (serviceEither.isRight()) {
2725             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
2726         }
2727         final Service service = serviceEither.left().value();
2728         validateUserAndRole(service, user, errorContext);
2729
2730         Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
2731         if (!optionalComponentInstance.isPresent()){
2732             return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2733         }
2734         ComponentInstance componentInstance = optionalComponentInstance.get();
2735         CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
2736         if (serviceFilter != null){
2737             return Either.left(serviceFilter);
2738         }
2739
2740         Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2741
2742         Either<Boolean, ResponseFormat> lockResult = null;
2743         if (lock) {
2744             lockResult =
2745                     lockComponent(service.getUniqueId(), service, "Create Service Filter");
2746             if (lockResult.isRight()) {
2747                 log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
2748                         lockResult.right().value().getFormattedMessage());
2749                 return Either.right(lockResult.right().value());
2750             } else {
2751                 log.debug("The service with system name {} locked. ", service.getSystemName());
2752             }
2753         }
2754         CINodeFilterDataDefinition serviceFilterResult;
2755         try {
2756             result =  serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
2757             if (result.isRight()) {
2758                 titanDao.rollback();
2759                 return Either.right(componentsUtils.getResponseFormat(
2760                         componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2761                         ""));
2762             } else {
2763                 serviceFilterResult = result.left().value();
2764             }
2765             titanDao.commit();
2766
2767         } catch (Exception e) {
2768             titanDao.rollback();
2769             log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2770                     e);
2771             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2772
2773         } finally {
2774             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2775                 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2776             }
2777         }
2778         return Either.left(serviceFilterResult);
2779     }
2780
2781
2782     public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
2783             List<String> constraints,  User inUser, boolean lock) {
2784         String errorContext =  "createIfNotAlreadyExistServiceFilter";
2785         User user = validateUserExists(inUser, errorContext, true);
2786         validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2787         Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2788
2789         if(serviceStorageOperationStatusEither.isRight()){
2790             StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2791             log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2792             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2793         }
2794         Service storedService = serviceStorageOperationStatusEither.left().value();
2795
2796         Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2797                 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
2798                         NodeFilterConstraintAction.UPDATE);
2799         if(booleanResponseFormatEither.isRight()){
2800             return Either.right(booleanResponseFormatEither.right().value());
2801         }
2802
2803
2804         Either<Boolean, ResponseFormat> lockResult = null;
2805         if (lock) {
2806             lockResult =
2807                     lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2808             if (lockResult.isRight()) {
2809                 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2810                         lockResult.right().value().getFormattedMessage());
2811                 return Either.right(lockResult.right().value());
2812             } else {
2813                 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2814             }
2815         }
2816         Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2817         if (!componentInstanceOptional.isPresent()){
2818             return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2819         }
2820         CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2821         if(serviceFilter == null){
2822             return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2823         }
2824         CINodeFilterDataDefinition serviceFilterResult;
2825         try {
2826             List<RequirementNodeFilterPropertyDataDefinition> properties =  constraints.stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
2827             Either<CINodeFilterDataDefinition, StorageOperationStatus>  result =  serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
2828
2829             if (result.isRight()) {
2830                 titanDao.rollback();
2831                 return Either.right(componentsUtils.getResponseFormat(
2832                         componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2833                         ""));
2834             } else {
2835                 serviceFilterResult = result.left().value();
2836             }
2837             titanDao.commit();
2838
2839         } catch (Exception e) {
2840             titanDao.rollback();
2841             log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2842                     e);
2843             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2844
2845         } finally {
2846             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2847                 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2848             }
2849         }
2850         return Either.left(serviceFilterResult);
2851     }
2852
2853     private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
2854         RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
2855         pdd.setConstraints(Arrays.asList(constraint));
2856         return pdd;
2857     }
2858
2859     public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
2860             NodeFilterConstraintAction action, String constraint, int position, User inUser, boolean lock) {
2861         String errorContext =  "createIfNotAlreadyExistServiceFilter";
2862         User user = validateUserExists(inUser, errorContext, true);
2863         validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2864
2865         Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2866
2867         if(serviceStorageOperationStatusEither.isRight()){
2868             StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2869             log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2870             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2871         }
2872         Service storedService = serviceStorageOperationStatusEither.left().value();
2873
2874         Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2875                 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
2876                         Collections.singletonList(constraint), action);
2877         if(booleanResponseFormatEither.isRight()){
2878             return Either.right(booleanResponseFormatEither.right().value());
2879         }
2880
2881         Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2882
2883         Either<Boolean, ResponseFormat> lockResult = null;
2884         CINodeFilterDataDefinition serviceFilterResult = null;
2885         try {
2886             if (lock) {
2887                 lockResult =
2888                         lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2889                 if (lockResult.isRight()) {
2890                     log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2891                             lockResult.right().value().getFormattedMessage());
2892                     return Either.right(lockResult.right().value());
2893                 } else {
2894                     log.debug("The service with system name {} locked. ", storedService.getSystemName());
2895                 }
2896             }
2897
2898             Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2899             if (!componentInstanceOptional.isPresent()){
2900                 return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2901             }
2902             CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2903             if(serviceFilter == null){
2904                 return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2905             }
2906
2907
2908             switch (action) {
2909                 case ADD:
2910                     RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
2911                     newProperty.setConstraints(Collections.singletonList(constraint));
2912                     result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
2913                     break;
2914                 case DELETE:
2915                     result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
2916                     break;
2917                 default:
2918                     log.error("Unsupported operation "+action);
2919                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2920
2921             }
2922
2923             if (result.isRight()) {
2924                 titanDao.rollback();
2925                 return Either.right(componentsUtils.getResponseFormat(
2926                         componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2927                         ""));
2928             } else {
2929                 serviceFilterResult = result.left().value();
2930             }
2931             titanDao.commit();
2932
2933         } catch (Exception e) {
2934             titanDao.rollback();
2935             log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
2936                     e);
2937             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2938
2939         } finally {
2940             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2941                 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2942             }
2943         }
2944         return Either.left(serviceFilterResult);
2945     }
2946 }