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