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