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