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