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