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