Expose generic Service properties as properties
[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, 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(final Service service, final 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, AuditingActionEnum.CREATE_RESOURCE,
869                 ComponentTypeEnum.SERVICE);
870             return Either.right(responseFormat);
871         }
872
873         log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
874
875         try {
876             createMandatoryArtifactsData(service, user);
877             createServiceApiArtifactsData(service, user);
878             setToscaArtifactsPlaceHolders(service, user);
879             final Resource genericType = fetchAndSetDerivedFromGenericType(service);
880             generatePropertiesFromGenericType(service, genericType);
881             generateAndAddInputsFromGenericTypeProperties(service, genericType);
882             beforeCreate(service);
883
884             Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
885             if (dataModelResponse.isLeft()) {
886                 log.debug("Service '{}' created successfully", service.getName());
887                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
888                 componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_RESOURCE,
889                     ComponentTypeEnum.SERVICE);
890                 ASDCKpiApi.countCreatedServicesKPI();
891                 return Either.left(dataModelResponse.left().value());
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, AuditingActionEnum.CREATE_RESOURCE,
896                 ComponentTypeEnum.SERVICE);
897             return Either.right(responseFormat);
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     private void generatePropertiesFromGenericType(final Service service, final Resource genericType) {
920         if (CollectionUtils.isEmpty(genericType.getProperties())) {
921             return;
922         }
923         final List<PropertyDefinition> genericTypePropertyList = genericType.getProperties().stream()
924             .map(PropertyDefinition::new)
925             .peek(propertyDefinition -> propertyDefinition.setUniqueId(null))
926             .collect(Collectors.toList());
927         if (service.getProperties() == null) {
928             service.setProperties(new ArrayList<>(genericTypePropertyList));
929         } else {
930             List<PropertyDefinition> servicePropertyList = service.getProperties();
931             genericTypePropertyList.stream()
932                 .filter(property -> servicePropertyList.stream()
933                     .noneMatch(property1 -> property1.getName().equals(property.getName())))
934                 .forEach(servicePropertyList::add);
935         }
936
937         service.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(null));
938     }
939
940     @SuppressWarnings("unchecked")
941     private void createServiceApiArtifactsData(Service service, User user) {
942         // create mandatory artifacts
943
944         // TODO it must be removed after that artifact uniqueId creation will be
945         // moved to ArtifactOperation
946         String serviceUniqueId = service.getUniqueId();
947         Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
948         if (artifactMap == null)
949             artifactMap = new HashMap<>();
950
951         Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
952         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
953
954         List<CategoryDefinition> categories = service.getCategories();
955         boolean isCreateArtifact = true;
956         if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
957             for (String exlude : exludeServiceCategory) {
958                 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
959                     isCreateArtifact = false;
960                     break;
961                 }
962             }
963
964         }
965
966         if (serviceApiArtifacts != null && isCreateArtifact) {
967             Set<String> keys = serviceApiArtifacts.keySet();
968             for (String serviceApiArtifactName : keys) {
969                 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
970                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
971                 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
972                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
973             }
974
975             service.setServiceApiArtifacts(artifactMap);
976         }
977     }
978
979     @VisibleForTesting
980     protected Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
981
982         try {
983             serviceValidator.validate(user,service,actionEnum);
984         } catch (ComponentException exp) {
985             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exp);
986             componentsUtils.auditComponentAdmin(responseFormat, user, service,
987                     AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
988             throw exp;
989         }
990
991         service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
992         service.setContactId(service.getContactId().toLowerCase());
993
994         // Generate invariant UUID - must be here and not in operation since it
995         // should stay constant during clone
996         String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
997         service.setInvariantUUID(invariantUUID);
998
999         return Either.left(service);
1000     }
1001
1002     public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
1003         validateUserExists(userId);
1004
1005         Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
1006         // DE242223
1007         janusGraphDao.commit();
1008
1009         if (dataModelResponse.isLeft()) {
1010             Map<String, Boolean> result = new HashMap<>();
1011             result.put(IS_VALID, dataModelResponse.left().value());
1012             log.debug("validation was successfully performed.");
1013             return Either.left(result);
1014         }
1015         ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
1016         return Either.right(responseFormat);
1017     }
1018
1019     public void setElementDao(IElementOperation elementDao) {
1020         this.elementDao = elementDao;
1021     }
1022
1023     @Autowired
1024     public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
1025         this.auditCassandraDao = auditingDao;
1026     }
1027
1028     public ArtifactsBusinessLogic getArtifactBl() {
1029         return artifactsBusinessLogic;
1030     }
1031
1032     public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
1033         this.artifactsBusinessLogic = artifactBl;
1034     }
1035
1036     public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
1037         user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
1038         // validate user role
1039         validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1040
1041         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1042         if (storageStatus.isRight()) {
1043             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1044         }
1045
1046         Service currentService = storageStatus.left().value();
1047
1048         if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
1049             log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
1050             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
1051         }
1052
1053         Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
1054         if (validationRsponse.isRight()) {
1055             log.info("service update metadata: validations field.");
1056             return validationRsponse;
1057         }
1058         Service serviceToUpdate = validationRsponse.left().value();
1059         // lock resource
1060
1061         lockComponent(serviceId, currentService, "Update Service Metadata");
1062         try {
1063             return toscaOperationFacade.updateToscaElement(serviceToUpdate)
1064                     .right()
1065                     .map(rf -> {
1066                         janusGraphDao.rollback();
1067                         BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
1068                         log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
1069                         return (componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1070                        })
1071                     .left()
1072                     .bind(c ->  updateCatalogAndCommit(c));
1073
1074         } finally {
1075             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1076         }
1077     }
1078
1079     private Either<Service, ResponseFormat> updateCatalogAndCommit(Service service){
1080         Either<Service, ResponseFormat> res = updateCatalog(service, ChangeTypeEnum.LIFECYCLE).left().map(s -> (Service)s);
1081         janusGraphDao.commit();
1082         return res;
1083
1084     }
1085
1086     public Set<String> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
1087         Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
1088         user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
1089         // validate user role
1090         validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
1091         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1092         if (storageStatus.isRight()) {
1093             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
1094         }
1095         Service service = storageStatus.left().value();
1096         Either<Set<String>, StorageOperationStatus> result = null;
1097         if (lock) {
1098             try {
1099                 lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
1100             } catch (ComponentException e) {
1101                 janusGraphDao.rollback();
1102                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse
1103                         (storageStatus.right().value(), ComponentTypeEnum.SERVICE), "");
1104             }
1105         }
1106         try{
1107             result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
1108             if (result.isRight()) {
1109                 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
1110                 janusGraphDao.rollback();
1111                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse
1112                         (storageStatus.right().value(), ComponentTypeEnum.SERVICE));
1113             }
1114             janusGraphDao.commit();
1115             log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
1116
1117         } catch (ComponentException e){
1118             log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
1119             janusGraphDao.rollback();
1120             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1121         } finally {
1122               graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1123         }
1124         return result.left().value();
1125     }
1126
1127     private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
1128         Service serviceToDelete = new Service();
1129         serviceToDelete.setUniqueId(serviceId);
1130         serviceToDelete.setForwardingPaths(new HashMap<>());
1131         pathIdsToDelete.forEach(pathIdToDelete ->  serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
1132         return serviceToDelete;
1133     }
1134
1135     public Service updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1136         return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
1137     }
1138
1139     public Service createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
1140         return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
1141     }
1142
1143     private ForwardingPathDataDefinition  getTrimmedValues(ForwardingPathDataDefinition path){
1144         ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
1145         dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
1146         dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
1147         dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
1148         dataDefinition.setUniqueId(path.getUniqueId());
1149         dataDefinition.setPathElements(path.getPathElements());
1150         dataDefinition.setDescription(path.getDescription());
1151         dataDefinition.setToscaResourceName(path.getToscaResourceName());
1152         return  dataDefinition;
1153     }
1154
1155     private Service createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
1156         validateUserAndRole(serviceUpdate, user, errorContext);
1157
1158         Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
1159
1160         Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
1161                 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
1162                         entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
1163
1164         forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
1165                 serviceId, isUpdate);
1166
1167         Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
1168
1169         if(serviceStorageOperationStatusEither.isRight()){
1170             StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
1171             log.debug("Failed to fetch service information by service id, error {}", errorStatus);
1172             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
1173         }
1174         Service storedService = serviceStorageOperationStatusEither.left().value();
1175
1176         Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1177         Component component = getForwardingPathOriginComponent();
1178         final String toscaResourceName;
1179         if (  component.getComponentType() == ComponentTypeEnum.RESOURCE) {
1180             toscaResourceName = ((Resource) component).getToscaResourceName();
1181         } else {
1182             toscaResourceName = "";
1183         }
1184         if (lock) {
1185            lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
1186            log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
1187         }
1188         Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
1189         try {
1190             trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
1191
1192             populateForwardingPaths(serviceId, isUpdate, trimmedForwardingPaths, resultMap);
1193             janusGraphDao.commit();
1194         } finally {
1195             if (lock) {
1196                 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
1197             }
1198         }
1199         return createServiceWithForwardingPathForResponse(serviceId, resultMap);
1200     }
1201
1202     private Component getForwardingPathOriginComponent() {
1203         Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
1204         if (forwardingPathOrigin.isRight()) {
1205             StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
1206             log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
1207             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(errorStatus));
1208         }
1209         return forwardingPathOrigin.left().value();
1210     }
1211
1212     private void populateForwardingPaths(String serviceId, boolean isUpdate, Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths, Map<String, ForwardingPathDataDefinition> resultMap) {
1213         Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
1214         try {
1215             for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
1216                 if (isUpdate) {
1217                     result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
1218                 } else {
1219                     result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
1220                 }
1221                 if (result.isRight()) {
1222                     janusGraphDao.rollback();
1223                     throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(
1224                         componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
1225                         ""));
1226                 } else {
1227                     ForwardingPathDataDefinition fpDataDefinition = result.left().value();
1228                     resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
1229                 }
1230             }
1231
1232         } catch (ComponentException e) {
1233             janusGraphDao.rollback();
1234             log.error("Exception occurred during add or update forwarding path property values: {}",
1235                     e.getMessage(), e);
1236             throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
1237         }
1238     }
1239
1240     private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
1241         Service service = new Service();
1242         service.setUniqueId(serviceId);
1243         service.setForwardingPaths(forwardingPathDataDefinitionMap);
1244         return service;
1245     }
1246
1247     private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
1248         user = validateUser(user, errorContext, serviceUpdate, null, false);
1249         validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
1250     }
1251
1252     @VisibleForTesting
1253     Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
1254
1255         try {
1256             boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
1257             Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1258             if (response.isRight()) {
1259                 ResponseFormat errorResponse = response.right().value();
1260                 return Either.right(errorResponse);
1261             }
1262
1263             verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
1264             verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
1265             verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
1266             verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
1267
1268             response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
1269             if (response.isRight()) {
1270                 return Either.right(response.right().value());
1271             }
1272
1273             verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
1274
1275             if (serviceUpdate.getProjectCode() != null) {
1276                 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1277                 if (response.isRight()) {
1278                     return Either.right(response.right().value());
1279                 }
1280             }
1281
1282             response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
1283             if (response.isRight()) {
1284                 return Either.right(response.right().value());
1285             }
1286
1287             verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
1288             verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
1289
1290             response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1291             if (response.isRight()) {
1292                 return Either.right(response.right().value());
1293             }
1294
1295             response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1296             if (response.isRight()) {
1297                 return Either.right(response.right().value());
1298             }
1299
1300             response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1301             if (response.isRight()) {
1302                 return Either.right(response.right().value());
1303             }
1304
1305             verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
1306             verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
1307             verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
1308             verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
1309
1310             validateAndUpdateServiceType(currentService, serviceUpdate);
1311             validateAndUpdateServiceFunction(currentService, serviceUpdate);
1312
1313             response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1314             if (response.isRight()) {
1315                 return Either.right(response.right().value());
1316             }
1317
1318             response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
1319             if (response.isRight()) {
1320                 return Either.right(response.right().value());
1321             }
1322
1323             verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
1324
1325             validateAndUpdateEcompNaming(currentService, serviceUpdate);
1326
1327             currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
1328             return Either.left(currentService);
1329
1330         } catch (ComponentException exception) {
1331             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1332             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
1333                     AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1334             return Either.right(responseFormat);
1335         }
1336     }
1337
1338     private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1339         if (updatedValue != null && !updatedValue.equals(originalValue)) {
1340             log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1341         }
1342     }
1343
1344     private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1345         Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1346         Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1347         if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1348             currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1349         }
1350         String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1351         if (currentService.isEcompGeneratedNaming() != null && currentService.isEcompGeneratedNaming()) {
1352             currentService.setNamingPolicy(namingPolicyUpdate);
1353         } else {
1354             if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1355                 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1356             }
1357             currentService.setNamingPolicy("");
1358         }
1359     }
1360
1361     private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1362         String contactIdUpdated = serviceUpdate.getContactId();
1363         String contactIdCurrent = currentService.getContactId();
1364         if (!contactIdCurrent.equals(contactIdUpdated)) {
1365             componentContactIdValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1366             currentService.setContactId(contactIdUpdated.toLowerCase());
1367         }
1368         return Either.left(true);
1369     }
1370
1371     private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1372         List<String> tagsUpdated = serviceUpdate.getTags();
1373         List<String> tagsCurrent = currentService.getTags();
1374         if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1375             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1376             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1377             return Either.right(responseFormat);
1378         }
1379
1380         if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1381             componentTagsValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1382             currentService.setTags(tagsUpdated);
1383         }
1384         return Either.left(true);
1385     }
1386
1387     private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1388         String descriptionUpdated = serviceUpdate.getDescription();
1389         String descriptionCurrent = currentService.getDescription();
1390         if (!descriptionCurrent.equals(descriptionUpdated)) {
1391             componentDescriptionValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1392             currentService.setDescription(serviceUpdate.getDescription());
1393         }
1394         return Either.left(true);
1395     }
1396
1397     private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1398         String projectCodeUpdated = serviceUpdate.getProjectCode();
1399         String projectCodeCurrent = currentService.getProjectCode();
1400         if (StringUtils.isEmpty(projectCodeCurrent)
1401                 || !projectCodeCurrent.equals(projectCodeUpdated)) {
1402
1403             try {
1404                 componentProjectCodeValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1405             } catch (ComponentException exp) {
1406                 ResponseFormat errorRespons = exp.getResponseFormat();
1407                 return Either.right(errorRespons);
1408             }
1409             currentService.setProjectCode(projectCodeUpdated);
1410
1411         }
1412         return Either.left(true);
1413     }
1414
1415     private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1416         String iconUpdated = serviceUpdate.getIcon();
1417         String iconCurrent = currentService.getIcon();
1418         if (!iconCurrent.equals(iconUpdated)) {
1419             if (!hasBeenCertified) {
1420                 componentIconValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1421                 currentService.setIcon(iconUpdated);
1422             } else {
1423                 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1424                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1425                 return Either.right(errorResponse);
1426             }
1427         }
1428         return Either.left(true);
1429     }
1430
1431     private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1432         String serviceNameUpdated = serviceUpdate.getName();
1433         String serviceNameCurrent = currentService.getName();
1434         if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1435             if (!hasBeenCertified) {
1436                 componentNameValidator.validateAndCorrectField(user, serviceUpdate, auditingAction);
1437                 try {
1438                     componentNameValidator.validateComponentNameUnique(user, serviceUpdate, auditingAction);
1439                 } catch (ComponentException exp) {
1440                     return Either.right(exp.getResponseFormat());
1441                 }
1442                 currentService.setName(serviceNameUpdated);
1443                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1444                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1445
1446             } else {
1447                 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1448                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1449                 return Either.right(errorResponse);
1450             }
1451         }
1452         return Either.left(true);
1453     }
1454
1455     private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1456         String updatedServiceType = updatedService.getServiceType();
1457         String currentServiceType = currentService.getServiceType();
1458         if (!currentServiceType.equals(updatedServiceType)) {
1459             serviceTypeValidator.validateAndCorrectField(null, updatedService, null);
1460             currentService.setServiceType(updatedServiceType);
1461         }
1462     }
1463
1464     private void validateAndUpdateServiceFunction(Service currentService, Service updatedService) {
1465         String updatedServiceFunction = updatedService.getServiceFunction();
1466         String currentServiceFunction = currentService.getServiceFunction();
1467         if (!currentServiceFunction.equals(updatedServiceFunction)) {
1468             serviceFunctionValidator.validateAndCorrectField(null, updatedService, null);
1469             currentService.setServiceFunction(updatedService.getServiceFunction());
1470         }
1471     }
1472
1473     private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1474         String updatedServiceRole = updatedService.getServiceRole();
1475         String currentServiceRole = currentService.getServiceRole();
1476         if (!currentServiceRole.equals(updatedServiceRole)) {
1477             try {
1478                 serviceRoleValidator.validateAndCorrectField(user, updatedService, auditingAction);
1479             } catch (ComponentException exp) {
1480                 ResponseFormat errorResponse = exp.getResponseFormat();
1481                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1482                 return Either.right(errorResponse);
1483             }
1484             currentService.setServiceRole(updatedServiceRole);
1485         }
1486         return Either.left(true);
1487     }
1488
1489     private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1490         String updatedInstaType= updatedService.getInstantiationType();
1491         String currentInstaType = currentService.getInstantiationType();
1492         if (!currentInstaType.equals(updatedInstaType)) {
1493             try {
1494                 serviceInstantiationTypeValidator.validateAndCorrectField(user, updatedService, auditingAction);
1495             } catch (ComponentException exp) {
1496                 ResponseFormat errorResponse = exp.getResponseFormat();
1497                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1498                 return Either.right(errorResponse);
1499             }
1500             currentService.setInstantiationType(updatedInstaType);
1501         }
1502         return Either.left(true);
1503     }
1504
1505     private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1506         try {
1507             List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1508             List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1509             serviceCategoryValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1510             if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1511                 if (!hasBeenCertified) {
1512                     currentService.setCategories(categoryUpdated);
1513                 } else {
1514                     log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1515                     ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1516                     return Either.right(errorResponse);
1517                 }
1518             }
1519         } catch (ComponentException exp) {
1520             return Either.right(exp.getResponseFormat());
1521         }
1522         return Either.left(true);
1523
1524     }
1525
1526     public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1527         Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1528         if (serviceResponseFormatEither.isRight()){
1529             return Either.right(serviceResponseFormatEither.right().value());
1530         }
1531         final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1532         return Either.left(serviceRelations);
1533
1534
1535     }
1536
1537     public ResponseFormat deleteService(String serviceId, User user) {
1538         ResponseFormat responseFormat;
1539
1540         validateUserExists(user);
1541         Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1542         if (serviceStatus.isRight()) {
1543             log.debug("failed to get service {}", serviceId);
1544             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1545         }
1546
1547         Service service = serviceStatus.left().value();
1548
1549         StorageOperationStatus result = StorageOperationStatus.OK;
1550         try {
1551             lockComponent(service, "Mark service to delete");
1552             result = markComponentToDelete(service);
1553             if (result == StorageOperationStatus.OK) {
1554                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1555             } else {
1556                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1557                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1558             }
1559             return responseFormat;
1560         }catch (ComponentException e){
1561             return e.getResponseFormat();
1562         }finally {
1563             if (result == null || result != StorageOperationStatus.OK) {
1564                 log.warn("operation failed. do rollback");
1565                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1566                 janusGraphDao.rollback();
1567             } else {
1568                 log.debug("operation success. do commit");
1569                 janusGraphDao.commit();
1570             }
1571             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1572         }
1573     }
1574
1575     public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1576         ResponseFormat responseFormat;
1577         String ecompErrorContext = "delete service";
1578         validateUserNotEmpty(user, ecompErrorContext);
1579         user = validateUserExists(user);
1580
1581         Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1582         if (getResult.isRight()) {
1583             return getResult.right().value();
1584         }
1585         Service service = getResult.left().value();
1586
1587         StorageOperationStatus result = StorageOperationStatus.OK;
1588
1589         try {
1590             lockComponent(service, "Mark service to delete");
1591             result = markComponentToDelete(service);
1592             if (result == StorageOperationStatus.OK) {
1593                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1594             } else {
1595                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1596                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1597             }
1598             return responseFormat;
1599
1600         }catch (ComponentException e){
1601             result = StorageOperationStatus.GENERAL_ERROR;
1602             return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1603         }finally {
1604             if (result == null || result != StorageOperationStatus.OK) {
1605                 log.warn("operation failed. do rollback");
1606                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1607                 janusGraphDao.rollback();
1608             } else {
1609                 log.debug("operation success. do commit");
1610                 janusGraphDao.commit();
1611             }
1612             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1613         }
1614     }
1615
1616     public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1617         String ecompErrorContext = "Get service";
1618         validateUserNotEmpty(user, ecompErrorContext);
1619         validateUserExists(user);
1620
1621         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1622         if (storageStatus.isRight()) {
1623             log.debug("failed to get service by id {}", serviceId);
1624             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1625         }
1626
1627         if(!(storageStatus.left().value() instanceof Service)){
1628             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1629         }
1630         Service service = storageStatus.left().value();
1631         return Either.left(service);
1632
1633
1634
1635
1636     }
1637
1638     public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1639         validateUserExists(userId);
1640         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1641         if (storageStatus.isRight()) {
1642             log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1643             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1644         }
1645         Service service = storageStatus.left().value();
1646         return Either.left(service);
1647     }
1648
1649     @SuppressWarnings("unchecked")
1650     private void createMandatoryArtifactsData(Service service, User user) {
1651         // create mandatory artifacts
1652
1653         // TODO it must be removed after that artifact uniqueId creation will be
1654         // moved to ArtifactOperation
1655         String serviceUniqueId = service.getUniqueId();
1656         Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1657         if (artifactMap == null)
1658             artifactMap = new HashMap<>();
1659
1660         Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1661         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1662
1663         String category = service.getCategories().get(0).getName();
1664         boolean isCreateArtifact = true;
1665         if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1666             for (String exlude : exludeServiceCategory) {
1667                 if (exlude.equalsIgnoreCase(category)) {
1668                     isCreateArtifact = false;
1669                     break;
1670                 }
1671             }
1672
1673         }
1674
1675         if (informationalServiceArtifacts != null && isCreateArtifact) {
1676             Set<String> keys = informationalServiceArtifacts.keySet();
1677             for (String informationalServiceArtifactName : keys) {
1678                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1679                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1680                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1681
1682             }
1683
1684             service.setArtifacts(artifactMap);
1685         }
1686     }
1687
1688     private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1689
1690         ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1691
1692         if (isServiceApi) {
1693             artifactInfo.setMandatory(false);
1694             artifactInfo.setServiceApi(true);
1695         }
1696         return artifactInfo;
1697     }
1698
1699     private DistributionTransitionEnum validateTransitionEnum(String distributionTransition) {
1700         DistributionTransitionEnum transitionEnum;
1701
1702         transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1703         if (transitionEnum == null) {
1704             BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1705             log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1706             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_DISTRIBUTION_STATUS, distributionTransition));
1707         }
1708
1709         return transitionEnum;
1710     }
1711
1712     private String validateComment(LifecycleChangeInfoWithAction comment) {
1713         if (comment==null || StringUtils.isEmpty(comment.getUserRemarks())) {
1714             return "";
1715         }
1716         String data = comment.getUserRemarks();
1717         data = ValidationUtils.removeNoneUtf8Chars(data);
1718         data = ValidationUtils.removeHtmlTags(data);
1719         data = ValidationUtils.normaliseWhitespace(data);
1720         data = ValidationUtils.stripOctets(data);
1721
1722         if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1723             BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1724             log.debug("user comment exceeds limit.");
1725             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1726         }
1727         if (!ValidationUtils.validateCommentPattern(data)) {
1728             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1729         }
1730
1731         return data;
1732     }
1733
1734     private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1735         log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1736         componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1737                 ResourceVersionInfo.newBuilder()
1738                         .state(component.getLifecycleState().name())
1739                         .version(component.getVersion())
1740                         .build(),
1741                 comment);
1742     }
1743
1744     private String getEnvNameFromConfiguration() {
1745         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1746         log.trace("Update environment name to be {}", configuredEnvName);
1747         return configuredEnvName;
1748     }
1749
1750     public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1751
1752         Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1753         if (activationRequestInformationEither.isRight()) {
1754             return Either.right(activationRequestInformationEither.right().value());
1755         }
1756
1757         ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1758
1759         Either<String, ResponseFormat> result = null;
1760         String did = ThreadLocalsHolder.getUuid();
1761         Service service = activationRequestInformation.getServiceToActivate();
1762         result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1763         return result;
1764     }
1765
1766     public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1767         String envName = getEnvNameFromConfiguration();
1768         INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1769         ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1770         if (notifyServiceResponse == ActionStatus.OK) {
1771             return Either.left(did);
1772         } else {
1773             BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1774             log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1775             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1776             return Either.right(error);
1777         }
1778     }
1779
1780     public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1781
1782         User user = validateUserExists(modifier.getUserId());
1783         validateUserRole(user, Collections.singletonList(Role.DESIGNER));
1784         Either<Service, ResponseFormat> result;
1785         ResponseFormat response;
1786         Service updatedService;
1787         String did = ThreadLocalsHolder.getUuid();
1788          // DE194021
1789         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1790         if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1791             log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1792             envName = configuredEnvName;
1793         }
1794         // DE194021
1795
1796         ServletContext servletContext = request.getSession().getServletContext();
1797         boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1798         if (!isDistributionEngineUp) {
1799             BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1800             log.debug("Distribution Engine is DOWN");
1801             response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1802             return Either.right(response);
1803         }
1804
1805         Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1806         if (serviceRes.isRight()) {
1807             log.debug("failed retrieving service");
1808             response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1809             componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1810                     new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1811                     ResourceVersionInfo.newBuilder()
1812                             .build(),
1813                     did);
1814             return Either.right(response);
1815         }
1816         Service service = serviceRes.left().value();
1817         if (service.isArchived()) {
1818             log.info("Component is archived. Component id: {}", serviceId);
1819             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName()));
1820         }
1821         if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1822             log.info("service {} is  not available for distribution. Should be in certified state", service.getUniqueId());
1823             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1824             return Either.right(responseFormat);
1825         }
1826         String dcurrStatus = service.getDistributionStatus().name();
1827         String updatedStatus = dcurrStatus;
1828         StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1829         if (readyForDistribution == StorageOperationStatus.OK) {
1830             INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1831             ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1832             if (notifyServiceResponse == ActionStatus.OK) {
1833                 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1834                 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1835                     updatedService = updateStateRes.left().value();
1836                     updatedStatus = updatedService.getDistributionStatus().name();
1837                 } else {
1838                     // The response is not relevant
1839                     updatedService = service;
1840                 }
1841                 ASDCKpiApi.countActivatedDistribution();
1842                 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1843                 result = Either.left(updatedService);
1844             } else {
1845                 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1846                 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1847                 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1848                 result = Either.right(response);
1849             }
1850         } else {
1851             response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution, ComponentTypeEnum.SERVICE), envName);
1852             result = Either.right(response);
1853         }
1854         componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1855                 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1856                 ResourceVersionInfo.newBuilder()
1857                         .distributionStatus(dcurrStatus)
1858                         .build(),
1859                 ResourceVersionInfo.newBuilder()
1860                         .distributionStatus(updatedStatus)
1861                         .build(),
1862                 null, null, did);
1863         return result;
1864     }
1865
1866     // convert to private after deletion of temp url
1867     public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1868
1869         validateUserExists(user.getUserId());
1870
1871         String serviceId = service.getUniqueId();
1872          lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1873         try {
1874             Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1875             if (result.isRight()) {
1876                 janusGraphDao.rollback();
1877                 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1878                 log.debug("service {}  change distribution status failed", serviceId);
1879                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1880             }
1881             janusGraphDao.commit();
1882             updateCatalog(service, ChangeTypeEnum.LIFECYCLE);
1883             return Either.left(result.left().value());
1884         } finally {
1885             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1886         }
1887     }
1888
1889     public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1890
1891         validateUserExists(user.getUserId());
1892         log.debug("mark distribution deployed");
1893
1894         AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1895         Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1896         if (getServiceResponse.isRight()) {
1897             BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1898             log.debug("service {} not found", serviceId);
1899             ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1900
1901             return Either.right(responseFormat);
1902         }
1903
1904         Service service = getServiceResponse.left().value();
1905         user = validateRoleForDeploy(did, user, auditAction, service);
1906         return checkDistributionAndDeploy(did, user, auditAction, service);
1907
1908     }
1909
1910     public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1911         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1912                 // Only one VF Module Artifact per instance - add it to a list of one
1913                 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1914
1915         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1916
1917     }
1918
1919     private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
1920         List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1921
1922         if (ri.getOriginType() == OriginTypeEnum.VF) {
1923             asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
1924         }
1925         return asList;
1926     }
1927
1928     private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
1929         Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1930         if(currVF.getGroupInstances() != null){
1931             currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1932         }
1933         return currVF.getGroupInstances();
1934     }
1935
1936     private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
1937         ArtifactDefinition vfModuleAertifact = null;
1938         if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1939             final Optional<ArtifactDefinition> optionalVfModuleArtifact =
1940                 currVF.getDeploymentArtifacts().values().stream()
1941                     .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType()))
1942                     .findAny();
1943             if (optionalVfModuleArtifact.isPresent()) {
1944                 vfModuleAertifact = optionalVfModuleArtifact.get();
1945             }
1946         }
1947         if (vfModuleAertifact == null) {
1948             Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
1949             if (createVfModuleArtifact.isLeft()) {
1950                 vfModuleAertifact = createVfModuleArtifact.left().value();
1951             } else {
1952                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1953             }
1954         }
1955         return vfModuleAertifact;
1956     }
1957
1958     private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1959         List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
1960         if (groupsForCurrVF != null) {
1961             for (GroupInstance groupInstance : groupsForCurrVF) {
1962                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1963                 vfModulePayloads.add(modulePayload);
1964             }
1965             vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
1966
1967             final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1968
1969             String vfModulePayloadString = gson.toJson(vfModulePayloads);
1970             payloadWrapper.setInnerElement(vfModulePayloadString);
1971         }
1972
1973     }
1974
1975     private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
1976         ArtifactDefinition vfModuleArtifact = null;
1977         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1978         Wrapper<String> payloadWrapper = new Wrapper<>();
1979         List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
1980         if (responseWrapper.isEmpty()) {
1981             fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1982         }
1983         if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1984             vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
1985         }
1986         if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
1987             vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
1988         }
1989
1990         Either<ArtifactDefinition, ResponseFormat> result;
1991         if (responseWrapper.isEmpty()) {
1992             result = Either.left(vfModuleArtifact);
1993         } else {
1994             result = Either.right(responseWrapper.getInnerElement());
1995         }
1996
1997         return result;
1998     }
1999
2000     private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2001         ArtifactDefinition result = null;
2002         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2003                 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2004         if (eitherPayload.isLeft()) {
2005             result = eitherPayload.left().value();
2006         } else {
2007             responseWrapper.setInnerElement(eitherPayload.right().value());
2008         }
2009         if (result == null) {
2010             result = vfModuleArtifact;
2011         }
2012
2013         return result;
2014     }
2015
2016     private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2017
2018         ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2019         String newCheckSum = null;
2020
2021         vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2022         vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2023         vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2024         vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2025         vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2026         vfModuleArtifactDefinition.setTimeout(0);
2027         vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2028         vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2029         if (vfModulePayloadString != null) {
2030             newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2031         }
2032         vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2033
2034         Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation.addArtifactToComponent(
2035                 vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2036
2037         Either<ArtifactDefinition, ResponseFormat> result;
2038         if (addArtifactToComponent.isLeft()) {
2039             result = Either.left(addArtifactToComponent.left().value());
2040         } else {
2041             result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
2042         }
2043
2044         return result;
2045     }
2046
2047     public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2048
2049         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2050                 // Get All Deployment Artifacts
2051                 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2052                         // Filter in Only Heat Env
2053                                 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2054                         // Create ArtifactGenerator from those Artifacts
2055                                 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2056
2057         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2058
2059     }
2060
2061     private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2062
2063         // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2064         // service
2065         if (service.getComponentInstances() != null) {
2066             List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2067             if (artifactGenList != null && !artifactGenList.isEmpty()) {
2068                 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
2069                 if (callRes != null) return callRes;
2070             }
2071         }
2072         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2073         if (storageStatus.isRight()) {
2074             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2075         }
2076
2077         Service currentService = storageStatus.left().value();
2078
2079         return Either.left(currentService);
2080
2081     }
2082
2083     private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
2084         for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2085             Either<CallVal, ResponseFormat> callRes;
2086             try {
2087                 callRes = entry.call();
2088                 if (callRes.isRight()) {
2089                     log.debug("Failed to generate artifact error : {}", callRes.right().value());
2090                     return Either.right(callRes.right().value());
2091                 }
2092             } catch (Exception e) {
2093                 log.debug("Failed to generate artifact exception : {}", e);
2094                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2095             }
2096         }
2097         return null;
2098     }
2099
2100     abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2101
2102     }
2103
2104     class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2105         ArtifactDefinition artifactDefinition;
2106         Service service;
2107         String resourceInstanceName;
2108         User modifier;
2109         String instanceId;
2110         boolean shouldLock;
2111         boolean inTransaction;
2112
2113         HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2114             this.artifactDefinition = artifactDefinition;
2115             this.service = service;
2116             this.resourceInstanceName = resourceInstanceName;
2117             this.modifier = modifier;
2118             this.shouldLock = shouldLock;
2119             this.instanceId = instanceId;
2120             this.inTransaction = inTransaction;
2121         }
2122
2123         @Override
2124         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2125             return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2126         }
2127
2128         public ArtifactDefinition getArtifactDefinition() {
2129             return artifactDefinition;
2130         }
2131
2132     }
2133
2134     class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2135         private User user;
2136         private ComponentInstance componentInstance;
2137         private Service service;
2138         boolean shouldLock;
2139         boolean inTransaction;
2140
2141         @Override
2142         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2143             return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2144         }
2145
2146         private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2147             super();
2148             this.user = user;
2149             this.componentInstance = componentInstance;
2150             this.service = service;
2151             this.shouldLock = shouldLock;
2152             this.inTransaction = inTransaction;
2153         }
2154
2155     }
2156
2157     private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2158         boolean isDeployed = isDistributionDeployed(distributionId);
2159         if (isDeployed) {
2160             return Either.left(service);
2161         }
2162         Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2163         if (distributionSuccess.isRight()) {
2164             return Either.right(distributionSuccess.right().value());
2165         }
2166
2167         log.debug("mark distribution {} as deployed - success", distributionId);
2168         componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2169         return Either.left(service);
2170     }
2171
2172     private boolean isDistributionDeployed(String distributionId) {
2173         Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2174
2175         boolean isDeployed = false;
2176         if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2177             // already deployed
2178             log.debug("distribution {} is already deployed", distributionId);
2179             isDeployed = true;
2180         }
2181         return isDeployed;
2182     }
2183
2184     protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2185
2186         log.trace("checkDistributionSuccess");
2187         // get all "DRequest" records for this distribution
2188
2189         Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2190         if (distRequestsResponse.isRight()) {
2191             ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2192             return Either.right(error);
2193         }
2194
2195         List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2196         if (distributionRequests.isEmpty()) {
2197             BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2198             log.info("distribution {} is not found", did);
2199             ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2200             return Either.right(error);
2201         }
2202         boolean isRequestSucceeded = false;
2203         for (ResourceAdminEvent event : distributionRequests) {
2204             String eventStatus = event.getStatus();
2205             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2206                 isRequestSucceeded = true;
2207                 break;
2208             }
2209         }
2210
2211         // get all "DNotify" records for this distribution
2212         Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2213         if (distNotificationsResponse.isRight()) {
2214             ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2215             return Either.right(error);
2216         }
2217
2218         List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2219         boolean isNotificationsSucceeded = false;
2220         for (DistributionNotificationEvent event : distributionNotifications) {
2221             String eventStatus = event.getStatus();
2222             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2223                 isNotificationsSucceeded = true;
2224                 break;
2225             }
2226         }
2227
2228         // if request failed OR there are notifications that failed
2229         if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2230
2231             log.info("distribution {} has failed", did);
2232             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2233             auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2234             return Either.right(error);
2235         }
2236         return Either.left(true);
2237     }
2238
2239     private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2240
2241         ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2242         String message = "";
2243         if (error.getMessageId() != null) {
2244             message = error.getMessageId() + ": ";
2245         }
2246         message += error.getFormattedMessage();
2247
2248         if (service != null) {
2249             componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2250         } else {
2251             componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2252         }
2253         return error;
2254     }
2255
2256     private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2257         user = userAdmin.getUser(user.getUserId());
2258         log.debug("validate user role");
2259         List<Role> roles = new ArrayList<>();
2260         roles.add(Role.ADMIN);
2261         roles.add(Role.DESIGNER);
2262         try{
2263             validateUserRole(user, service, roles, auditAction, null);
2264         } catch (ByActionStatusComponentException e){
2265             log.info("role {} is not allowed to perform this action", user.getRole());
2266             auditDeployError(did, user, auditAction, service, e.getActionStatus());
2267             throw e;
2268         }
2269         return user;
2270     }
2271
2272     @Override
2273     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2274         Service service = (Service) component;
2275         Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2276         if (artifactMap == null) {
2277             artifactMap = new HashMap<>();
2278         }
2279         service.setDeploymentArtifacts(artifactMap);
2280     }
2281
2282     @Override
2283     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2284         return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2285     }
2286
2287     private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2288         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2289         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2290         return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2291     }
2292
2293     @Override
2294     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2295         return componentInstanceBusinessLogic;
2296     }
2297
2298     @Override
2299     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2300
2301         validateUserExists(userId);
2302         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2303         if (getComponentRes.isRight()) {
2304             ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2305             return Either.right(responseFormat);
2306         }
2307
2308         List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2309
2310         return Either.left(componentInstances);
2311     }
2312
2313     @Autowired
2314     public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2315         this.forwardingPathOperation = forwardingPathOperation;
2316     }
2317
2318     /**
2319      * 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
2320      *
2321      */
2322     public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2323
2324         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2325         Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2326         Component component = null;
2327         Either<Boolean, ResponseFormat> lockResult = null;
2328         log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2329         try {
2330             validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2331             if (validateUserAndComponentRes.isRight()) {
2332                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
2333                 actionResult = Either.right(validateUserAndComponentRes.right().value());
2334             }
2335             if (actionResult == null) {
2336                 component = validateUserAndComponentRes.left().value().getKey();
2337                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2338                 if (lockResult.isRight()) {
2339                     log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2340                     actionResult = Either.right(lockResult.right().value());
2341                 } else {
2342                     log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2343                 }
2344             }
2345             if (actionResult == null) {
2346                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2347                 if (actionResult.isRight()) {
2348                     log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2349                 }
2350             }
2351         } catch (Exception e) {
2352             log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2353             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2354         } finally {
2355             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2356                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2357             }
2358         }
2359         return actionResult;
2360     }
2361
2362     private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2363
2364         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2365         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2366         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2367         ComponentInstance relatedComponentInstance = null;
2368         GroupInstance oldGroupInstance = null;
2369         Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2370         GroupInstance updatedGroupInstance = null;
2371         boolean inTransaction = true;
2372         findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2373         if (findGroupInstanceRes.isRight()) {
2374             log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2375             actionResult = Either.right(findGroupInstanceRes.right().value());
2376         }
2377         if (actionResult == null) {
2378             oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2379             relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2380             updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2381             if (updateGroupInstanceResult.isRight()) {
2382                 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2383                 actionResult = Either.right(updateGroupInstanceResult.right().value());
2384             }
2385         }
2386         if (actionResult == null) {
2387             updatedGroupInstance = updateGroupInstanceResult.left().value();
2388             if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2389                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2390                 if (updateParentsModificationTimeRes.isRight()) {
2391                     log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2392                     actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2393                 }
2394             }
2395         }
2396         if (actionResult == null) {
2397             actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2398         }
2399         return actionResult;
2400     }
2401
2402     private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2403                                                                                                                                                   boolean inTranscation) {
2404
2405         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2406         Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2407         Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2408                 updatedGroupInstance.getModificationTime(), inTranscation);
2409         if (updateComponentInstanceRes.isRight()) {
2410             log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2411             actionResult = Either.right(updateComponentInstanceRes.right().value());
2412         } else {
2413             serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2414             if (serviceMetadataUpdateResult.isRight()) {
2415                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2416                 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2417             } else {
2418                 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2419             }
2420         }
2421         return actionResult;
2422     }
2423
2424     private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2425
2426         Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2427         User currUser = null;
2428         Component component = null;
2429         Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2430         if (validationUserResult.isRight()) {
2431             log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2432             result = Either.right(validationUserResult.right().value());
2433         }
2434         if (result == null) {
2435             currUser = validationUserResult.left().value();
2436             try {
2437                 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2438                 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2439                     log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2440                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2441                 }
2442             } catch (ComponentException e) {
2443                 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2444                 result = Either.right(e.getResponseFormat());
2445             }
2446         }
2447
2448         if (result == null) {
2449             result = Either.left(new ImmutablePair<>(component, currUser));
2450         }
2451         return result;
2452     }
2453
2454     private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2455
2456         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2457         GroupInstance groupInstance = null;
2458         ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2459         if (foundComponentInstance == null) {
2460             log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2461             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2462         }
2463         else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2464             groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2465             if (groupInstance == null) {
2466                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2467                 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2468             }
2469         }
2470         if (actionResult == null) {
2471             actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2472         }
2473         return actionResult;
2474     }
2475
2476     private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2477         ComponentInstance componentInstance = null;
2478         if (isNotEmpty(component.getComponentInstances())) {
2479             componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2480         }
2481         return componentInstance;
2482     }
2483
2484     private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2485         User user = validateUser(modifier, ecompErrorContext, null, null, false);
2486         List<Role> roles = new ArrayList<>();
2487         roles.add(Role.ADMIN);
2488         roles.add(Role.DESIGNER);
2489         validateUserRole(user, roles);
2490         return Either.left(user);
2491     }
2492
2493     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2494
2495         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2496         paramsToReturn.setIgnoreComponentInstancesProperties(false);
2497         Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2498
2499         if (serviceResultEither.isRight()) {
2500             if(serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2501                 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2502                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2503             }
2504
2505             log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2506             return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2507         }
2508
2509         Service service = serviceResultEither.left().value();
2510                 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2511                         ListUtils.emptyIfNull(service.getInputs())
2512                                         .forEach(input -> input.setConstraints(setInputConstraint(input)));
2513                 }
2514
2515         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2516         return Either.left(dataTransfer);
2517     }
2518
2519     @Autowired(required = false)
2520     public void setServiceCreationPluginList(List<ServiceCreationPlugin> serviceCreationPluginList) {
2521         this.serviceCreationPluginList = serviceCreationPluginList;
2522     }
2523 }