Fix updating of category specific metadata
[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             currentService.setCategorySpecificMetadata(serviceUpdate.getCategorySpecificMetadata());
1330             return Either.left(currentService);
1331
1332         } catch (ComponentException exception) {
1333             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
1334             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
1335                     AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
1336             return Either.right(responseFormat);
1337         }
1338     }
1339
1340     private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
1341         if (updatedValue != null && !updatedValue.equals(originalValue)) {
1342             log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
1343         }
1344     }
1345
1346     private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
1347         Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
1348         Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
1349         if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
1350             currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
1351         }
1352         String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
1353         if (currentService.isEcompGeneratedNaming() != null && currentService.isEcompGeneratedNaming()) {
1354             currentService.setNamingPolicy(namingPolicyUpdate);
1355         } else {
1356             if (!StringUtils.isEmpty(namingPolicyUpdate)) {
1357                 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
1358             }
1359             currentService.setNamingPolicy("");
1360         }
1361     }
1362
1363     private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1364         String contactIdUpdated = serviceUpdate.getContactId();
1365         String contactIdCurrent = currentService.getContactId();
1366         if (!contactIdCurrent.equals(contactIdUpdated)) {
1367             componentContactIdValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1368             currentService.setContactId(contactIdUpdated.toLowerCase());
1369         }
1370         return Either.left(true);
1371     }
1372
1373     private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1374         List<String> tagsUpdated = serviceUpdate.getTags();
1375         List<String> tagsCurrent = currentService.getTags();
1376         if (tagsUpdated == null || tagsUpdated.isEmpty()) {
1377             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
1378             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
1379             return Either.right(responseFormat);
1380         }
1381
1382         if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
1383             componentTagsValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1384             currentService.setTags(tagsUpdated);
1385         }
1386         return Either.left(true);
1387     }
1388
1389     private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1390         String descriptionUpdated = serviceUpdate.getDescription();
1391         String descriptionCurrent = currentService.getDescription();
1392         if (!descriptionCurrent.equals(descriptionUpdated)) {
1393             componentDescriptionValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1394             currentService.setDescription(serviceUpdate.getDescription());
1395         }
1396         return Either.left(true);
1397     }
1398
1399     private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
1400         String projectCodeUpdated = serviceUpdate.getProjectCode();
1401         String projectCodeCurrent = currentService.getProjectCode();
1402         if (StringUtils.isEmpty(projectCodeCurrent)
1403                 || !projectCodeCurrent.equals(projectCodeUpdated)) {
1404
1405             try {
1406                 componentProjectCodeValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1407             } catch (ComponentException exp) {
1408                 ResponseFormat errorRespons = exp.getResponseFormat();
1409                 return Either.right(errorRespons);
1410             }
1411             currentService.setProjectCode(projectCodeUpdated);
1412
1413         }
1414         return Either.left(true);
1415     }
1416
1417     private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1418         String iconUpdated = serviceUpdate.getIcon();
1419         String iconCurrent = currentService.getIcon();
1420         if (!iconCurrent.equals(iconUpdated)) {
1421             if (!hasBeenCertified) {
1422                 componentIconValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1423                 currentService.setIcon(iconUpdated);
1424             } else {
1425                 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1426                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1427                 return Either.right(errorResponse);
1428             }
1429         }
1430         return Either.left(true);
1431     }
1432
1433     private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1434         String serviceNameUpdated = serviceUpdate.getName();
1435         String serviceNameCurrent = currentService.getName();
1436         if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1437             if (!hasBeenCertified) {
1438                 componentNameValidator.validateAndCorrectField(user, serviceUpdate, auditingAction);
1439                 try {
1440                     componentNameValidator.validateComponentNameUnique(user, serviceUpdate, auditingAction);
1441                 } catch (ComponentException exp) {
1442                     return Either.right(exp.getResponseFormat());
1443                 }
1444                 currentService.setName(serviceNameUpdated);
1445                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1446                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1447
1448             } else {
1449                 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1450                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1451                 return Either.right(errorResponse);
1452             }
1453         }
1454         return Either.left(true);
1455     }
1456
1457     private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
1458         String updatedServiceType = updatedService.getServiceType();
1459         String currentServiceType = currentService.getServiceType();
1460         if (!currentServiceType.equals(updatedServiceType)) {
1461             serviceTypeValidator.validateAndCorrectField(null, updatedService, null);
1462             currentService.setServiceType(updatedServiceType);
1463         }
1464     }
1465
1466     private void validateAndUpdateServiceFunction(Service currentService, Service updatedService) {
1467         String updatedServiceFunction = updatedService.getServiceFunction();
1468         String currentServiceFunction = currentService.getServiceFunction();
1469         if (!currentServiceFunction.equals(updatedServiceFunction)) {
1470             serviceFunctionValidator.validateAndCorrectField(null, updatedService, null);
1471             currentService.setServiceFunction(updatedService.getServiceFunction());
1472         }
1473     }
1474
1475     private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1476         String updatedServiceRole = updatedService.getServiceRole();
1477         String currentServiceRole = currentService.getServiceRole();
1478         if (!currentServiceRole.equals(updatedServiceRole)) {
1479             try {
1480                 serviceRoleValidator.validateAndCorrectField(user, updatedService, auditingAction);
1481             } catch (ComponentException exp) {
1482                 ResponseFormat errorResponse = exp.getResponseFormat();
1483                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1484                 return Either.right(errorResponse);
1485             }
1486             currentService.setServiceRole(updatedServiceRole);
1487         }
1488         return Either.left(true);
1489     }
1490
1491     private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1492         String updatedInstaType= updatedService.getInstantiationType();
1493         String currentInstaType = currentService.getInstantiationType();
1494         if (!currentInstaType.equals(updatedInstaType)) {
1495             try {
1496                 serviceInstantiationTypeValidator.validateAndCorrectField(user, updatedService, auditingAction);
1497             } catch (ComponentException exp) {
1498                 ResponseFormat errorResponse = exp.getResponseFormat();
1499                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1500                 return Either.right(errorResponse);
1501             }
1502             currentService.setInstantiationType(updatedInstaType);
1503         }
1504         return Either.left(true);
1505     }
1506
1507     private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1508         try {
1509             List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1510             List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1511             serviceCategoryValidator.validateAndCorrectField(user, serviceUpdate, audatingAction);
1512             if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1513                 if (!hasBeenCertified) {
1514                     currentService.setCategories(categoryUpdated);
1515                 } else {
1516                     log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1517                     ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1518                     return Either.right(errorResponse);
1519                 }
1520             }
1521         } catch (ComponentException exp) {
1522             return Either.right(exp.getResponseFormat());
1523         }
1524         return Either.left(true);
1525
1526     }
1527
1528     public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1529         Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1530         if (serviceResponseFormatEither.isRight()){
1531             return Either.right(serviceResponseFormatEither.right().value());
1532         }
1533         final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1534         return Either.left(serviceRelations);
1535
1536
1537     }
1538
1539     public ResponseFormat deleteService(String serviceId, User user) {
1540         ResponseFormat responseFormat;
1541
1542         validateUserExists(user);
1543         Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1544         if (serviceStatus.isRight()) {
1545             log.debug("failed to get service {}", serviceId);
1546             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1547         }
1548
1549         Service service = serviceStatus.left().value();
1550
1551         StorageOperationStatus result = StorageOperationStatus.OK;
1552         try {
1553             lockComponent(service, "Mark service to delete");
1554             result = markComponentToDelete(service);
1555             if (result == StorageOperationStatus.OK) {
1556                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1557             } else {
1558                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1559                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1560             }
1561             return responseFormat;
1562         }catch (ComponentException e){
1563             return e.getResponseFormat();
1564         }finally {
1565             if (result == null || result != StorageOperationStatus.OK) {
1566                 log.warn("operation failed. do rollback");
1567                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1568                 janusGraphDao.rollback();
1569             } else {
1570                 log.debug("operation success. do commit");
1571                 janusGraphDao.commit();
1572             }
1573             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1574         }
1575     }
1576
1577     public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1578         ResponseFormat responseFormat;
1579         String ecompErrorContext = "delete service";
1580         validateUserNotEmpty(user, ecompErrorContext);
1581         user = validateUserExists(user);
1582
1583         Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1584         if (getResult.isRight()) {
1585             return getResult.right().value();
1586         }
1587         Service service = getResult.left().value();
1588
1589         StorageOperationStatus result = StorageOperationStatus.OK;
1590
1591         try {
1592             lockComponent(service, "Mark service to delete");
1593             result = markComponentToDelete(service);
1594             if (result == StorageOperationStatus.OK) {
1595                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1596             } else {
1597                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1598                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1599             }
1600             return responseFormat;
1601
1602         }catch (ComponentException e){
1603             result = StorageOperationStatus.GENERAL_ERROR;
1604             return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1605         }finally {
1606             if (result == null || result != StorageOperationStatus.OK) {
1607                 log.warn("operation failed. do rollback");
1608                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1609                 janusGraphDao.rollback();
1610             } else {
1611                 log.debug("operation success. do commit");
1612                 janusGraphDao.commit();
1613             }
1614             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1615         }
1616     }
1617
1618     public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1619         String ecompErrorContext = "Get service";
1620         validateUserNotEmpty(user, ecompErrorContext);
1621         validateUserExists(user);
1622
1623         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1624         if (storageStatus.isRight()) {
1625             log.debug("failed to get service by id {}", serviceId);
1626             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1627         }
1628
1629         if(!(storageStatus.left().value() instanceof Service)){
1630             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1631         }
1632         Service service = storageStatus.left().value();
1633         return Either.left(service);
1634
1635
1636
1637
1638     }
1639
1640     public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1641         validateUserExists(userId);
1642         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1643         if (storageStatus.isRight()) {
1644             log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1645             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1646         }
1647         Service service = storageStatus.left().value();
1648         return Either.left(service);
1649     }
1650
1651     @SuppressWarnings("unchecked")
1652     private void createMandatoryArtifactsData(Service service, User user) {
1653         // create mandatory artifacts
1654
1655         // TODO it must be removed after that artifact uniqueId creation will be
1656         // moved to ArtifactOperation
1657         String serviceUniqueId = service.getUniqueId();
1658         Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1659         if (artifactMap == null)
1660             artifactMap = new HashMap<>();
1661
1662         Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1663         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1664
1665         String category = service.getCategories().get(0).getName();
1666         boolean isCreateArtifact = true;
1667         if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1668             for (String exlude : exludeServiceCategory) {
1669                 if (exlude.equalsIgnoreCase(category)) {
1670                     isCreateArtifact = false;
1671                     break;
1672                 }
1673             }
1674
1675         }
1676
1677         if (informationalServiceArtifacts != null && isCreateArtifact) {
1678             Set<String> keys = informationalServiceArtifacts.keySet();
1679             for (String informationalServiceArtifactName : keys) {
1680                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1681                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1682                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1683
1684             }
1685
1686             service.setArtifacts(artifactMap);
1687         }
1688     }
1689
1690     private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1691
1692         ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1693
1694         if (isServiceApi) {
1695             artifactInfo.setMandatory(false);
1696             artifactInfo.setServiceApi(true);
1697         }
1698         return artifactInfo;
1699     }
1700
1701     private DistributionTransitionEnum validateTransitionEnum(String distributionTransition) {
1702         DistributionTransitionEnum transitionEnum;
1703
1704         transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1705         if (transitionEnum == null) {
1706             BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1707             log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1708             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_DISTRIBUTION_STATUS, distributionTransition));
1709         }
1710
1711         return transitionEnum;
1712     }
1713
1714     private String validateComment(LifecycleChangeInfoWithAction comment) {
1715         if (comment==null || StringUtils.isEmpty(comment.getUserRemarks())) {
1716             return "";
1717         }
1718         String data = comment.getUserRemarks();
1719         data = ValidationUtils.removeNoneUtf8Chars(data);
1720         data = ValidationUtils.removeHtmlTags(data);
1721         data = ValidationUtils.normaliseWhitespace(data);
1722         data = ValidationUtils.stripOctets(data);
1723
1724         if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1725             BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1726             log.debug("user comment exceeds limit.");
1727             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1728         }
1729         if (!ValidationUtils.validateCommentPattern(data)) {
1730             throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1731         }
1732
1733         return data;
1734     }
1735
1736     private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1737         log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1738         componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1739                 ResourceVersionInfo.newBuilder()
1740                         .state(component.getLifecycleState().name())
1741                         .version(component.getVersion())
1742                         .build(),
1743                 comment);
1744     }
1745
1746     private String getEnvNameFromConfiguration() {
1747         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1748         log.trace("Update environment name to be {}", configuredEnvName);
1749         return configuredEnvName;
1750     }
1751
1752     public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1753
1754         Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1755         if (activationRequestInformationEither.isRight()) {
1756             return Either.right(activationRequestInformationEither.right().value());
1757         }
1758
1759         ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1760
1761         Either<String, ResponseFormat> result = null;
1762         String did = ThreadLocalsHolder.getUuid();
1763         Service service = activationRequestInformation.getServiceToActivate();
1764         result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1765         return result;
1766     }
1767
1768     public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1769         String envName = getEnvNameFromConfiguration();
1770         INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1771         ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1772         if (notifyServiceResponse == ActionStatus.OK) {
1773             return Either.left(did);
1774         } else {
1775             BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1776             log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1777             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1778             return Either.right(error);
1779         }
1780     }
1781
1782     public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1783
1784         User user = validateUserExists(modifier.getUserId());
1785         validateUserRole(user, Collections.singletonList(Role.DESIGNER));
1786         Either<Service, ResponseFormat> result;
1787         ResponseFormat response;
1788         Service updatedService;
1789         String did = ThreadLocalsHolder.getUuid();
1790          // DE194021
1791         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1792         if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1793             log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1794             envName = configuredEnvName;
1795         }
1796         // DE194021
1797
1798         ServletContext servletContext = request.getSession().getServletContext();
1799         boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1800         if (!isDistributionEngineUp) {
1801             BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1802             log.debug("Distribution Engine is DOWN");
1803             response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1804             return Either.right(response);
1805         }
1806
1807         Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1808         if (serviceRes.isRight()) {
1809             log.debug("failed retrieving service");
1810             response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1811             componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1812                     new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1813                     ResourceVersionInfo.newBuilder()
1814                             .build(),
1815                     did);
1816             return Either.right(response);
1817         }
1818         Service service = serviceRes.left().value();
1819         if (service.isArchived()) {
1820             log.info("Component is archived. Component id: {}", serviceId);
1821             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName()));
1822         }
1823         if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1824             log.info("service {} is  not available for distribution. Should be in certified state", service.getUniqueId());
1825             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1826             return Either.right(responseFormat);
1827         }
1828         String dcurrStatus = service.getDistributionStatus().name();
1829         String updatedStatus = dcurrStatus;
1830         StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1831         if (readyForDistribution == StorageOperationStatus.OK) {
1832             INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1833             ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1834             if (notifyServiceResponse == ActionStatus.OK) {
1835                 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1836                 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1837                     updatedService = updateStateRes.left().value();
1838                     updatedStatus = updatedService.getDistributionStatus().name();
1839                 } else {
1840                     // The response is not relevant
1841                     updatedService = service;
1842                 }
1843                 ASDCKpiApi.countActivatedDistribution();
1844                 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1845                 result = Either.left(updatedService);
1846             } else {
1847                 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1848                 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1849                 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1850                 result = Either.right(response);
1851             }
1852         } else {
1853             response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution, ComponentTypeEnum.SERVICE), envName);
1854             result = Either.right(response);
1855         }
1856         componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1857                 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1858                 ResourceVersionInfo.newBuilder()
1859                         .distributionStatus(dcurrStatus)
1860                         .build(),
1861                 ResourceVersionInfo.newBuilder()
1862                         .distributionStatus(updatedStatus)
1863                         .build(),
1864                 null, null, did);
1865         return result;
1866     }
1867
1868     // convert to private after deletion of temp url
1869     public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1870
1871         validateUserExists(user.getUserId());
1872
1873         String serviceId = service.getUniqueId();
1874          lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1875         try {
1876             Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1877             if (result.isRight()) {
1878                 janusGraphDao.rollback();
1879                 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1880                 log.debug("service {}  change distribution status failed", serviceId);
1881                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1882             }
1883             janusGraphDao.commit();
1884             updateCatalog(service, ChangeTypeEnum.LIFECYCLE);
1885             return Either.left(result.left().value());
1886         } finally {
1887             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1888         }
1889     }
1890
1891     public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1892
1893         validateUserExists(user.getUserId());
1894         log.debug("mark distribution deployed");
1895
1896         AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1897         Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1898         if (getServiceResponse.isRight()) {
1899             BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1900             log.debug("service {} not found", serviceId);
1901             ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1902
1903             return Either.right(responseFormat);
1904         }
1905
1906         Service service = getServiceResponse.left().value();
1907         user = validateRoleForDeploy(did, user, auditAction, service);
1908         return checkDistributionAndDeploy(did, user, auditAction, service);
1909
1910     }
1911
1912     public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1913         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1914                 // Only one VF Module Artifact per instance - add it to a list of one
1915                 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1916
1917         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1918
1919     }
1920
1921     private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
1922         List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1923
1924         if (ri.getOriginType() == OriginTypeEnum.VF) {
1925             asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
1926         }
1927         return asList;
1928     }
1929
1930     private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
1931         Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1932         if(currVF.getGroupInstances() != null){
1933             currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1934         }
1935         return currVF.getGroupInstances();
1936     }
1937
1938     private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
1939         ArtifactDefinition vfModuleAertifact = null;
1940         if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1941             final Optional<ArtifactDefinition> optionalVfModuleArtifact =
1942                 currVF.getDeploymentArtifacts().values().stream()
1943                     .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType()))
1944                     .findAny();
1945             if (optionalVfModuleArtifact.isPresent()) {
1946                 vfModuleAertifact = optionalVfModuleArtifact.get();
1947             }
1948         }
1949         if (vfModuleAertifact == null) {
1950             Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
1951             if (createVfModuleArtifact.isLeft()) {
1952                 vfModuleAertifact = createVfModuleArtifact.left().value();
1953             } else {
1954                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1955             }
1956         }
1957         return vfModuleAertifact;
1958     }
1959
1960     private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1961         List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
1962         if (groupsForCurrVF != null) {
1963             for (GroupInstance groupInstance : groupsForCurrVF) {
1964                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1965                 vfModulePayloads.add(modulePayload);
1966             }
1967             vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
1968
1969             final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1970
1971             String vfModulePayloadString = gson.toJson(vfModulePayloads);
1972             payloadWrapper.setInnerElement(vfModulePayloadString);
1973         }
1974
1975     }
1976
1977     private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
1978         ArtifactDefinition vfModuleArtifact = null;
1979         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1980         Wrapper<String> payloadWrapper = new Wrapper<>();
1981         List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
1982         if (responseWrapper.isEmpty()) {
1983             fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1984         }
1985         if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1986             vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
1987         }
1988         if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
1989             vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
1990         }
1991
1992         Either<ArtifactDefinition, ResponseFormat> result;
1993         if (responseWrapper.isEmpty()) {
1994             result = Either.left(vfModuleArtifact);
1995         } else {
1996             result = Either.right(responseWrapper.getInnerElement());
1997         }
1998
1999         return result;
2000     }
2001
2002     private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2003         ArtifactDefinition result = null;
2004         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2005                 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2006         if (eitherPayload.isLeft()) {
2007             result = eitherPayload.left().value();
2008         } else {
2009             responseWrapper.setInnerElement(eitherPayload.right().value());
2010         }
2011         if (result == null) {
2012             result = vfModuleArtifact;
2013         }
2014
2015         return result;
2016     }
2017
2018     private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2019
2020         ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2021         String newCheckSum = null;
2022
2023         vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2024         vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2025         vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2026         vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2027         vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2028         vfModuleArtifactDefinition.setTimeout(0);
2029         vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2030         vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2031         if (vfModulePayloadString != null) {
2032             newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2033         }
2034         vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2035
2036         Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation.addArtifactToComponent(
2037                 vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2038
2039         Either<ArtifactDefinition, ResponseFormat> result;
2040         if (addArtifactToComponent.isLeft()) {
2041             result = Either.left(addArtifactToComponent.left().value());
2042         } else {
2043             result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
2044         }
2045
2046         return result;
2047     }
2048
2049     public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2050
2051         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2052                 // Get All Deployment Artifacts
2053                 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2054                         // Filter in Only Heat Env
2055                                 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2056                         // Create ArtifactGenerator from those Artifacts
2057                                 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2058
2059         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2060
2061     }
2062
2063     private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2064
2065         // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2066         // service
2067         if (service.getComponentInstances() != null) {
2068             List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2069             if (artifactGenList != null && !artifactGenList.isEmpty()) {
2070                 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
2071                 if (callRes != null) return callRes;
2072             }
2073         }
2074         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2075         if (storageStatus.isRight()) {
2076             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2077         }
2078
2079         Service currentService = storageStatus.left().value();
2080
2081         return Either.left(currentService);
2082
2083     }
2084
2085     private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
2086         for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2087             Either<CallVal, ResponseFormat> callRes;
2088             try {
2089                 callRes = entry.call();
2090                 if (callRes.isRight()) {
2091                     log.debug("Failed to generate artifact error : {}", callRes.right().value());
2092                     return Either.right(callRes.right().value());
2093                 }
2094             } catch (Exception e) {
2095                 log.debug("Failed to generate artifact exception : {}", e);
2096                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2097             }
2098         }
2099         return null;
2100     }
2101
2102     abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2103
2104     }
2105
2106     class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2107         ArtifactDefinition artifactDefinition;
2108         Service service;
2109         String resourceInstanceName;
2110         User modifier;
2111         String instanceId;
2112         boolean shouldLock;
2113         boolean inTransaction;
2114
2115         HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2116             this.artifactDefinition = artifactDefinition;
2117             this.service = service;
2118             this.resourceInstanceName = resourceInstanceName;
2119             this.modifier = modifier;
2120             this.shouldLock = shouldLock;
2121             this.instanceId = instanceId;
2122             this.inTransaction = inTransaction;
2123         }
2124
2125         @Override
2126         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2127             return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2128         }
2129
2130         public ArtifactDefinition getArtifactDefinition() {
2131             return artifactDefinition;
2132         }
2133
2134     }
2135
2136     class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2137         private User user;
2138         private ComponentInstance componentInstance;
2139         private Service service;
2140         boolean shouldLock;
2141         boolean inTransaction;
2142
2143         @Override
2144         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2145             return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2146         }
2147
2148         private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2149             super();
2150             this.user = user;
2151             this.componentInstance = componentInstance;
2152             this.service = service;
2153             this.shouldLock = shouldLock;
2154             this.inTransaction = inTransaction;
2155         }
2156
2157     }
2158
2159     private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2160         boolean isDeployed = isDistributionDeployed(distributionId);
2161         if (isDeployed) {
2162             return Either.left(service);
2163         }
2164         Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2165         if (distributionSuccess.isRight()) {
2166             return Either.right(distributionSuccess.right().value());
2167         }
2168
2169         log.debug("mark distribution {} as deployed - success", distributionId);
2170         componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2171         return Either.left(service);
2172     }
2173
2174     private boolean isDistributionDeployed(String distributionId) {
2175         Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2176
2177         boolean isDeployed = false;
2178         if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2179             // already deployed
2180             log.debug("distribution {} is already deployed", distributionId);
2181             isDeployed = true;
2182         }
2183         return isDeployed;
2184     }
2185
2186     protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2187
2188         log.trace("checkDistributionSuccess");
2189         // get all "DRequest" records for this distribution
2190
2191         Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2192         if (distRequestsResponse.isRight()) {
2193             ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2194             return Either.right(error);
2195         }
2196
2197         List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2198         if (distributionRequests.isEmpty()) {
2199             BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2200             log.info("distribution {} is not found", did);
2201             ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2202             return Either.right(error);
2203         }
2204         boolean isRequestSucceeded = false;
2205         for (ResourceAdminEvent event : distributionRequests) {
2206             String eventStatus = event.getStatus();
2207             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2208                 isRequestSucceeded = true;
2209                 break;
2210             }
2211         }
2212
2213         // get all "DNotify" records for this distribution
2214         Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2215         if (distNotificationsResponse.isRight()) {
2216             ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2217             return Either.right(error);
2218         }
2219
2220         List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2221         boolean isNotificationsSucceeded = false;
2222         for (DistributionNotificationEvent event : distributionNotifications) {
2223             String eventStatus = event.getStatus();
2224             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2225                 isNotificationsSucceeded = true;
2226                 break;
2227             }
2228         }
2229
2230         // if request failed OR there are notifications that failed
2231         if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2232
2233             log.info("distribution {} has failed", did);
2234             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2235             auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2236             return Either.right(error);
2237         }
2238         return Either.left(true);
2239     }
2240
2241     private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2242
2243         ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2244         String message = "";
2245         if (error.getMessageId() != null) {
2246             message = error.getMessageId() + ": ";
2247         }
2248         message += error.getFormattedMessage();
2249
2250         if (service != null) {
2251             componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2252         } else {
2253             componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2254         }
2255         return error;
2256     }
2257
2258     private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2259         user = userAdmin.getUser(user.getUserId());
2260         log.debug("validate user role");
2261         List<Role> roles = new ArrayList<>();
2262         roles.add(Role.ADMIN);
2263         roles.add(Role.DESIGNER);
2264         try{
2265             validateUserRole(user, service, roles, auditAction, null);
2266         } catch (ByActionStatusComponentException e){
2267             log.info("role {} is not allowed to perform this action", user.getRole());
2268             auditDeployError(did, user, auditAction, service, e.getActionStatus());
2269             throw e;
2270         }
2271         return user;
2272     }
2273
2274     @Override
2275     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2276         if(component instanceof Service){
2277             Service service = (Service) component;
2278             Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2279             if (artifactMap == null) {
2280                 artifactMap = new HashMap<>();
2281             }
2282             service.setDeploymentArtifacts(artifactMap);
2283         }else if(component instanceof Resource){
2284             Resource resource = (Resource) component;
2285             Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
2286             if (artifactMap == null) {
2287                 artifactMap = new HashMap<>();
2288             }
2289             Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager()
2290                                                                       .getConfiguration().getDeploymentResourceArtifacts();
2291             if (deploymentResourceArtifacts != null) {
2292                 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
2293                 deploymentResourceArtifacts.forEach((k, v)->processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k,v));
2294             }
2295             resource.setDeploymentArtifacts(artifactMap);
2296         }
2297
2298     }
2299
2300     private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
2301         Map<String, Object> artifactDetails = (Map<String, Object>) v;
2302         Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
2303         if (object != null) {
2304             List<String> artifactTypes = (List<String>) object;
2305             if (!artifactTypes.contains(resource.getResourceType().name())) {
2306                 return;
2307             }
2308         } else {
2309             log.info("resource types for artifact placeholder {} were not defined. default is all resources",
2310                     k);
2311         }
2312         if (artifactsBusinessLogic != null) {
2313             ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(
2314                     resource.getUniqueId(), k, (Map<String, Object>) v,
2315                     user, ArtifactGroupTypeEnum.DEPLOYMENT);
2316             if (artifactDefinition != null
2317                     && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
2318                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
2319             }
2320         }
2321     }
2322
2323     @Override
2324     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2325         return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2326     }
2327
2328     private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2329         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2330         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2331         return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2332     }
2333
2334     @Override
2335     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2336         return componentInstanceBusinessLogic;
2337     }
2338
2339     @Override
2340     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2341
2342         validateUserExists(userId);
2343         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2344         if (getComponentRes.isRight()) {
2345             ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2346             return Either.right(responseFormat);
2347         }
2348
2349         List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2350
2351         return Either.left(componentInstances);
2352     }
2353
2354     @Autowired
2355     public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2356         this.forwardingPathOperation = forwardingPathOperation;
2357     }
2358
2359     /**
2360      * 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
2361      *
2362      */
2363     public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2364
2365         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2366         Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2367         Component component = null;
2368         Either<Boolean, ResponseFormat> lockResult = null;
2369         log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2370         try {
2371             validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2372             if (validateUserAndComponentRes.isRight()) {
2373                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
2374                 actionResult = Either.right(validateUserAndComponentRes.right().value());
2375             }
2376             if (actionResult == null) {
2377                 component = validateUserAndComponentRes.left().value().getKey();
2378                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2379                 if (lockResult.isRight()) {
2380                     log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2381                     actionResult = Either.right(lockResult.right().value());
2382                 } else {
2383                     log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2384                 }
2385             }
2386             if (actionResult == null) {
2387                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2388                 if (actionResult.isRight()) {
2389                     log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2390                 }
2391             }
2392         } catch (Exception e) {
2393             log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2394             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2395         } finally {
2396             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2397                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2398             }
2399         }
2400         return actionResult;
2401     }
2402
2403     private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2404
2405         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2406         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2407         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2408         ComponentInstance relatedComponentInstance = null;
2409         GroupInstance oldGroupInstance = null;
2410         Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2411         GroupInstance updatedGroupInstance = null;
2412         boolean inTransaction = true;
2413         findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2414         if (findGroupInstanceRes.isRight()) {
2415             log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2416             actionResult = Either.right(findGroupInstanceRes.right().value());
2417         }
2418         if (actionResult == null) {
2419             oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2420             relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2421             updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2422             if (updateGroupInstanceResult.isRight()) {
2423                 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2424                 actionResult = Either.right(updateGroupInstanceResult.right().value());
2425             }
2426         }
2427         if (actionResult == null) {
2428             updatedGroupInstance = updateGroupInstanceResult.left().value();
2429             if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2430                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2431                 if (updateParentsModificationTimeRes.isRight()) {
2432                     log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2433                     actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2434                 }
2435             }
2436         }
2437         if (actionResult == null) {
2438             actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2439         }
2440         return actionResult;
2441     }
2442
2443     private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2444                                                                                                                                                   boolean inTranscation) {
2445
2446         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2447         Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2448         Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2449                 updatedGroupInstance.getModificationTime(), inTranscation);
2450         if (updateComponentInstanceRes.isRight()) {
2451             log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2452             actionResult = Either.right(updateComponentInstanceRes.right().value());
2453         } else {
2454             serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2455             if (serviceMetadataUpdateResult.isRight()) {
2456                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2457                 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2458             } else {
2459                 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2460             }
2461         }
2462         return actionResult;
2463     }
2464
2465     private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2466
2467         Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2468         User currUser = null;
2469         Component component = null;
2470         Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2471         if (validationUserResult.isRight()) {
2472             log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2473             result = Either.right(validationUserResult.right().value());
2474         }
2475         if (result == null) {
2476             currUser = validationUserResult.left().value();
2477             try {
2478                 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2479                 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2480                     log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2481                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2482                 }
2483             } catch (ComponentException e) {
2484                 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2485                 result = Either.right(e.getResponseFormat());
2486             }
2487         }
2488
2489         if (result == null) {
2490             result = Either.left(new ImmutablePair<>(component, currUser));
2491         }
2492         return result;
2493     }
2494
2495     private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2496
2497         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2498         GroupInstance groupInstance = null;
2499         ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2500         if (foundComponentInstance == null) {
2501             log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2502             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2503         }
2504         else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2505             groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2506             if (groupInstance == null) {
2507                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2508                 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2509             }
2510         }
2511         if (actionResult == null) {
2512             actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2513         }
2514         return actionResult;
2515     }
2516
2517     private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2518         ComponentInstance componentInstance = null;
2519         if (isNotEmpty(component.getComponentInstances())) {
2520             componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2521         }
2522         return componentInstance;
2523     }
2524
2525     private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2526         User user = validateUser(modifier, ecompErrorContext, null, null, false);
2527         List<Role> roles = new ArrayList<>();
2528         roles.add(Role.ADMIN);
2529         roles.add(Role.DESIGNER);
2530         validateUserRole(user, roles);
2531         return Either.left(user);
2532     }
2533
2534     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2535
2536         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2537         paramsToReturn.setIgnoreComponentInstancesProperties(false);
2538         Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2539
2540         if (serviceResultEither.isRight()) {
2541             if(serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2542                 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2543                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2544             }
2545
2546             log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2547             return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2548         }
2549
2550         Service service = serviceResultEither.left().value();
2551                 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2552                         ListUtils.emptyIfNull(service.getInputs())
2553                                         .forEach(input -> input.setConstraints(setInputConstraint(input)));
2554                 }
2555
2556         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2557         return Either.left(dataTransfer);
2558     }
2559
2560     @Autowired(required = false)
2561     public void setServiceCreationPluginList(List<ServiceCreationPlugin> serviceCreationPluginList) {
2562         this.serviceCreationPluginList = serviceCreationPluginList;
2563     }
2564
2565     public boolean isServiceExist(String serviceName) {
2566         Either<Service, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByServiceName(serviceName);
2567         return latestByName.isLeft();
2568     }
2569 }