Fix locally failing TCs in catalog-be
[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         String did = ThreadLocalsHolder.getUuid();
1762         Service service = activationRequestInformation.getServiceToActivate();
1763         return buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1764     }
1765
1766     private Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1767         String envName = getEnvNameFromConfiguration();
1768         INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1769         ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1770         if (notifyServiceResponse == ActionStatus.OK) {
1771             return Either.left(did);
1772         } else {
1773             BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1774             log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1775             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1776             return Either.right(error);
1777         }
1778     }
1779
1780     public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1781
1782         User user = validateUserExists(modifier.getUserId());
1783         validateUserRole(user, Collections.singletonList(Role.DESIGNER));
1784         Either<Service, ResponseFormat> result;
1785         ResponseFormat response;
1786         Service updatedService;
1787         String did = ThreadLocalsHolder.getUuid();
1788          // DE194021
1789         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1790         if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1791             log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1792             envName = configuredEnvName;
1793         }
1794         // DE194021
1795
1796         ServletContext servletContext = request.getSession().getServletContext();
1797         boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1798         if (!isDistributionEngineUp) {
1799             BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1800             log.debug("Distribution Engine is DOWN");
1801             response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1802             return Either.right(response);
1803         }
1804
1805         Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1806         if (serviceRes.isRight()) {
1807             log.debug("failed retrieving service");
1808             response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1809             componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1810                     new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1811                     ResourceVersionInfo.newBuilder()
1812                             .build(),
1813                     did);
1814             return Either.right(response);
1815         }
1816         Service service = serviceRes.left().value();
1817         if (service.isArchived()) {
1818             log.info("Component is archived. Component id: {}", serviceId);
1819             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, service.getName()));
1820         }
1821         if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1822             log.info("service {} is  not available for distribution. Should be in certified state", service.getUniqueId());
1823             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1824             return Either.right(responseFormat);
1825         }
1826         String dcurrStatus = service.getDistributionStatus().name();
1827         String updatedStatus = dcurrStatus;
1828         StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1829         if (readyForDistribution == StorageOperationStatus.OK) {
1830             INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1831             ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1832             if (notifyServiceResponse == ActionStatus.OK) {
1833                 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1834                 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1835                     updatedService = updateStateRes.left().value();
1836                     updatedStatus = updatedService.getDistributionStatus().name();
1837                 } else {
1838                     // The response is not relevant
1839                     updatedService = service;
1840                 }
1841                 ASDCKpiApi.countActivatedDistribution();
1842                 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1843                 result = Either.left(updatedService);
1844             } else {
1845                 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1846                 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1847                 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1848                 result = Either.right(response);
1849             }
1850         } else {
1851             response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution, ComponentTypeEnum.SERVICE), envName);
1852             result = Either.right(response);
1853         }
1854         componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1855                 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1856                 ResourceVersionInfo.newBuilder()
1857                         .distributionStatus(dcurrStatus)
1858                         .build(),
1859                 ResourceVersionInfo.newBuilder()
1860                         .distributionStatus(updatedStatus)
1861                         .build(),
1862                 null, null, did);
1863         return result;
1864     }
1865
1866     // convert to private after deletion of temp url
1867     public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1868
1869         validateUserExists(user.getUserId());
1870
1871         String serviceId = service.getUniqueId();
1872          lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1873         try {
1874             Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1875             if (result.isRight()) {
1876                 janusGraphDao.rollback();
1877                 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1878                 log.debug("service {}  change distribution status failed", serviceId);
1879                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1880             }
1881             janusGraphDao.commit();
1882             updateCatalog(service, ChangeTypeEnum.LIFECYCLE);
1883             return Either.left(result.left().value());
1884         } finally {
1885             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1886         }
1887     }
1888
1889     public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1890
1891         validateUserExists(user.getUserId());
1892         log.debug("mark distribution deployed");
1893
1894         AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1895         Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1896         if (getServiceResponse.isRight()) {
1897             BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1898             log.debug("service {} not found", serviceId);
1899             ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1900
1901             return Either.right(responseFormat);
1902         }
1903
1904         Service service = getServiceResponse.left().value();
1905         user = validateRoleForDeploy(did, user, auditAction, service);
1906         return checkDistributionAndDeploy(did, user, auditAction, service);
1907
1908     }
1909
1910     public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1911         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1912                 // Only one VF Module Artifact per instance - add it to a list of one
1913                 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1914
1915         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1916
1917     }
1918
1919     private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
1920         List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1921
1922         if (ri.getOriginType() == OriginTypeEnum.VF) {
1923             asList = Arrays.asList(new VfModuleArtifactGenerator(modifier, ri, service, shouldLock, inTransaction));
1924         }
1925         return asList;
1926     }
1927
1928     private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
1929         Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1930         if(currVF.getGroupInstances() != null){
1931             currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1932         }
1933         return currVF.getGroupInstances();
1934     }
1935
1936     private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
1937         ArtifactDefinition vfModuleAertifact = null;
1938         if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1939             final Optional<ArtifactDefinition> optionalVfModuleArtifact =
1940                 currVF.getDeploymentArtifacts().values().stream()
1941                     .filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.getType()))
1942                     .findAny();
1943             if (optionalVfModuleArtifact.isPresent()) {
1944                 vfModuleAertifact = optionalVfModuleArtifact.get();
1945             }
1946         }
1947         if (vfModuleAertifact == null) {
1948             Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
1949             if (createVfModuleArtifact.isLeft()) {
1950                 vfModuleAertifact = createVfModuleArtifact.left().value();
1951             } else {
1952                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1953             }
1954         }
1955         return vfModuleAertifact;
1956     }
1957
1958     private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1959         List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
1960         if (groupsForCurrVF != null) {
1961             for (GroupInstance groupInstance : groupsForCurrVF) {
1962                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1963                 vfModulePayloads.add(modulePayload);
1964             }
1965             vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
1966
1967             final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1968
1969             String vfModulePayloadString = gson.toJson(vfModulePayloads);
1970             payloadWrapper.setInnerElement(vfModulePayloadString);
1971         }
1972
1973     }
1974
1975     private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
1976         ArtifactDefinition vfModuleArtifact = null;
1977         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1978         Wrapper<String> payloadWrapper = new Wrapper<>();
1979         List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
1980         if (responseWrapper.isEmpty()) {
1981             fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1982         }
1983         if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1984             vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
1985         }
1986         if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
1987             vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
1988         }
1989
1990         Either<ArtifactDefinition, ResponseFormat> result;
1991         if (responseWrapper.isEmpty()) {
1992             result = Either.left(vfModuleArtifact);
1993         } else {
1994             result = Either.right(responseWrapper.getInnerElement());
1995         }
1996
1997         return result;
1998     }
1999
2000     private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
2001         ArtifactDefinition result = null;
2002         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
2003                 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
2004         if (eitherPayload.isLeft()) {
2005             result = eitherPayload.left().value();
2006         } else {
2007             responseWrapper.setInnerElement(eitherPayload.right().value());
2008         }
2009         if (result == null) {
2010             result = vfModuleArtifact;
2011         }
2012
2013         return result;
2014     }
2015
2016     private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
2017
2018         ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
2019         String newCheckSum = null;
2020
2021         vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
2022         vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
2023         vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
2024         vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
2025         vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
2026         vfModuleArtifactDefinition.setTimeout(0);
2027         vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
2028         vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
2029         if (vfModulePayloadString != null) {
2030             newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
2031         }
2032         vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
2033
2034         Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation.addArtifactToComponent(
2035                 vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
2036
2037         Either<ArtifactDefinition, ResponseFormat> result;
2038         if (addArtifactToComponent.isLeft()) {
2039             result = Either.left(addArtifactToComponent.left().value());
2040         } else {
2041             result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
2042         }
2043
2044         return result;
2045     }
2046
2047     public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
2048
2049         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
2050                 // Get All Deployment Artifacts
2051                 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
2052                         // Filter in Only Heat Env
2053                                 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
2054                         // Create ArtifactGenerator from those Artifacts
2055                                 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
2056
2057         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
2058
2059     }
2060
2061     private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
2062
2063         // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
2064         // service
2065         if (service.getComponentInstances() != null) {
2066             List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
2067             if (artifactGenList != null && !artifactGenList.isEmpty()) {
2068                 Either<Service, ResponseFormat> callRes = checkDeploymentArtifact(artifactGenList);
2069                 if (callRes != null) return callRes;
2070             }
2071         }
2072         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
2073         if (storageStatus.isRight()) {
2074             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2075         }
2076
2077         Service currentService = storageStatus.left().value();
2078
2079         return Either.left(currentService);
2080
2081     }
2082
2083     private <CallVal> Either<Service, ResponseFormat> checkDeploymentArtifact(List<ArtifactGenerator<CallVal>> artifactGenList) {
2084         for (ArtifactGenerator<CallVal> entry : artifactGenList) {
2085             Either<CallVal, ResponseFormat> callRes;
2086             try {
2087                 callRes = entry.call();
2088                 if (callRes.isRight()) {
2089                     log.debug("Failed to generate artifact error : {}", callRes.right().value());
2090                     return Either.right(callRes.right().value());
2091                 }
2092             } catch (Exception e) {
2093                 log.debug("Failed to generate artifact exception : {}", e);
2094                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2095             }
2096         }
2097         return null;
2098     }
2099
2100     abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
2101
2102     }
2103
2104     class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2105         ArtifactDefinition artifactDefinition;
2106         Service service;
2107         String resourceInstanceName;
2108         User modifier;
2109         String instanceId;
2110         boolean shouldLock;
2111         boolean inTransaction;
2112
2113         HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
2114             this.artifactDefinition = artifactDefinition;
2115             this.service = service;
2116             this.resourceInstanceName = resourceInstanceName;
2117             this.modifier = modifier;
2118             this.shouldLock = shouldLock;
2119             this.instanceId = instanceId;
2120             this.inTransaction = inTransaction;
2121         }
2122
2123         @Override
2124         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2125             return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
2126         }
2127
2128         public ArtifactDefinition getArtifactDefinition() {
2129             return artifactDefinition;
2130         }
2131
2132     }
2133
2134     class VfModuleArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
2135         private User user;
2136         private ComponentInstance componentInstance;
2137         private Service service;
2138         boolean shouldLock;
2139         boolean inTransaction;
2140
2141         @Override
2142         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
2143             return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
2144         }
2145
2146         private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
2147             super();
2148             this.user = user;
2149             this.componentInstance = componentInstance;
2150             this.service = service;
2151             this.shouldLock = shouldLock;
2152             this.inTransaction = inTransaction;
2153         }
2154
2155     }
2156
2157     private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
2158         boolean isDeployed = isDistributionDeployed(distributionId);
2159         if (isDeployed) {
2160             return Either.left(service);
2161         }
2162         Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
2163         if (distributionSuccess.isRight()) {
2164             return Either.right(distributionSuccess.right().value());
2165         }
2166
2167         log.debug("mark distribution {} as deployed - success", distributionId);
2168         componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
2169         return Either.left(service);
2170     }
2171
2172     private boolean isDistributionDeployed(String distributionId) {
2173         Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
2174
2175         boolean isDeployed = false;
2176         if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
2177             // already deployed
2178             log.debug("distribution {} is already deployed", distributionId);
2179             isDeployed = true;
2180         }
2181         return isDeployed;
2182     }
2183
2184     protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
2185
2186         log.trace("checkDistributionSuccess");
2187         // get all "DRequest" records for this distribution
2188
2189         Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
2190         if (distRequestsResponse.isRight()) {
2191             ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
2192             return Either.right(error);
2193         }
2194
2195         List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
2196         if (distributionRequests.isEmpty()) {
2197             BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
2198             log.info("distribution {} is not found", did);
2199             ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
2200             return Either.right(error);
2201         }
2202         boolean isRequestSucceeded = false;
2203         for (ResourceAdminEvent event : distributionRequests) {
2204             String eventStatus = event.getStatus();
2205             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2206                 isRequestSucceeded = true;
2207                 break;
2208             }
2209         }
2210
2211         // get all "DNotify" records for this distribution
2212         Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
2213         if (distNotificationsResponse.isRight()) {
2214             ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
2215             return Either.right(error);
2216         }
2217
2218         List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
2219         boolean isNotificationsSucceeded = false;
2220         for (DistributionNotificationEvent event : distributionNotifications) {
2221             String eventStatus = event.getStatus();
2222             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
2223                 isNotificationsSucceeded = true;
2224                 break;
2225             }
2226         }
2227
2228         // if request failed OR there are notifications that failed
2229         if (!(isRequestSucceeded && isNotificationsSucceeded)) {
2230
2231             log.info("distribution {} has failed", did);
2232             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2233             auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
2234             return Either.right(error);
2235         }
2236         return Either.left(true);
2237     }
2238
2239     private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2240
2241         ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2242         String message = "";
2243         if (error.getMessageId() != null) {
2244             message = error.getMessageId() + ": ";
2245         }
2246         message += error.getFormattedMessage();
2247
2248         if (service != null) {
2249             componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2250         } else {
2251             componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
2252         }
2253         return error;
2254     }
2255
2256     private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2257         user = userAdmin.getUser(user.getUserId());
2258         log.debug("validate user role");
2259         List<Role> roles = new ArrayList<>();
2260         roles.add(Role.ADMIN);
2261         roles.add(Role.DESIGNER);
2262         try{
2263             validateUserRole(user, service, roles, auditAction, null);
2264         } catch (ByActionStatusComponentException e){
2265             log.info("role {} is not allowed to perform this action", user.getRole());
2266             auditDeployError(did, user, auditAction, service, e.getActionStatus());
2267             throw e;
2268         }
2269         return user;
2270     }
2271
2272     @Override
2273     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2274         if(component instanceof Service){
2275             Service service = (Service) component;
2276             Map<String, ArtifactDefinition> artifactMap = service.getDeploymentArtifacts();
2277             if (artifactMap == null) {
2278                 artifactMap = new HashMap<>();
2279             }
2280             service.setDeploymentArtifacts(artifactMap);
2281         }else if(component instanceof Resource){
2282             Resource resource = (Resource) component;
2283             Map<String, ArtifactDefinition> artifactMap = resource.getDeploymentArtifacts();
2284             if (artifactMap == null) {
2285                 artifactMap = new HashMap<>();
2286             }
2287             Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager()
2288                                                                       .getConfiguration().getDeploymentResourceArtifacts();
2289             if (deploymentResourceArtifacts != null) {
2290                 Map<String, ArtifactDefinition> finalArtifactMap = artifactMap;
2291                 deploymentResourceArtifacts.forEach((k, v)->processDeploymentResourceArtifacts(user, resource, finalArtifactMap, k,v));
2292             }
2293             resource.setDeploymentArtifacts(artifactMap);
2294         }
2295
2296     }
2297
2298     private void processDeploymentResourceArtifacts(User user, Resource resource, Map<String, ArtifactDefinition> artifactMap, String k, Object v) {
2299         Map<String, Object> artifactDetails = (Map<String, Object>) v;
2300         Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES);
2301         if (object != null) {
2302             List<String> artifactTypes = (List<String>) object;
2303             if (!artifactTypes.contains(resource.getResourceType().name())) {
2304                 return;
2305             }
2306         } else {
2307             log.info("resource types for artifact placeholder {} were not defined. default is all resources",
2308                     k);
2309         }
2310         if (artifactsBusinessLogic != null) {
2311             ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(
2312                     resource.getUniqueId(), k, (Map<String, Object>) v,
2313                     user, ArtifactGroupTypeEnum.DEPLOYMENT);
2314             if (artifactDefinition != null
2315                     && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) {
2316                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
2317             }
2318         }
2319     }
2320
2321     @Override
2322     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2323         return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2324     }
2325
2326     private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2327         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2328         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2329         return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2330     }
2331
2332     @Override
2333     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2334         return componentInstanceBusinessLogic;
2335     }
2336
2337     @Override
2338     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
2339
2340         validateUserExists(userId);
2341         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2342         if (getComponentRes.isRight()) {
2343             ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2344             return Either.right(responseFormat);
2345         }
2346
2347         List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2348
2349         return Either.left(componentInstances);
2350     }
2351
2352     @Autowired
2353     public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2354         this.forwardingPathOperation = forwardingPathOperation;
2355     }
2356
2357     /**
2358      * 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
2359      *
2360      */
2361     public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2362
2363         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2364         Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2365         Component component = null;
2366         Either<Boolean, ResponseFormat> lockResult = null;
2367         log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2368         try {
2369             validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2370             if (validateUserAndComponentRes.isRight()) {
2371                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
2372                 actionResult = Either.right(validateUserAndComponentRes.right().value());
2373             }
2374             if (actionResult == null) {
2375                 component = validateUserAndComponentRes.left().value().getKey();
2376                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2377                 if (lockResult.isRight()) {
2378                     log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
2379                     actionResult = Either.right(lockResult.right().value());
2380                 } else {
2381                     log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
2382                 }
2383             }
2384             if (actionResult == null) {
2385                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2386                 if (actionResult.isRight()) {
2387                     log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2388                 }
2389             }
2390         } catch (Exception e) {
2391             log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2392             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2393         } finally {
2394             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2395                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2396             }
2397         }
2398         return actionResult;
2399     }
2400
2401     private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2402
2403         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2404         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2405         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2406         ComponentInstance relatedComponentInstance = null;
2407         GroupInstance oldGroupInstance = null;
2408         Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2409         GroupInstance updatedGroupInstance = null;
2410         boolean inTransaction = true;
2411         findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2412         if (findGroupInstanceRes.isRight()) {
2413             log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
2414             actionResult = Either.right(findGroupInstanceRes.right().value());
2415         }
2416         if (actionResult == null) {
2417             oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2418             relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2419             updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
2420             if (updateGroupInstanceResult.isRight()) {
2421                 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
2422                 actionResult = Either.right(updateGroupInstanceResult.right().value());
2423             }
2424         }
2425         if (actionResult == null) {
2426             updatedGroupInstance = updateGroupInstanceResult.left().value();
2427             if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2428                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
2429                 if (updateParentsModificationTimeRes.isRight()) {
2430                     log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
2431                     actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2432                 }
2433             }
2434         }
2435         if (actionResult == null) {
2436             actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2437         }
2438         return actionResult;
2439     }
2440
2441     private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2442                                                                                                                                                   boolean inTranscation) {
2443
2444         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2445         Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2446         Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2447                 updatedGroupInstance.getModificationTime(), inTranscation);
2448         if (updateComponentInstanceRes.isRight()) {
2449             log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2450             actionResult = Either.right(updateComponentInstanceRes.right().value());
2451         } else {
2452             serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2453             if (serviceMetadataUpdateResult.isRight()) {
2454                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2455                 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2456             } else {
2457                 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2458             }
2459         }
2460         return actionResult;
2461     }
2462
2463     private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2464
2465         Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2466         User currUser = null;
2467         Component component = null;
2468         Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2469         if (validationUserResult.isRight()) {
2470             log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2471             result = Either.right(validationUserResult.right().value());
2472         }
2473         if (result == null) {
2474             currUser = validationUserResult.left().value();
2475             try {
2476                 component = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2477                 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2478                     log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2479                     return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2480                 }
2481             } catch (ComponentException e) {
2482                 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2483                 result = Either.right(e.getResponseFormat());
2484             }
2485         }
2486
2487         if (result == null) {
2488             result = Either.left(new ImmutablePair<>(component, currUser));
2489         }
2490         return result;
2491     }
2492
2493     private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2494
2495         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2496         GroupInstance groupInstance = null;
2497         ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2498         if (foundComponentInstance == null) {
2499             log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2500             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2501         }
2502         else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2503             groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2504             if (groupInstance == null) {
2505                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2506                 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2507             }
2508         }
2509         if (actionResult == null) {
2510             actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2511         }
2512         return actionResult;
2513     }
2514
2515     private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2516         ComponentInstance componentInstance = null;
2517         if (isNotEmpty(component.getComponentInstances())) {
2518             componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2519         }
2520         return componentInstance;
2521     }
2522
2523     private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2524         User user = validateUser(modifier, ecompErrorContext, null, null, false);
2525         List<Role> roles = new ArrayList<>();
2526         roles.add(Role.ADMIN);
2527         roles.add(Role.DESIGNER);
2528         validateUserRole(user, roles);
2529         return Either.left(user);
2530     }
2531
2532     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2533
2534         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2535         paramsToReturn.setIgnoreComponentInstancesProperties(false);
2536         Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2537
2538         if (serviceResultEither.isRight()) {
2539             if(serviceResultEither.right().value() == StorageOperationStatus.NOT_FOUND) {
2540                 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2541                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2542             }
2543
2544             log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2545             return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2546         }
2547
2548         Service service = serviceResultEither.left().value();
2549                 if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
2550                         ListUtils.emptyIfNull(service.getInputs())
2551                                         .forEach(input -> input.setConstraints(setInputConstraint(input)));
2552                 }
2553
2554         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2555         return Either.left(dataTransfer);
2556     }
2557
2558     @Autowired(required = false)
2559     public void setServiceCreationPluginList(List<ServiceCreationPlugin> serviceCreationPluginList) {
2560         this.serviceCreationPluginList = serviceCreationPluginList;
2561     }
2562
2563     public boolean isServiceExist(String serviceName) {
2564         Either<Service, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByServiceName(serviceName);
2565         return latestByName.isLeft();
2566     }
2567 }