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