8d4f896d47c72e23491836a721baae6cc262fcbf
[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             return Either.left(currentService);
793
794         } catch (ComponentException exception) {
795             ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
796             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
797                     AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
798             return Either.right(responseFormat);
799         }
800     }
801
802     private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
803         if (updatedValue != null && !updatedValue.equals(originalValue)) {
804             log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
805         }
806     }
807
808     private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
809         Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
810         Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
811         if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
812             currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
813         }
814         String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
815         if (currentService.isEcompGeneratedNaming()) {
816             currentService.setNamingPolicy(namingPolicyUpdate);
817         } else {
818             if (!StringUtils.isEmpty(namingPolicyUpdate)) {
819                 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
820             }
821             currentService.setNamingPolicy("");
822         }
823     }
824
825     private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
826         String contactIdUpdated = serviceUpdate.getContactId();
827         String contactIdCurrent = currentService.getContactId();
828         if (!contactIdCurrent.equals(contactIdUpdated)) {
829            validateContactId(user, serviceUpdate, audatingAction);
830             currentService.setContactId(contactIdUpdated.toLowerCase());
831         }
832         return Either.left(true);
833     }
834
835     private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
836         List<String> tagsUpdated = serviceUpdate.getTags();
837         List<String> tagsCurrent = currentService.getTags();
838         if (tagsUpdated == null || tagsUpdated.isEmpty()) {
839             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
840             componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
841             return Either.right(responseFormat);
842         }
843
844         if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
845             validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
846             currentService.setTags(tagsUpdated);
847         }
848         return Either.left(true);
849     }
850
851     private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
852         String descriptionUpdated = serviceUpdate.getDescription();
853         String descriptionCurrent = currentService.getDescription();
854         if (!descriptionCurrent.equals(descriptionUpdated)) {
855             validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
856             currentService.setDescription(serviceUpdate.getDescription());
857         }
858         return Either.left(true);
859     }
860
861     private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
862         String projectCodeUpdated = serviceUpdate.getProjectCode();
863         String projectCodeCurrent = currentService.getProjectCode();
864         if (!projectCodeCurrent.equals(projectCodeUpdated)) {
865
866             Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
867             if (validatProjectCodeResponse.isRight()) {
868                 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
869                 return Either.right(errorRespons);
870             }
871             currentService.setProjectCode(projectCodeUpdated);
872
873         }
874         return Either.left(true);
875     }
876
877     private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
878         String iconUpdated = serviceUpdate.getIcon();
879         String iconCurrent = currentService.getIcon();
880         if (!iconCurrent.equals(iconUpdated)) {
881             if (!hasBeenCertified) {
882                 validateIcon(user, serviceUpdate, audatingAction);
883                 currentService.setIcon(iconUpdated);
884             } else {
885                 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
886                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
887                 return Either.right(errorResponse);
888             }
889         }
890         return Either.left(true);
891     }
892
893     private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
894         String serviceNameUpdated = serviceUpdate.getName();
895         String serviceNameCurrent = currentService.getName();
896         if (!serviceNameCurrent.equals(serviceNameUpdated)) {
897             if (!hasBeenCertified) {
898                 validateComponentName(user, serviceUpdate, auditingAction);
899                 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
900                 if (serviceNameUniquenessValidation.isRight()) {
901                     return serviceNameUniquenessValidation;
902                 }
903                 currentService.setName(serviceNameUpdated);
904                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
905                 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
906
907             } else {
908                 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
909                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
910                 return Either.right(errorResponse);
911             }
912         }
913         return Either.left(true);
914     }
915
916     private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
917         String updatedServiceType = updatedService.getServiceType();
918         String currentServiceType = currentService.getServiceType();
919         if (!currentServiceType.equals(updatedServiceType)) {
920             validateServiceTypeAndCleanup(updatedService);
921             currentService.setServiceType(updatedServiceType);
922         }
923     }
924
925     private void validateServiceTypeAndCleanup(Component component) {
926         log.debug("validate service type");
927         String serviceType = ((Service)component).getServiceType();
928         if (serviceType == null) {
929             log.info("service type is not valid.");
930             throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
931         }
932         serviceType = cleanUpText(serviceType);
933         validateServiceType(serviceType);
934     }
935
936
937     private void validateServiceType(String serviceType) {
938         if (serviceType.isEmpty()) {
939             return;
940         }
941         if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
942             log.info("service type exceeds limit.");
943             throw new ComponentException(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
944         }
945         if (!ValidationUtils.validateIsEnglish(serviceType)) {
946             log.info("service type is not valid.");
947             throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
948         }
949     }
950
951     private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
952         String updatedServiceRole = updatedService.getServiceRole();
953         String currentServiceRole = currentService.getServiceRole();
954         if (!currentServiceRole.equals(updatedServiceRole)) {
955             Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
956             if (validateServiceRole.isRight()) {
957                 ResponseFormat errorResponse = validateServiceRole.right().value();
958                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
959                 return Either.right(errorResponse);
960             }
961             currentService.setServiceRole(updatedServiceRole);
962         }
963         return Either.left(true);
964     }
965
966     protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
967         log.debug("validate service role");
968         String serviceRole = ((Service)component).getServiceRole();
969         if (serviceRole != null){
970             serviceRole = cleanUpText(serviceRole);
971
972             Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
973             if (validateServiceRole.isRight()) {
974                 ResponseFormat responseFormat = validateServiceRole.right().value();
975                 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
976                 return Either.right(responseFormat);
977             }
978             return Either.left(true);
979         } else {
980             return Either.left(false);
981         }
982     }
983
984     private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
985         String updatedInstaType= updatedService.getInstantiationType();
986         String currentInstaType = currentService.getInstantiationType();
987         if (!currentInstaType.equals(updatedInstaType)) {
988             Either<Boolean, ResponseFormat> validateInstantiationType = validateInstantiationTypeValue(user, updatedService , auditingAction);
989             if (validateInstantiationType.isRight()) {
990                 ResponseFormat errorResponse = validateInstantiationType.right().value();
991                 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
992                 return Either.right(errorResponse);
993             }
994             currentService.setInstantiationType(updatedInstaType);
995         }
996         return Either.left(true);
997     }
998
999     private Either<Boolean, ResponseFormat> validateInstantiationTypeValue(User user, Service service, AuditingActionEnum actionEnum) {
1000         log.debug("validate instantiation type");
1001         String instantiationType = service.getInstantiationType();
1002         if (!InstantiationTypes.containsName(instantiationType) || instantiationType == null){
1003                         log.error("Recieved Instantiation type {} is not valid.", instantiationType);
1004                         ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_INSTANTIATION_TYPE);
1005                         componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1006                         return Either.right(errorResponse);
1007                 }
1008                 return Either.left(true);
1009     }
1010     
1011     private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1012         if (serviceRole.equals("")){
1013             return Either.left(true);
1014         } else {
1015             if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1016                 log.info("service role exceeds limit.");
1017                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1018                 return Either.right(errorResponse);
1019             }
1020
1021             if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1022                 log.info("service role is not valid.");
1023                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1024                 return Either.right(errorResponse);
1025             }
1026             return Either.left(true);
1027         }
1028     }
1029
1030     private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1031         List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1032         List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1033         Either<Boolean, ResponseFormat> validateCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1034         if (validateCategoryResponse.isRight()) {
1035             return Either.right(validateCategoryResponse.right().value());
1036         }
1037         if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1038             if (!hasBeenCertified) {
1039                 currentService.setCategories(categoryUpdated);
1040             } else {
1041                 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1042                 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1043                 return Either.right(errorResponse);
1044             }
1045         }
1046         return Either.left(true);
1047
1048     }
1049
1050     private Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1051         if (list != null) {
1052             if (list.size() > 1) {
1053                 log.debug("Must be only one category for service");
1054                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1055                 return Either.right(responseFormat);
1056             }
1057             CategoryDefinition category = list.get(0);
1058             if (category.getSubcategories() != null) {
1059                 log.debug("Subcategories cannot be defined for service");
1060                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1061                 return Either.right(responseFormat);
1062             }
1063             if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1064                 log.debug("Resource category is empty");
1065                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1066                 return Either.right(responseFormat);
1067             }
1068
1069             log.debug("validating service category {} against valid categories list", list);
1070             Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1071             if (categorys.isRight()) {
1072                 log.debug("failed to retrive service categories from Titan");
1073                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1074                 return Either.right(responseFormat);
1075             }
1076             List<CategoryDefinition> categoryList = categorys.left().value();
1077             for (CategoryDefinition value : categoryList) {
1078                 if (value.getName().equals(category.getName())) {
1079                     return Either.left(true);
1080                 }
1081             }
1082             log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1083             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1084         }
1085         return Either.left(false);
1086     }
1087
1088     public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1089         Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1090         if (serviceResponseFormatEither.isRight()){
1091             return Either.right(serviceResponseFormatEither.right().value());
1092         }
1093         final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1094         return Either.left(serviceRelations);
1095
1096
1097     }
1098
1099     public ResponseFormat deleteService(String serviceId, User user) {
1100         ResponseFormat responseFormat;
1101         String ecompErrorContext = "delete service";
1102
1103         validateUserExists(user, ecompErrorContext, false);
1104         Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1105         if (serviceStatus.isRight()) {
1106             log.debug("failed to get service {}", serviceId);
1107             return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1108         }
1109
1110         Service service = serviceStatus.left().value();
1111
1112         StorageOperationStatus result = StorageOperationStatus.OK;
1113         Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1114         if (lockResult.isRight()) {
1115             return lockResult.right().value();
1116         }
1117         try {
1118             result = markComponentToDelete(service);
1119             if (result.equals(StorageOperationStatus.OK)) {
1120                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1121             } else {
1122                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1123                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1124             }
1125             return responseFormat;
1126         } finally {
1127             if (result == null || !result.equals(StorageOperationStatus.OK)) {
1128                 log.warn("operation failed. do rollback");
1129                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1130                 titanDao.rollback();
1131             } else {
1132                 log.debug("operation success. do commit");
1133                 titanDao.commit();
1134             }
1135             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1136         }
1137     }
1138
1139     public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1140         ResponseFormat responseFormat;
1141         String ecompErrorContext = "delete service";
1142         validateUserNotEmpty(user, ecompErrorContext);
1143         user = validateUserExists(user, ecompErrorContext, false);
1144
1145         Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1146         if (getResult.isRight()) {
1147             return getResult.right().value();
1148         }
1149         Service service = getResult.left().value();
1150
1151         StorageOperationStatus result = StorageOperationStatus.OK;
1152         Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1153         if (lockResult.isRight()) {
1154             result = StorageOperationStatus.GENERAL_ERROR;
1155             return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1156         }
1157
1158         try {
1159             result = markComponentToDelete(service);
1160             if (result.equals(StorageOperationStatus.OK)) {
1161                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1162             } else {
1163                 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1164                 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1165             }
1166             return responseFormat;
1167
1168         } finally {
1169             if (result == null || !result.equals(StorageOperationStatus.OK)) {
1170                 log.warn("operation failed. do rollback");
1171                 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1172                 titanDao.rollback();
1173             } else {
1174                 log.debug("operation success. do commit");
1175                 titanDao.commit();
1176             }
1177             graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1178         }
1179     }
1180
1181     public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1182         String ecompErrorContext = "Get service";
1183         validateUserNotEmpty(user, ecompErrorContext);
1184         validateUserExists(user, ecompErrorContext, false);
1185
1186         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1187         if (storageStatus.isRight()) {
1188             log.debug("failed to get service by id {}", serviceId);
1189             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1190         }
1191
1192         if(!(storageStatus.left().value() instanceof Service)){
1193             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1194         }
1195         Service service = storageStatus.left().value();
1196         return Either.left(service);
1197
1198
1199
1200
1201     }
1202
1203     public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1204         validateUserExists(userId, "get Service By Name And Version", false);
1205         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1206         if (storageStatus.isRight()) {
1207             log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1208             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1209         }
1210         Service service = storageStatus.left().value();
1211         return Either.left(service);
1212     }
1213
1214     @SuppressWarnings("unchecked")
1215     private void createMandatoryArtifactsData(Service service, User user) {
1216         // create mandatory artifacts
1217
1218         // TODO it must be removed after that artifact uniqueId creation will be
1219         // moved to ArtifactOperation
1220         String serviceUniqueId = service.getUniqueId();
1221         Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1222         if (artifactMap == null)
1223             artifactMap = new HashMap<>();
1224
1225         Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1226         List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1227
1228         String category = service.getCategories().get(0).getName();
1229         boolean isCreateArtifact = true;
1230         if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1231             for (String exlude : exludeServiceCategory) {
1232                 if (exlude.equalsIgnoreCase(category)) {
1233                     isCreateArtifact = false;
1234                     break;
1235                 }
1236             }
1237
1238         }
1239
1240         if (informationalServiceArtifacts != null && isCreateArtifact) {
1241             Set<String> keys = informationalServiceArtifacts.keySet();
1242             for (String informationalServiceArtifactName : keys) {
1243                 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1244                 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1245                 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1246
1247             }
1248
1249             service.setArtifacts(artifactMap);
1250         }
1251     }
1252
1253     private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1254
1255         ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1256
1257         if (isServiceApi) {
1258             artifactInfo.setMandatory(false);
1259             artifactInfo.setServiceApi(true);
1260         }
1261         return artifactInfo;
1262     }
1263
1264     private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition) {
1265         DistributionTransitionEnum transitionEnum = null;
1266
1267         transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1268         if (transitionEnum == null) {
1269             BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1270             log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1271             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1272             return Either.right(error);
1273         }
1274
1275         return Either.left(transitionEnum);
1276     }
1277
1278     private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment) {
1279         String data = comment.getUserRemarks();
1280
1281         if (data == null || data.trim().isEmpty()) {
1282             BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1283             log.debug("user comment cannot be empty or null.");
1284             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1285         }
1286         data = ValidationUtils.removeNoneUtf8Chars(data);
1287         data = ValidationUtils.removeHtmlTags(data);
1288         data = ValidationUtils.normaliseWhitespace(data);
1289         data = ValidationUtils.stripOctets(data);
1290
1291         if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1292             BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1293             log.debug("user comment exceeds limit.");
1294             return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1295         }
1296         if (!ValidationUtils.validateIsEnglish(data)) {
1297             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1298         }
1299         return Either.left(data);
1300     }
1301
1302     private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1303         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1304         if (storageStatus.isRight()) {
1305             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1306             log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1307             componentsUtils.auditComponent(responseFormat, user, auditAction, new ResourceCommonInfo(serviceId, ComponentTypeEnum.SERVICE.getValue()), comment);
1308             return Either.right(responseFormat);
1309         }
1310         Service service = storageStatus.left().value();
1311
1312         if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1313             log.info("service {} is  not available for distribution. Should be in certified state", service.getUniqueId());
1314             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1315             createAudit(user, auditAction, comment, service, responseFormat);
1316             return Either.right(responseFormat);
1317         }
1318         return Either.left(service);
1319     }
1320
1321     private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1322         log.debug("get user from DB");
1323
1324         // get user details
1325         user = validateUser(user, "Activate Distribution", service, auditAction, false);
1326         // validate user role
1327         List<Role> roles = new ArrayList<>();
1328         roles.add(Role.ADMIN);
1329         roles.add(Role.GOVERNOR);
1330         roles.add(Role.OPS);
1331         validateUserRole(user, service, roles, auditAction, comment);
1332         return Either.left(user);
1333     }
1334
1335     private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1336         log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1337         componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1338                 ResourceVersionInfo.newBuilder()
1339                         .state(component.getLifecycleState().name())
1340                         .version(component.getVersion())
1341                         .build(),
1342                 comment);
1343     }
1344
1345     private String getEnvNameFromConfiguration() {
1346         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1347         log.trace("Update environment name to be {}", configuredEnvName);
1348         return configuredEnvName;
1349     }
1350
1351     public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1352
1353         Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1354         if (activationRequestInformationEither.isRight()) {
1355             return Either.right(activationRequestInformationEither.right().value());
1356         }
1357
1358         ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1359
1360         Either<String, ResponseFormat> result = null;
1361         String did = ThreadLocalsHolder.getUuid();
1362         Service service = activationRequestInformation.getServiceToActivate();
1363         result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1364         return result;
1365     }
1366
1367     public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1368         String envName = getEnvNameFromConfiguration();
1369         INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1370         ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1371         if (notifyServiceResponse == ActionStatus.OK) {
1372             return Either.left(did);
1373         } else {
1374             BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1375             log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1376             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1377             return Either.right(error);
1378         }
1379     }
1380
1381     public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1382
1383         User user = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1384         Either<Service, ResponseFormat> result = null;
1385         ResponseFormat response = null;
1386         Service updatedService = null;
1387         String did = ThreadLocalsHolder.getUuid();
1388          // DE194021
1389         String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1390         if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1391             log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1392             envName = configuredEnvName;
1393         }
1394         // DE194021
1395
1396         ServletContext servletContext = request.getSession().getServletContext();
1397         boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1398         if (!isDistributionEngineUp) {
1399             BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1400             log.debug("Distribution Engine is DOWN");
1401             response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1402             return Either.right(response);
1403         }
1404
1405         Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1406         if (serviceRes.isRight()) {
1407             log.debug("failed retrieving service");
1408             response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1409             componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1410                     new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1411                     ResourceVersionInfo.newBuilder()
1412                             .build(),
1413                     did);
1414             return Either.right(response);
1415         }
1416         Service service = serviceRes.left().value();
1417         String dcurrStatus = service.getDistributionStatus().name();
1418         String updatedStatus = dcurrStatus;
1419         StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1420         if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1421             INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1422             ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1423             if (notifyServiceResponse == ActionStatus.OK) {
1424                 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1425                 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1426                     updatedService = updateStateRes.left().value();
1427                     updatedStatus = updatedService.getDistributionStatus().name();
1428                 } else {
1429                     // The response is not relevant
1430                     updatedService = service;
1431                 }
1432                 ASDCKpiApi.countActivatedDistribution();
1433                 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1434                 result = Either.left(updatedService);
1435             } else {
1436                 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1437                 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1438                 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1439                 result = Either.right(response);
1440             }
1441         } else {
1442             response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), envName);
1443             result = Either.right(response);
1444         }
1445         componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1446                 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1447                 ResourceVersionInfo.newBuilder()
1448                         .distributionStatus(dcurrStatus)
1449                         .build(),
1450                 ResourceVersionInfo.newBuilder()
1451                         .distributionStatus(updatedStatus)
1452                         .build(),
1453                 null, null, did);
1454         return result;
1455     }
1456
1457     // convert to private after deletion of temp url
1458     public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1459
1460         validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1461
1462         String serviceId = service.getUniqueId();
1463         Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1464         if (lockResult.isRight()) {
1465             return Either.right(lockResult.right().value());
1466         }
1467         try {
1468             Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1469             if (result.isRight()) {
1470                 titanDao.rollback();
1471                 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1472                 log.debug("service {}  change distribution status failed", serviceId);
1473                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1474             }
1475             titanDao.commit();
1476             return Either.left(result.left().value());
1477         } finally {
1478             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1479         }
1480     }
1481
1482     public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1483
1484         validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
1485         log.debug("mark distribution deployed");
1486
1487         AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1488         Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1489         if (getServiceResponse.isRight()) {
1490             BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1491             log.debug("service {} not found", serviceId);
1492             ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1493
1494             return Either.right(responseFormat);
1495         }
1496
1497         Service service = getServiceResponse.left().value();
1498         user = validateRoleForDeploy(did, user, auditAction, service);
1499         return checkDistributionAndDeploy(did, user, auditAction, service);
1500
1501     }
1502
1503     public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1504         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1505                 // Only one VF Module Artifact per instance - add it to a list of one
1506                 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1507
1508         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1509
1510     }
1511
1512     private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
1513         List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1514
1515         if (ri.getOriginType() == OriginTypeEnum.VF) {
1516             asList = Arrays.asList(new VfModuleArtifacGenerator(modifier, ri, service, shouldLock, inTransaction));
1517         }
1518         return asList;
1519     }
1520
1521     private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
1522         Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1523         if(currVF.getGroupInstances() != null){
1524             currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1525         }
1526         return currVF.getGroupInstances();
1527     }
1528
1529     private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
1530         ArtifactDefinition vfModuleAertifact = null;
1531         if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1532             Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
1533             if (optionalVfModuleArtifact.isPresent()) {
1534                 vfModuleAertifact = optionalVfModuleArtifact.get();
1535             }
1536         }
1537         if (vfModuleAertifact == null) {
1538             Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
1539             if (createVfModuleArtifact.isLeft()) {
1540                 vfModuleAertifact = createVfModuleArtifact.left().value();
1541             } else {
1542                 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1543             }
1544         }
1545         return vfModuleAertifact;
1546     }
1547
1548     private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1549         List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
1550         if (groupsForCurrVF != null) {
1551             for (GroupInstance groupInstance : groupsForCurrVF) {
1552                 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1553                 vfModulePayloads.add(modulePayload);
1554             }
1555             vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
1556
1557             final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1558
1559             String vfModulePayloadString = gson.toJson(vfModulePayloads);
1560             payloadWrapper.setInnerElement(vfModulePayloadString);
1561         }
1562
1563     }
1564
1565     private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
1566         ArtifactDefinition vfModuleArtifact = null;
1567         Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1568         Wrapper<String> payloadWrapper = new Wrapper<>();
1569         List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
1570         if (responseWrapper.isEmpty()) {
1571             fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1572         }
1573         if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1574             vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
1575         }
1576         if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
1577             vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
1578         }
1579
1580         Either<ArtifactDefinition, ResponseFormat> result;
1581         if (responseWrapper.isEmpty()) {
1582             result = Either.left(vfModuleArtifact);
1583         } else {
1584             result = Either.right(responseWrapper.getInnerElement());
1585         }
1586
1587         return result;
1588     }
1589
1590     private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
1591         ArtifactDefinition result = null;
1592         Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
1593                 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
1594         if (eitherPayload.isLeft()) {
1595             result = eitherPayload.left().value();
1596         } else {
1597             responseWrapper.setInnerElement(eitherPayload.right().value());
1598         }
1599         if (result == null) {
1600             result = vfModuleArtifact;
1601         }
1602
1603         return result;
1604     }
1605
1606     private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
1607
1608         ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
1609         String newCheckSum = null;
1610
1611         vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
1612         vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
1613         vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
1614         vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
1615         vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
1616         vfModuleArtifactDefinition.setTimeout(0);
1617         vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
1618         vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
1619         if (vfModulePayloadString != null) {
1620             newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
1621         }
1622         vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
1623
1624         Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
1625
1626         Either<ArtifactDefinition, ResponseFormat> result;
1627         if (addArifactToComponent.isLeft()) {
1628             result = Either.left(addArifactToComponent.left().value());
1629         } else {
1630             result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
1631         }
1632
1633         return result;
1634     }
1635
1636     public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1637
1638         Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1639                 // Get All Deployment Artifacts
1640                 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1641                         // Filter in Only Heat Env
1642                                 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1643                         // Create ArtifactGenerator from those Artifacts
1644                                 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
1645
1646         return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1647
1648     }
1649
1650     private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1651
1652         // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1653         // service
1654         if (service.getComponentInstances() != null) {
1655             List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1656             if (artifactGenList != null && !artifactGenList.isEmpty()) {
1657                 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1658                     Either<CallVal, ResponseFormat> callRes;
1659                     try {
1660                         callRes = entry.call();
1661                         if (callRes.isRight()) {
1662                             log.debug("Failed to generate artifact error : {}", callRes.right().value());
1663                             return Either.right(callRes.right().value());
1664                         }
1665                     } catch (Exception e) {
1666                         log.debug("Failed to generate artifact exception : {}", e);
1667                         return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1668                     }
1669                 }
1670             }
1671         }
1672         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1673         if (storageStatus.isRight()) {
1674             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1675         }
1676
1677         Service currentService = storageStatus.left().value();
1678
1679         return Either.left(currentService);
1680
1681     }
1682
1683     abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
1684
1685     }
1686
1687     class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
1688         ArtifactDefinition artifactDefinition;
1689         Service service;
1690         String resourceInstanceName;
1691         User modifier;
1692         String instanceId;
1693         boolean shouldLock;
1694         boolean inTransaction;
1695
1696         HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
1697             this.artifactDefinition = artifactDefinition;
1698             this.service = service;
1699             this.resourceInstanceName = resourceInstanceName;
1700             this.modifier = modifier;
1701             this.shouldLock = shouldLock;
1702             this.instanceId = instanceId;
1703             this.inTransaction = inTransaction;
1704         }
1705
1706         @Override
1707         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1708             return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
1709         }
1710
1711         public ArtifactDefinition getArtifactDefinition() {
1712             return artifactDefinition;
1713         }
1714
1715     }
1716
1717     class VfModuleArtifacGenerator extends ArtifactGenerator<ArtifactDefinition> {
1718         private User user;
1719         private ComponentInstance componentInstance;
1720         private Service service;
1721         boolean shouldLock;
1722         boolean inTransaction;
1723
1724         @Override
1725         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1726             return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
1727         }
1728
1729         private VfModuleArtifacGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
1730             super();
1731             this.user = user;
1732             this.componentInstance = componentInstance;
1733             this.service = service;
1734             this.shouldLock = shouldLock;
1735             this.inTransaction = inTransaction;
1736         }
1737
1738     }
1739
1740     private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
1741         boolean isDeployed = isDistributionDeployed(distributionId);
1742         if (isDeployed) {
1743             return Either.left(service);
1744         }
1745         Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
1746         if (distributionSuccess.isRight()) {
1747             return Either.right(distributionSuccess.right().value());
1748         }
1749
1750         log.debug("mark distribution {} as deployed - success", distributionId);
1751         componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
1752         return Either.left(service);
1753     }
1754
1755     private boolean isDistributionDeployed(String distributionId) {
1756         Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1757
1758         boolean isDeployed = false;
1759         if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1760             // already deployed
1761             log.debug("distribution {} is already deployed", distributionId);
1762             isDeployed = true;
1763         }
1764         return isDeployed;
1765     }
1766
1767     protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1768
1769         log.trace("checkDistributionSuccess");
1770         // get all "DRequest" records for this distribution
1771
1772         Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1773         if (distRequestsResponse.isRight()) {
1774             ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1775             return Either.right(error);
1776         }
1777
1778         List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1779         if (distributionRequests.isEmpty()) {
1780             BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1781             log.info("distribution {} is not found", did);
1782             ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1783             return Either.right(error);
1784         }
1785         boolean isRequestSucceeded = false;
1786         for (ResourceAdminEvent event : distributionRequests) {
1787             String eventStatus = event.getStatus();
1788             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1789                 isRequestSucceeded = true;
1790                 break;
1791             }
1792         }
1793
1794         // get all "DNotify" records for this distribution
1795         Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1796         if (distNotificationsResponse.isRight()) {
1797             ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1798             return Either.right(error);
1799         }
1800
1801         List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1802         boolean isNotificationsSucceeded = false;
1803         for (DistributionNotificationEvent event : distributionNotifications) {
1804             String eventStatus = event.getStatus();
1805             if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1806                 isNotificationsSucceeded = true;
1807                 break;
1808             }
1809         }
1810
1811         // if request failed OR there are notifications that failed
1812         if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1813
1814             log.info("distribution {} has failed", did);
1815             ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1816             auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1817             return Either.right(error);
1818         }
1819         return Either.left(true);
1820     }
1821
1822     private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
1823
1824         ResponseFormat error = componentsUtils.getResponseFormat(status, params);
1825         String message = "";
1826         if (error.getMessageId() != null) {
1827             message = error.getMessageId() + ": ";
1828         }
1829         message += error.getFormattedMessage();
1830
1831         if (service != null) {
1832             componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
1833         } else {
1834             componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
1835         }
1836         return error;
1837     }
1838
1839     private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
1840         Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
1841         if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
1842             BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
1843             log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
1844             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
1845             auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
1846             throw new ComponentException(ActionStatus.USER_NOT_FOUND, user.getUserId());
1847         }
1848         user = eitherCreator.left().value();
1849         log.debug("validate user role");
1850         List<Role> roles = new ArrayList<>();
1851         roles.add(Role.ADMIN);
1852         roles.add(Role.OPS);
1853         try{
1854             validateUserRole(user, service, roles, auditAction, null);
1855         } catch (ComponentException e){
1856             log.info("role {} is not allowed to perform this action", user.getRole());
1857             auditDeployError(did, user, auditAction, service, e.getActionStatus());
1858             throw e;
1859         }
1860         return user;
1861     }
1862
1863     @Override
1864     public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
1865
1866     }
1867
1868     @Override
1869     public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
1870         return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
1871     }
1872
1873     private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
1874         WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
1875         WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
1876         return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
1877     }
1878
1879     @Override
1880     public ComponentInstanceBusinessLogic getComponentInstanceBL() {
1881         return componentInstanceBusinessLogic;
1882     }
1883
1884     @Override
1885     public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
1886
1887         validateUserExists(userId, "Get Component Instances", false);
1888         Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
1889         if (getComponentRes.isRight()) {
1890             ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
1891             return Either.right(responseFormat);
1892         }
1893
1894         List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
1895
1896         return Either.left(componentInstances);
1897     }
1898
1899     public ICacheMangerOperation getCacheManagerOperation() {
1900         return cacheManagerOperation;
1901     }
1902
1903     public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
1904         this.cacheManagerOperation = cacheManagerOperation;
1905     }
1906
1907     public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
1908         this.forwardingPathOperation = forwardingPathOperation;
1909     }
1910
1911     @Override
1912     public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
1913         this.toscaOperationFacade = toscaOperationFacade;
1914     }/**
1915      * 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
1916      *
1917      */
1918     public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
1919
1920         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
1921         Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
1922         Component component = null;
1923         Either<Boolean, ResponseFormat> lockResult = null;
1924         log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
1925         try {
1926             validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
1927             if (validateUserAndComponentRes.isRight()) {
1928                 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed.  ", groupInstanceId, serviceId);
1929                 actionResult = Either.right(validateUserAndComponentRes.right().value());
1930             }
1931             if (actionResult == null) {
1932                 component = validateUserAndComponentRes.left().value().getKey();
1933                 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
1934                 if (lockResult.isRight()) {
1935                     log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
1936                     actionResult = Either.right(lockResult.right().value());
1937                 } else {
1938                     log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
1939                 }
1940             }
1941             if (actionResult == null) {
1942                 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
1943                 if (actionResult.isRight()) {
1944                     log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
1945                 }
1946             }
1947         } catch (Exception e) {
1948             log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
1949             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1950         } finally {
1951             if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1952                 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
1953             }
1954         }
1955         return actionResult;
1956     }
1957
1958     private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
1959
1960         Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
1961         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
1962         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
1963         ComponentInstance relatedComponentInstance = null;
1964         GroupInstance oldGroupInstance = null;
1965         Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
1966         GroupInstance updatedGroupInstance = null;
1967         boolean inTransaction = true;
1968         findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
1969         if (findGroupInstanceRes.isRight()) {
1970             log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
1971             actionResult = Either.right(findGroupInstanceRes.right().value());
1972         }
1973         if (actionResult == null) {
1974             oldGroupInstance = findGroupInstanceRes.left().value().getValue();
1975             relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
1976             updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
1977             if (updateGroupInstanceResult.isRight()) {
1978                 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
1979                 actionResult = Either.right(updateGroupInstanceResult.right().value());
1980             }
1981         }
1982         if (actionResult == null) {
1983             updatedGroupInstance = updateGroupInstanceResult.left().value();
1984             if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
1985                 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
1986                 if (updateParentsModificationTimeRes.isRight()) {
1987                     log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
1988                     actionResult = Either.right(updateParentsModificationTimeRes.right().value());
1989                 }
1990             }
1991         }
1992         if (actionResult == null) {
1993             actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
1994         }
1995         return actionResult;
1996     }
1997
1998     private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
1999                                                                                                                                                   boolean inTranscation) {
2000
2001         Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2002         Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2003         Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2004                 updatedGroupInstance.getModificationTime(), inTranscation);
2005         if (updateComponentInstanceRes.isRight()) {
2006             log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2007             actionResult = Either.right(updateComponentInstanceRes.right().value());
2008         } else {
2009             serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2010             if (serviceMetadataUpdateResult.isRight()) {
2011                 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2012                 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2013             } else {
2014                 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2015             }
2016         }
2017         return actionResult;
2018     }
2019
2020     private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2021
2022         Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2023         Either<Component, ResponseFormat> validateComponentExistsRes = null;
2024         User currUser = null;
2025         Component component = null;
2026         Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2027         if (validationUserResult.isRight()) {
2028             log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2029             result = Either.right(validationUserResult.right().value());
2030         }
2031         if (result == null) {
2032             currUser = validationUserResult.left().value();
2033             validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2034             if (validateComponentExistsRes.isRight()) {
2035                 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2036                 result = Either.right(validateComponentExistsRes.right().value());
2037             }
2038         }
2039         if (result == null) {
2040             component = validateComponentExistsRes.left().value();
2041             if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2042                 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2043                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2044             }
2045         }
2046         if (result == null) {
2047             result = Either.left(new ImmutablePair<>(component, currUser));
2048         }
2049         return result;
2050     }
2051
2052     private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2053
2054         Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2055         GroupInstance groupInstance = null;
2056         ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2057         if (foundComponentInstance == null) {
2058             log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2059             actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2060         }
2061         else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2062             groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2063             if (groupInstance == null) {
2064                 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2065                 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2066             }
2067         }
2068         if (actionResult == null) {
2069             actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2070         }
2071         return actionResult;
2072     }
2073
2074     private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2075         ComponentInstance componentInstance = null;
2076         if (isNotEmpty(component.getComponentInstances())) {
2077             componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2078         }
2079         return componentInstance;
2080     }
2081
2082     private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2083         User user = validateUser(modifier, ecompErrorContext, null, null, false);
2084         List<Role> roles = new ArrayList<>();
2085         roles.add(Role.ADMIN);
2086         roles.add(Role.DESIGNER);
2087         validateUserRole(user, roles);
2088         return Either.left(user);
2089     }
2090
2091     public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2092
2093         ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2094         Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2095
2096         if (serviceResultEither.isRight()) {
2097             if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2098                 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2099                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2100             }
2101
2102             log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2103             return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2104         }
2105
2106         Service service = serviceResultEither.left().value();
2107         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2108         return Either.left(dataTransfer);
2109     }
2110 }