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