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