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