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