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