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