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