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