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