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