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