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