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