Configure a new Artifact Type
[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.InterfacesOperationsConverter.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             final Optional<ArtifactDefinition> optionalVfModuleArtifact =
1913                 currVF.getDeploymentArtifacts().values().stream()
1914                     .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType()))
1915                     .findAny();
1916             if (optionalVfModuleArtifact.isPresent()) {
1917                 vfModuleAertifact = optionalVfModuleArtifact.get();
1918             }
1919         }
1920         if (vfModuleAertifact == null) {
1921             Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
1922             if (createVfModuleArtifact.isLeft()) {
1923                 vfModuleAertifact = createVfModuleArtifact.left().value();
1924             } else {
1925                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1926             }
1927         }
1928         return vfModuleAertifact;
1929     }
1930
1931     private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1932         List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
1933         if (groupsForCurrVF != null) {
1934             for (GroupInstance groupInstance : groupsForCurrVF) {
1935                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1936                 vfModulePayloads.add(modulePayload);
1937             }
1938             vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
1939
1940             final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1941
1942             String vfModulePayloadString = gson.toJson(vfModulePayloads);
1943             payloadWrapper.setInnerElement(vfModulePayloadString);
1944         }
1945
1946     }
1947
1948     private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
1949         ArtifactDefinition vfModuleArtifact = null;
1950         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1951         Wrapper<String> payloadWrapper = new Wrapper<>();
1952         List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
1953         if (responseWrapper.isEmpty()) {
1954             fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1955         }
1956         if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1957             vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
1958         }
1959         if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
1960             vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
1961         }
1962
1963         Either<ArtifactDefinition, ResponseFormat> result;
1964         if (responseWrapper.isEmpty()) {
1965             result = Either.left(vfModuleArtifact);
1966         } else {
1967             result = Either.right(responseWrapper.getInnerElement());
1968         }
1969
1970         return result;
1971     }
1972
1973     private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
1974         ArtifactDefinition result = null;
1975         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
1976                 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
1977         if (eitherPayload.isLeft()) {
1978             result = eitherPayload.left().value();
1979         } else {
1980             responseWrapper.setInnerElement(eitherPayload.right().value());
1981         }
1982         if (result == null) {
1983             result = vfModuleArtifact;
1984         }
1985
1986         return result;
1987     }
1988
1989     private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
1990
1991         ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
1992         String newCheckSum = null;
1993
1994         vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
1995         vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
1996         vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
1997         vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
1998         vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
1999         vfModuleArtifactDefinition.setTimeout(0);
2000         vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2001         vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2002         if (vfModulePayloadString != null) {
2003             newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2004         }
2005         vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2006
2007         Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation.addArtifactToComponent(
2008                 vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2009
2010         Either<ArtifactDefinition, ResponseFormat> result;
2011         if (addArtifactToComponent.isLeft()) {
2012             result = Either.left(addArtifactToComponent.left().value());
2013         } else {
2014             result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
2015         }
2016
2017         return result;
2018     }
2019
2020     public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2021
2022         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2023                 // Get All Deployment Artifacts
2024                 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2025                         // Filter in Only Heat Env
2026                                 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2027                         // Create ArtifactGenerator from those Artifacts
2028                                 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2029
2030         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2031
2032     }
2033
2034     private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2035
2036         // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2037         // service
2038         if (service.getComponentInstances() != null) {
2039             List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2040             if (artifactGenList != null && !artifactGenList.isEmpty()) {
2041                 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
2042                 if (callRes != null) return callRes;
2043             }
2044         }
2045         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2046         if (storageStatus.isRight()) {
2047             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2048         }
2049
2050         Service currentService = storageStatus.left().value();
2051
2052         return Either.left(currentService);
2053
2054     }
2055
2056     private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
2057         for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2058             Either<CallVal, ResponseFormat> callRes;
2059             try {
2060                 callRes = entry.call();
2061                 if (callRes.isRight()) {
2062                     log.debug("Failed to generate artifact error : {}", callRes.right().value());
2063                     return Either.right(callRes.right().value());
2064                 }
2065             } catch (Exception e) {
2066                 log.debug("Failed to generate artifact exception : {}", e);
2067                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2068             }
2069         }
2070         return null;
2071     }
2072
2073     abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2074
2075     }
2076
2077     class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2078         ArtifactDefinition artifactDefinition;
2079         Service service;
2080         String resourceInstanceName;
2081         User modifier;
2082         String instanceId;
2083         boolean shouldLock;
2084         boolean inTransaction;
2085
2086         HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2087             this.artifactDefinition = artifactDefinition;
2088             this.service = service;
2089             this.resourceInstanceName = resourceInstanceName;
2090             this.modifier = modifier;
2091             this.shouldLock = shouldLock;
2092             this.instanceId = instanceId;
2093             this.inTransaction = inTransaction;
2094         }
2095
2096         @Override
2097         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2098             return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2099         }
2100
2101         public ArtifactDefinition getArtifactDefinition() {
2102             return artifactDefinition;
2103         }
2104
2105     }
2106
2107     class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2108         private User user;
2109         private ComponentInstance componentInstance;
2110         private Service service;
2111         boolean shouldLock;
2112         boolean inTransaction;
2113
2114         @Override
2115         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2116             return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2117         }
2118
2119         private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2120             super();
2121             this.user = user;
2122             this.componentInstance = componentInstance;
2123             this.service = service;
2124             this.shouldLock = shouldLock;
2125             this.inTransaction = inTransaction;
2126         }
2127
2128     }
2129
2130     private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2131         boolean isDeployed = isDistributionDeployed(distributionId);
2132         if (isDeployed) {
2133             return Either.left(service);
2134         }
2135         Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2136         if (distributionSuccess.isRight()) {
2137             return Either.right(distributionSuccess.right().value());
2138         }
2139
2140         log.debug("mark distribution {} as deployed - success", distributionId);
2141         componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2142         return Either.left(service);
2143     }
2144
2145     private boolean isDistributionDeployed(String distributionId) {
2146         Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2147
2148         boolean isDeployed = false;
2149         if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2150             // already deployed
2151             log.debug("distribution {} is already deployed", distributionId);
2152             isDeployed = true;
2153         }
2154         return isDeployed;
2155     }
2156
2157     protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2158
2159         log.trace("checkDistributionSuccess");
2160         // get all "DRequest" records for this distribution
2161
2162         Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2163         if (distRequestsResponse.isRight()) {
2164             ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2165             return Either.right(error);
2166         }
2167
2168         List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2169         if (distributionRequests.isEmpty()) {
2170             BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2171             log.info("distribution {} is not found", did);
2172             ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2173             return Either.right(error);
2174         }
2175         boolean isRequestSucceeded = false;
2176         for (ResourceAdminEvent event : distributionRequests) {
2177             String eventStatus = event.getStatus();
2178             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2179                 isRequestSucceeded = true;
2180                 break;
2181             }
2182         }
2183
2184         // get all "DNotify" records for this distribution
2185         Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2186         if (distNotificationsResponse.isRight()) {
2187             ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2188             return Either.right(error);
2189         }
2190
2191         List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2192         boolean isNotificationsSucceeded = false;
2193         for (DistributionNotificationEvent event : distributionNotifications) {
2194             String eventStatus = event.getStatus();
2195             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2196                 isNotificationsSucceeded = true;
2197                 break;
2198             }
2199         }
2200
2201         // if request failed OR there are notifications that failed
2202         if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2203
2204             log.info("distribution {} has failed", did);
2205             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2206             auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2207             return Either.right(error);
2208         }
2209         return Either.left(true);
2210     }
2211
2212     private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2213
2214         ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2215         String message = "";
2216         if (error.getMessageId() != null) {
2217             message = error.getMessageId() + ": ";
2218         }
2219         message += error.getFormattedMessage();
2220
2221         if (service != null) {
2222             componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2223         } else {
2224             componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2225         }
2226         return error;
2227     }
2228
2229     private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2230         user = userAdmin.getUser(user.getUserId());
2231         log.debug("validate user role");
2232         List<Role> roles = new ArrayList<>();
2233         roles.add(Role.ADMIN);
2234         roles.add(Role.DESIGNER);
2235         try{
2236             validateUserRole(user, service, roles, auditAction, null);
2237         } catch (ByActionStatusComponentException e){
2238             log.info("role {} is not allowed to perform this action", user.getRole());
2239             auditDeployError(did, user, auditAction, service, e.getActionStatus());
2240             throw e;
2241         }
2242         return user;
2243     }
2244
2245     @Override
2246     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2247         Service service = (Service) component;
2248         Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2249         if (artifactMap == null) {
2250             artifactMap = new HashMap<>();
2251         }
2252         service.setDeploymentArtifacts(artifactMap);
2253     }
2254
2255     @Override
2256     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2257         return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2258     }
2259
2260     private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2261         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2262         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2263         return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2264     }
2265
2266     @Override
2267     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2268         return componentInstanceBusinessLogic;
2269     }
2270
2271     @Override
2272     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2273
2274         validateUserExists(userId);
2275         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2276         if (getComponentRes.isRight()) {
2277             ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2278             return Either.right(responseFormat);
2279         }
2280
2281         List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2282
2283         return Either.left(componentInstances);
2284     }
2285
2286     @Autowired
2287     public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2288         this.forwardingPathOperation = forwardingPathOperation;
2289     }
2290
2291     /**
2292      * 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
2293      *
2294      */
2295     public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2296
2297         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2298         Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2299         Component component = null;
2300         Either<Boolean, ResponseFormat> lockResult = null;
2301         log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2302         try {
2303             validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2304             if (validateUserAndComponentRes.isRight()) {
2305                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
2306                 actionResult = Either.right(validateUserAndComponentRes.right().value());
2307             }
2308             if (actionResult == null) {
2309                 component = validateUserAndComponentRes.left().value().getKey();
2310                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2311                 if (lockResult.isRight()) {
2312                     log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2313                     actionResult = Either.right(lockResult.right().value());
2314                 } else {
2315                     log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2316                 }
2317             }
2318             if (actionResult == null) {
2319                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2320                 if (actionResult.isRight()) {
2321                     log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2322                 }
2323             }
2324         } catch (Exception e) {
2325             log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2326             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2327         } finally {
2328             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2329                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2330             }
2331         }
2332         return actionResult;
2333     }
2334
2335     private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2336
2337         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2338         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2339         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2340         ComponentInstance relatedComponentInstance = null;
2341         GroupInstance oldGroupInstance = null;
2342         Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2343         GroupInstance updatedGroupInstance = null;
2344         boolean inTransaction = true;
2345         findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2346         if (findGroupInstanceRes.isRight()) {
2347             log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2348             actionResult = Either.right(findGroupInstanceRes.right().value());
2349         }
2350         if (actionResult == null) {
2351             oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2352             relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2353             updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2354             if (updateGroupInstanceResult.isRight()) {
2355                 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2356                 actionResult = Either.right(updateGroupInstanceResult.right().value());
2357             }
2358         }
2359         if (actionResult == null) {
2360             updatedGroupInstance = updateGroupInstanceResult.left().value();
2361             if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2362                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2363                 if (updateParentsModificationTimeRes.isRight()) {
2364                     log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2365                     actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2366                 }
2367             }
2368         }
2369         if (actionResult == null) {
2370             actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2371         }
2372         return actionResult;
2373     }
2374
2375     private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2376                                                                                                                                                   boolean inTranscation) {
2377
2378         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2379         Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2380         Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2381                 updatedGroupInstance.getModificationTime(), inTranscation);
2382         if (updateComponentInstanceRes.isRight()) {
2383             log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2384             actionResult = Either.right(updateComponentInstanceRes.right().value());
2385         } else {
2386             serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2387             if (serviceMetadataUpdateResult.isRight()) {
2388                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2389                 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2390             } else {
2391                 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2392             }
2393         }
2394         return actionResult;
2395     }
2396
2397     private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2398
2399         Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2400         User currUser = null;
2401         Component component = null;
2402         Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2403         if (validationUserResult.isRight()) {
2404             log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2405             result = Either.right(validationUserResult.right().value());
2406         }
2407         if (result == null) {
2408             currUser = validationUserResult.left().value();
2409             try {
2410                 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2411                 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2412                     log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2413                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2414                 }
2415             } catch (ComponentException e) {
2416                 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2417                 result = Either.right(e.getResponseFormat());
2418             }
2419         }
2420
2421         if (result == null) {
2422             result = Either.left(new ImmutablePair<>(component, currUser));
2423         }
2424         return result;
2425     }
2426
2427     private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2428
2429         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2430         GroupInstance groupInstance = null;
2431         ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2432         if (foundComponentInstance == null) {
2433             log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2434             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2435         }
2436         else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2437             groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2438             if (groupInstance == null) {
2439                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2440                 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2441             }
2442         }
2443         if (actionResult == null) {
2444             actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2445         }
2446         return actionResult;
2447     }
2448
2449     private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2450         ComponentInstance componentInstance = null;
2451         if (isNotEmpty(component.getComponentInstances())) {
2452             componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2453         }
2454         return componentInstance;
2455     }
2456
2457     private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2458         User user = validateUser(modifier, ecompErrorContext, null, null, false);
2459         List<Role> roles = new ArrayList<>();
2460         roles.add(Role.ADMIN);
2461         roles.add(Role.DESIGNER);
2462         validateUserRole(user, roles);
2463         return Either.left(user);
2464     }
2465
2466     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2467
2468         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2469         paramsToReturn.setIgnoreComponentInstancesProperties(false);
2470         Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2471
2472         if (serviceResultEither.isRight()) {
2473             if(serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2474                 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2475                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2476             }
2477
2478             log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2479             return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2480         }
2481
2482         Service service = serviceResultEither.left().value();
2483                 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2484                         ListUtils.emptyIfNull(service.getInputs())
2485                                         .forEach(input -> input.setConstraints(setInputConstraint(input)));
2486                 }
2487
2488         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2489         return Either.left(dataTransfer);
2490     }
2491
2492     public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
2493         validateUserExists(userId);
2494
2495          Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
2496         if (storageStatus.isRight()) {
2497             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2498         }
2499         Service service = storageStatus.left().value();
2500
2501         Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
2502         if (storageStatus.isRight()) {
2503             return Either.right(response.right().value());
2504         }
2505         final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
2506         if (!optionalComponentInstance.isPresent() ){
2507             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2508         }
2509         CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
2510         if (nodeFilter == null){
2511             return Either.left(resourceId);
2512         }
2513
2514         Either<String, StorageOperationStatus> result;
2515         try{
2516             if (lock) {
2517                 lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
2518             }
2519             result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
2520             if (result.isRight()) {
2521                 log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
2522                 janusGraphDao.rollback();
2523                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
2524             }
2525             janusGraphDao.commit();
2526             log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
2527
2528         } catch (Exception e){
2529             log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
2530             janusGraphDao.rollback();
2531             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2532         } finally {
2533             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2534         }
2535         return Either.left(result.left().value());
2536     }
2537
2538
2539     public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
2540         String errorContext =  "createIfNotAlreadyExistServiceFilter";
2541         User user = validateUserExists(userId);
2542
2543         Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
2544         if (serviceEither.isRight()) {
2545             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
2546         }
2547         final Service service = serviceEither.left().value();
2548         validateUserAndRole(service, user, errorContext);
2549
2550         Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
2551         if (!optionalComponentInstance.isPresent()){
2552             return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2553         }
2554         ComponentInstance componentInstance = optionalComponentInstance.get();
2555         CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
2556         if (serviceFilter != null){
2557             return Either.left(serviceFilter);
2558         }
2559         if (lock) {
2560             lockComponent(service.getUniqueId(), service, "Create Service Filter");
2561         }
2562         Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2563
2564         CINodeFilterDataDefinition serviceFilterResult;
2565         try {
2566             result =  serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
2567             if (result.isRight()) {
2568                 janusGraphDao.rollback();
2569                 return Either.right(componentsUtils.getResponseFormat(
2570                         componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2571                         ""));
2572             } else {
2573                 serviceFilterResult = result.left().value();
2574             }
2575             janusGraphDao.commit();
2576
2577         } catch (Exception e) {
2578             janusGraphDao.rollback();
2579             log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2580                     e);
2581             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2582
2583         } finally {
2584             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2585         }
2586         return Either.left(serviceFilterResult);
2587     }
2588
2589
2590     public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
2591             List<String> constraints,  User inUser, boolean lock) {
2592         User user = validateUserExists(inUser.getUserId());
2593         validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2594         Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2595
2596         if(serviceStorageOperationStatusEither.isRight()){
2597             StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2598             log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2599             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2600         }
2601         Service storedService = serviceStorageOperationStatusEither.left().value();
2602
2603         Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2604                 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
2605                         NodeFilterConstraintAction.UPDATE);
2606         if(booleanResponseFormatEither.isRight()){
2607             return Either.right(booleanResponseFormatEither.right().value());
2608         }
2609
2610
2611         Either<Boolean, ResponseFormat> lockResult = null;
2612         if (lock) {
2613             lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2614         }
2615         Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2616         if (!componentInstanceOptional.isPresent()){
2617             return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2618         }
2619         CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2620         if(serviceFilter == null){
2621             return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2622         }
2623         CINodeFilterDataDefinition serviceFilterResult;
2624         try {
2625             List<RequirementNodeFilterPropertyDataDefinition> properties =  constraints.stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
2626             Either<CINodeFilterDataDefinition, StorageOperationStatus>  result =  serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
2627
2628             if (result.isRight()) {
2629                 janusGraphDao.rollback();
2630                 return Either.right(componentsUtils.getResponseFormat(
2631                         componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2632                         ""));
2633             } else {
2634                 serviceFilterResult = result.left().value();
2635             }
2636             janusGraphDao.commit();
2637
2638         } catch (Exception e) {
2639             janusGraphDao.rollback();
2640             log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2641                     e);
2642             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2643
2644         } finally {
2645             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2646                 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2647             }
2648         }
2649         return Either.left(serviceFilterResult);
2650     }
2651
2652     private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
2653         RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
2654         pdd.setConstraints(Arrays.asList(constraint));
2655         return pdd;
2656     }
2657
2658     public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
2659             NodeFilterConstraintAction action, String propertyName, String constraint, int position, User inUser, boolean lock) {
2660         User user = validateUserExists(inUser.getUserId());
2661         validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2662
2663         Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2664
2665         if(serviceStorageOperationStatusEither.isRight()){
2666             StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2667             log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2668             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2669         }
2670         Service storedService = serviceStorageOperationStatusEither.left().value();
2671
2672         Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2673                 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
2674                         Collections.singletonList(constraint), action);
2675         if(booleanResponseFormatEither.isRight()){
2676             return Either.right(booleanResponseFormatEither.right().value());
2677         }
2678
2679         Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2680
2681         Either<Boolean, ResponseFormat> lockResult = null;
2682         CINodeFilterDataDefinition serviceFilterResult = null;
2683         try {
2684             if (lock) {
2685                 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2686             }
2687
2688             Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2689             if (!componentInstanceOptional.isPresent()) {
2690                 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2691             }
2692             CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2693             if (serviceFilter == null) {
2694                 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2695             }
2696
2697
2698             switch (action) {
2699                 case ADD:
2700                     RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
2701                     newProperty.setName(propertyName);
2702                     newProperty.setConstraints(Collections.singletonList(constraint));
2703                     result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId, serviceFilter, newProperty);
2704                     break;
2705                 case DELETE:
2706                     result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
2707                     break;
2708                 default:
2709                     log.error("Unsupported operation " + action);
2710                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2711
2712             }
2713
2714             if (result.isRight()) {
2715                 janusGraphDao.rollback();
2716                 return Either.right(componentsUtils.getResponseFormat(
2717                         componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2718                         ""));
2719             } else {
2720                 serviceFilterResult = result.left().value();
2721             }
2722             janusGraphDao.commit();
2723
2724         } catch (Exception e) {
2725             janusGraphDao.rollback();
2726             log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
2727                     e);
2728             return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2729
2730         } finally {
2731             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2732                 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2733             }
2734         }
2735         return Either.left(serviceFilterResult);
2736     }
2737
2738
2739
2740
2741 }