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