2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.be.components.impl;
23 import java.nio.charset.StandardCharsets;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.List;
31 import java.util.Optional;
33 import java.util.concurrent.Callable;
34 import java.util.function.Function;
35 import java.util.stream.Collectors;
37 import javax.servlet.ServletContext;
38 import javax.servlet.http.HttpServletRequest;
40 import org.apache.commons.collections.CollectionUtils;
41 import org.apache.commons.collections.MapUtils;
42 import org.apache.commons.lang3.tuple.ImmutablePair;
43 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
44 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
45 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
46 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
47 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
48 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
49 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
50 import org.openecomp.sdc.be.config.BeEcompErrorManager;
51 import org.openecomp.sdc.be.config.ConfigurationManager;
52 import org.openecomp.sdc.be.dao.api.ActionStatus;
53 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
54 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
55 import org.openecomp.sdc.be.datamodel.ServiceRelations;
56 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
57 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
58 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
59 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
60 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
61 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
62 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
63 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
64 import org.openecomp.sdc.be.model.ArtifactDefinition;
65 import org.openecomp.sdc.be.model.Component;
66 import org.openecomp.sdc.be.model.ComponentInstance;
67 import org.openecomp.sdc.be.model.ComponentParametersView;
68 import org.openecomp.sdc.be.model.DistributionStatusEnum;
69 import org.openecomp.sdc.be.model.DistributionTransitionEnum;
70 import org.openecomp.sdc.be.model.GroupInstance;
71 import org.openecomp.sdc.be.model.GroupInstanceProperty;
72 import org.openecomp.sdc.be.model.LifecycleStateEnum;
73 import org.openecomp.sdc.be.model.Resource;
74 import org.openecomp.sdc.be.model.Service;
75 import org.openecomp.sdc.be.model.User;
76 import org.openecomp.sdc.be.model.category.CategoryDefinition;
77 import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
78 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
79 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
80 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
81 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
82 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
83 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
84 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
85 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
86 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
87 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
88 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
89 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
90 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
91 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceAuditData;
92 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
93 import org.openecomp.sdc.be.user.Role;
94 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
95 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
96 import org.openecomp.sdc.common.api.Constants;
97 import org.openecomp.sdc.common.datastructure.Wrapper;
98 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
99 import org.openecomp.sdc.common.util.GeneralUtility;
100 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
101 import org.openecomp.sdc.common.util.ValidationUtils;
102 import org.openecomp.sdc.exception.ResponseFormat;
103 import org.slf4j.Logger;
104 import org.slf4j.LoggerFactory;
105 import org.springframework.beans.factory.annotation.Autowired;
106 import org.springframework.web.context.WebApplicationContext;
108 import com.google.common.base.Strings;
109 import com.google.gson.Gson;
110 import com.google.gson.GsonBuilder;
112 import fj.data.Either;
114 @org.springframework.stereotype.Component("serviceBusinessLogic")
115 public class ServiceBusinessLogic extends ComponentBusinessLogic {
117 private static final String STATUS_SUCCESS_200 = "200";
119 private static final String STATUS_DEPLOYED = "DEPLOYED";
122 private IElementOperation elementDao;
125 private IDistributionEngine distributionEngine;
128 private AuditCassandraDao auditCassandraDao;
131 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
134 private GroupBusinessLogic groupBusinessLogic;
137 private ICacheMangerOperation cacheManagerOperation;
140 private ServiceDistributionValidation serviceDistributionValidation;
142 private static final Logger log = LoggerFactory.getLogger(ServiceBusinessLogic.class);
143 private static final String INITIAL_VERSION = "0.1";
145 private ForwardingPathOperation forwardingPathOperation;
148 private ForwardingPathValidator forwardingPathValidator;
150 public ServiceBusinessLogic() {
151 log.debug("ServiceBusinessLogic started");
154 public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
156 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "change Service Distribution State", false);
157 if (resp.isRight()) {
158 return Either.right(resp.right().value());
161 log.debug("check request state");
162 Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state, user);
163 if (validateEnum.isRight()) {
164 return Either.right(validateEnum.right().value());
166 DistributionTransitionEnum distributionTransition = validateEnum.left().value();
167 AuditingActionEnum auditAction = distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT;
168 Either<String, ResponseFormat> commentResponse = validateComment(commentObj, user, auditAction);
169 if (commentResponse.isRight()) {
170 return Either.right(commentResponse.right().value());
172 String comment = commentResponse.left().value();
174 Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
175 if (validateService.isRight()) {
176 return Either.right(validateService.right().value());
178 Service service = validateService.left().value();
179 Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
180 if (validateUser.isRight()) {
181 return Either.right(validateUser.right().value());
183 user = validateUser.left().value();
187 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
188 if (lockResult.isRight()) {
189 ResponseFormat responseFormat = lockResult.right().value();
190 createAudit(user, auditAction, comment, service, responseFormat);
191 return Either.right(responseFormat);
196 DistributionStatusEnum newState;
197 if (distributionTransition == DistributionTransitionEnum.APPROVE) {
198 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
200 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
202 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
203 if (result.isRight()) {
205 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
206 log.debug("service {} is change destribuation status failed", service.getUniqueId());
207 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
208 createAudit(user, auditAction, comment, service, responseFormat);
209 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
212 Service updatedService = result.left().value();
213 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
214 log.debug("audit before sending response");
215 componentsUtils.auditComponent(responseFormat, user, updatedService, auditAction, ComponentTypeEnum.SERVICE, ResourceAuditData.newBuilder().build(), comment);
216 return Either.left(result.left().value());
218 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
223 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
224 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Component Audit Records", false);
225 if (resp.isRight()) {
226 return Either.right(resp.right().value());
228 Either<List<Map<String, Object>>, ActionStatus> result;
232 if (componentVersion.endsWith(".0")) {
233 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
234 if (eitherAuditingForCertified.isLeft()) {
235 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
237 result = Either.right(eitherAuditingForCertified.right().value());
240 // Uncertified Version
242 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
244 } catch (Exception e) {
245 log.debug("get Audit Records failed with exception {}", e);
246 result = Either.right(ActionStatus.GENERAL_ERROR);
249 if (result.isRight()) {
250 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
252 return Either.left(result.left().value());
257 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
259 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
261 if (eitherprevVerAudit.isRight()) {
262 return Either.right(eitherprevVerAudit.right().value());
266 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
267 if (eitherCurrVerAudit.isRight()) {
268 return Either.right(eitherCurrVerAudit.right().value());
271 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
272 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
274 List<Map<String, Object>> duplicateElements = new ArrayList<Map<String, Object>>();
275 duplicateElements.addAll(prevVerAuditList);
276 duplicateElements.retainAll(currVerAuditList);
278 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<Map<String, Object>>();
279 joinedNonDuplicatedList.addAll(prevVerAuditList);
280 joinedNonDuplicatedList.removeAll(duplicateElements);
281 joinedNonDuplicatedList.addAll(currVerAuditList);
283 return Either.left(joinedNonDuplicatedList);
286 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
288 List<Map<String, Object>> prevVerAudit = new ArrayList<Map<String, Object>>();
289 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
290 auditEvent.fillFields();
291 prevVerAudit.add(auditEvent.getFields());
302 * - modifier data (userId)
303 * @return Either<Service, responseFormat>
305 public Either<Service, ResponseFormat> createService(Service service, User user) {
308 Either<User, ResponseFormat> eitherCreator = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
309 if (eitherCreator.isRight()) {
310 return Either.right(eitherCreator.right().value());
312 user = eitherCreator.left().value();
314 // validate user role
315 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, new ArrayList<Role>(), AuditingActionEnum.CREATE_RESOURCE, null);
316 if (validateRes.isRight()) {
317 return Either.right(validateRes.right().value());
319 service.setCreatorUserId(user.getUserId());
321 // warn on overridden fields
322 checkFieldsForOverideAttampt(service);
324 log.debug("enrich service with version and state");
325 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
326 service.setVersion(INITIAL_VERSION);
327 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
328 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
330 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
331 if (createServiceResponse.isRight()) {
332 return createServiceResponse;
334 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
337 private void checkFieldsForOverideAttampt(Service service) {
338 checkComponentFieldsForOverrideAttempt(service);
339 if (service.getDistributionStatus() != null) {
340 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
344 private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
345 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
347 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
348 if (lockResult.isRight()) {
349 ResponseFormat responseFormat = lockResult.right().value();
350 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
351 return Either.right(responseFormat);
354 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
358 createMandatoryArtifactsData(service, user);
359 createServiceApiArtifactsData(service, user);
360 setToscaArtifactsPlaceHolders(service, user);
361 Either<Resource, ResponseFormat> genericServiceEither = fetchAndSetDerivedFromGenericType(service);
362 if (genericServiceEither.isRight())
363 return Either.right(genericServiceEither.right().value());
365 generateAndAddInputsFromGenericTypeProperties(service, genericServiceEither.left().value());
367 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
369 // service created successfully!!!
370 if (dataModelResponse.isLeft()) {
371 log.debug("Service created successfully!!!");
372 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
373 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
374 ASDCKpiApi.countCreatedServicesKPI();
375 return Either.left(dataModelResponse.left().value());
378 ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
379 log.debug("audit before sending response");
380 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
381 return Either.right(responseFormat);
384 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
388 @SuppressWarnings("unchecked")
389 private void createServiceApiArtifactsData(Service service, User user) {
390 // create mandatory artifacts
392 // TODO it must be removed after that artifact uniqueId creation will be
393 // moved to ArtifactOperation
394 String serviceUniqueId = service.getUniqueId();
395 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
396 if (artifactMap == null)
397 artifactMap = new HashMap<String, ArtifactDefinition>();
399 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
400 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
402 List<CategoryDefinition> categories = service.getCategories();
403 boolean isCreateArtifact = true;
404 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
405 for (String exlude : exludeServiceCategory) {
406 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
407 isCreateArtifact = false;
414 if (serviceApiArtifacts != null && isCreateArtifact) {
415 Set<String> keys = serviceApiArtifacts.keySet();
416 for (String serviceApiArtifactName : keys) {
417 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
418 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
419 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
420 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
423 service.setServiceApiArtifacts(artifactMap);
427 private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
429 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
430 if (validationResponse.isRight()) {
431 return Either.right(validationResponse.right().value());
433 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
434 service.setContactId(service.getContactId().toLowerCase());
436 // Generate invariant UUID - must be here and not in operation since it
437 // should stay constant during clone
438 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
439 service.setInvariantUUID(invariantUUID);
441 return Either.left(service);
444 private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
445 Either<Boolean, ResponseFormat> componentsFieldsValidation = validateComponentFieldsBeforeCreate(user, service, actionEnum);
446 if (componentsFieldsValidation.isRight()) {
447 return componentsFieldsValidation;
450 log.debug("validate service name uniqueness");
451 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
452 if (serviceNameUniquenessValidation.isRight()) {
453 return serviceNameUniquenessValidation;
456 log.debug("validate category");
457 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
458 if (categoryValidation.isRight()) {
459 return categoryValidation;
462 // validate project name (ProjectCode) - mandatory in service
463 log.debug("validate projectName");
464 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
465 if (projectCodeValidation.isRight()) {
466 return projectCodeValidation;
469 log.debug("validate service type");
470 Either<Boolean, ResponseFormat> serviceTypeValidation = validateServiceTypeAndCleanup(user, service, actionEnum);
471 if (serviceTypeValidation.isRight()) {
472 return serviceTypeValidation;
475 log.debug("validate service role");
476 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
477 if (serviceRoleValidation.isRight()) {
478 return serviceRoleValidation;
481 return Either.left(true);
485 private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
486 log.debug("validate Service category");
488 if (service.getCategories() == null || service.getCategories().size() == 0) {
489 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
490 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
491 return Either.right(errorResponse);
494 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
495 if (validatCategory.isRight()) {
496 ResponseFormat responseFormat = validatCategory.right().value();
497 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
498 return Either.right(responseFormat);
501 return Either.left(true);
504 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
506 Either<User, ResponseFormat> resp = validateUserExists(userId, "validate Service Name Exists", false);
507 if (resp.isRight()) {
508 return Either.right(resp.right().value());
511 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
516 if (dataModelResponse.isLeft()) {
517 Map<String, Boolean> result = new HashMap<>();
518 result.put("isValid", dataModelResponse.left().value());
519 log.debug("validation was successfully performed.");
520 return Either.left(result);
523 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
525 return Either.right(responseFormat);
528 public void setElementDao(IElementOperation elementDao) {
529 this.elementDao = elementDao;
532 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
533 this.auditCassandraDao = auditingDao;
536 public ArtifactsBusinessLogic getArtifactBl() {
537 return artifactsBusinessLogic;
540 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
541 this.artifactsBusinessLogic = artifactBl;
544 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
545 Either<User, ResponseFormat> eitherCreator = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
546 if (eitherCreator.isRight()) {
547 return Either.right(eitherCreator.right().value());
549 user = eitherCreator.left().value();
551 // validate user role
552 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
553 if (validateRes.isRight()) {
554 return Either.right(validateRes.right().value());
557 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
558 if (storageStatus.isRight()) {
559 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
562 Service currentService = storageStatus.left().value();
564 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
565 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
566 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
569 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
570 if (validationRsponse.isRight()) {
571 log.info("service update metadata: validations field.");
572 return validationRsponse;
574 Service serviceToUpdate = validationRsponse.left().value();
577 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
578 if (lockResult.isRight()) {
579 return Either.right(lockResult.right().value());
582 Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
583 if (updateResponse.isRight()) {
585 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
586 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
587 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
590 return Either.left(updateResponse.left().value());
592 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
596 public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
597 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
598 Either<User, ResponseFormat> eitherCreator = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
599 if (eitherCreator.isRight()) {
600 return Either.right(eitherCreator.right().value());
602 user = eitherCreator.left().value();
604 // validate user role
605 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
606 if (validateRes.isRight()) {
607 return Either.right(validateRes.right().value());
609 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
610 if (storageStatus.isRight()) {
611 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
613 Service service = storageStatus.left().value();
614 Either<Set<String>, StorageOperationStatus> result = null;
616 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
617 if (lockResult.isRight()) {
619 return Either.right(componentsUtils.getResponseFormat(componentsUtils
620 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
624 result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
625 if (result.isRight()) {
626 log.debug("Failed to lock service {}. Response is {}. ", service.getName(), result.right().value());
628 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
631 log.debug("The service with system name {} locked. ", service.getSystemName());
633 } catch (Exception e){
634 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
636 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
638 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
640 return Either.left(result.left().value());
643 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
644 Service serviceToDelete = new Service();
645 serviceToDelete.setUniqueId(serviceId);
646 serviceToDelete.setForwardingPaths(new HashMap<>());
647 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
648 return serviceToDelete;
651 public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
652 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
655 public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
656 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
659 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path){
660 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
661 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
662 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
663 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
664 dataDefinition.setUniqueId(path.getUniqueId());
665 dataDefinition.setPathElements(path.getPathElements());
666 dataDefinition.setDescription(path.getDescription());
667 dataDefinition.setToscaResourceName(path.getToscaResourceName());
668 return dataDefinition;
671 private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
672 Either<Service, ResponseFormat> eitherCreator1 = validateUserAndRole(serviceUpdate, user, errorContext);
673 if (eitherCreator1 != null) return eitherCreator1;
675 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
677 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
678 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
679 entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
681 Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
682 serviceId, isUpdate);
683 if(booleanResponseFormatEither.isRight()){
684 return Either.right(booleanResponseFormatEither.right().value());
687 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
689 if(serviceStorageOperationStatusEither.isRight()){
690 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
691 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
692 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
694 Service storedService = serviceStorageOperationStatusEither.left().value();
696 Set<ForwardingPathDataDefinition> forwardingPathDataDefinitions = trimmedForwardingPaths.entrySet().stream().map(entry -> entry.getValue())
697 .collect(Collectors.toSet());
699 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
700 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
701 if (forwardingPathOrigin.isRight()) {
702 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
703 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
704 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
706 Component component = forwardingPathOrigin.left().value();
707 final String toscaResourceName;
708 if ( component.getComponentType() == ComponentTypeEnum.RESOURCE) {
709 toscaResourceName = ((Resource) component).getToscaResourceName();
711 toscaResourceName = "";
713 Either<Boolean, ResponseFormat> lockResult = null;
716 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
717 if (lockResult.isRight()) {
718 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
719 lockResult.right().value().getFormattedMessage());
720 return Either.right(lockResult.right().value());
722 log.debug("The service with system name {} locked. ", storedService.getSystemName());
725 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
727 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
730 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
732 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
734 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
736 if (result.isRight()) {
738 return Either.right(componentsUtils.getResponseFormat(
739 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
742 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
743 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
747 } catch (Exception e) {
749 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
751 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
755 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
756 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
759 Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
760 return Either.left(service);
763 private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
764 Service service = new Service();
765 service.setUniqueId(serviceId);
766 service.setForwardingPaths(forwardingPathDataDefinitionMap);
770 private Either<Service, ResponseFormat> validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
771 Either<User, ResponseFormat> eitherCreator = validateUser(user, errorContext, serviceUpdate, null, false);
772 if (eitherCreator.isRight()) {
773 return Either.right(eitherCreator.right().value());
775 user = eitherCreator.left().value();
777 // validate user role
778 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
779 if (validateRes.isRight()) {
780 return Either.right(validateRes.right().value());
783 }private Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
785 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
786 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, null);
787 if (response.isRight()) {
788 ResponseFormat errorResponse = response.right().value();
789 return Either.right(errorResponse);
792 String creatorUserIdUpdated = serviceUpdate.getCreatorUserId();
793 String creatorUserIdCurrent = currentService.getCreatorUserId();
794 if (creatorUserIdUpdated != null && !creatorUserIdCurrent.equals(creatorUserIdUpdated)) {
795 log.info("update srvice: recived request to update creatorUserId to {} the field is not updatable ignoring.", creatorUserIdUpdated);
798 String creatorFullNameUpdated = serviceUpdate.getCreatorFullName();
799 String creatorFullNameCurrent = currentService.getCreatorFullName();
800 if (creatorFullNameUpdated != null && !creatorFullNameCurrent.equals(creatorFullNameUpdated)) {
801 log.info("update srvice: recived request to update creatorFullName to {} the field is not updatable ignoring.", creatorFullNameUpdated);
804 String lastUpdaterUserIdUpdated = serviceUpdate.getLastUpdaterUserId();
805 String lastUpdaterUserIdCurrent = currentService.getLastUpdaterUserId();
806 if (lastUpdaterUserIdUpdated != null && !lastUpdaterUserIdCurrent.equals(lastUpdaterUserIdUpdated)) {
807 log.info("update srvice: recived request to update lastUpdaterUserId to {} the field is not updatable ignoring.", lastUpdaterUserIdUpdated);
810 String lastUpdaterFullNameUpdated = serviceUpdate.getLastUpdaterFullName();
811 String lastUpdaterFullNameCurrent = currentService.getLastUpdaterFullName();
812 if (lastUpdaterFullNameUpdated != null && !lastUpdaterFullNameCurrent.equals(lastUpdaterFullNameUpdated)) {
813 log.info("update srvice: recived request to update lastUpdaterFullName to {} the field is not updatable ignoring.", lastUpdaterFullNameUpdated);
816 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
817 if (response.isRight()) {
818 ResponseFormat errorResponse = response.right().value();
819 return Either.right(errorResponse);
822 DistributionStatusEnum distributionStatusUpdated = serviceUpdate.getDistributionStatus();
823 DistributionStatusEnum distributionStatusCurrent = currentService.getDistributionStatus();
824 if (distributionStatusUpdated != null && !distributionStatusUpdated.name().equals(distributionStatusCurrent != null ? distributionStatusCurrent.name() : null)) {
825 log.info("update service: received request to update distributionStatus to {}. the field is read only, ignoring.", distributionStatusUpdated);
828 if (serviceUpdate.getProjectCode() != null) {
829 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, null);
830 if (response.isRight()) {
831 ResponseFormat errorResponse = response.right().value();
832 return Either.right(errorResponse);
836 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, null);
837 if (response.isRight()) {
838 ResponseFormat errorResponse = response.right().value();
839 return Either.right(errorResponse);
842 Long creationDateUpdated = serviceUpdate.getCreationDate();
843 Long creationDateCurrent = currentService.getCreationDate();
844 if (creationDateUpdated != null && !creationDateCurrent.equals(creationDateUpdated)) {
845 log.info("update srvice: recived request to update creationDate to {} the field is not updatable ignoring.", creationDateUpdated);
848 String versionUpdated = serviceUpdate.getVersion();
849 String versionCurrent = currentService.getVersion();
850 if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) {
851 log.info("update srvice: recived request to update version to {} the field is not updatable ignoring.", versionUpdated);
854 response = validateAndUpdateDescription(user, currentService, serviceUpdate, hasBeenCertified, null);
855 if (response.isRight()) {
856 ResponseFormat errorResponse = response.right().value();
857 return Either.right(errorResponse);
860 response = validateAndUpdateTags(user, currentService, serviceUpdate, hasBeenCertified, null);
861 if (response.isRight()) {
862 ResponseFormat errorResponse = response.right().value();
863 return Either.right(errorResponse);
866 response = validateAndUpdateContactId(user, currentService, serviceUpdate, null);
867 if (response.isRight()) {
868 ResponseFormat errorResponse = response.right().value();
869 return Either.right(errorResponse);
872 Long lastUpdateDateUpdated = serviceUpdate.getLastUpdateDate();
873 Long lastUpdateDateCurrent = currentService.getLastUpdateDate();
874 if (lastUpdateDateUpdated != null && !lastUpdateDateCurrent.equals(lastUpdateDateUpdated)) {
875 log.info("update srvice: recived request to update lastUpdateDate to {} the field is not updatable ignoring.", lastUpdateDateUpdated);
878 LifecycleStateEnum lifecycleStateUpdated = serviceUpdate.getLifecycleState();
879 LifecycleStateEnum lifecycleStateCurrent = currentService.getLifecycleState();
880 if (lifecycleStateUpdated != null && !lifecycleStateCurrent.name().equals(lifecycleStateUpdated.name())) {
881 log.info("update srvice: recived request to update lifecycleState to {} the field is not updatable ignoring.", lifecycleStateUpdated);
884 Boolean isHighestVersionUpdated = serviceUpdate.isHighestVersion();
885 Boolean isHighestVersionCurrent = currentService.isHighestVersion();
886 if (isHighestVersionUpdated != null && !isHighestVersionCurrent.equals(isHighestVersionUpdated)) {
887 log.info("update srvice: recived request to update isHighestVersion to {} the field is not updatable ignoring.", isHighestVersionUpdated);
890 String uuidUpdated = serviceUpdate.getUUID();
891 String uuidCurrent = currentService.getUUID();
892 if (!uuidCurrent.equals(uuidUpdated)) {
893 log.info("update service: recived request to update uuid to {} the field is not updatable ignoring.", uuidUpdated);
896 response = validateAndUpdateServiceType(user, currentService, serviceUpdate, null);
897 if (response.isRight()) {
898 ResponseFormat errorResponse = response.right().value();
899 return Either.right(errorResponse);
902 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, null);
903 if (response.isRight()) {
904 ResponseFormat errorResponse = response.right().value();
905 return Either.right(errorResponse);
908 String currentInvariantUuid = currentService.getInvariantUUID();
909 String updatedInvariantUuid = serviceUpdate.getInvariantUUID();
911 if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) {
912 log.warn("Product invariant UUID is automatically set and cannot be updated");
913 serviceUpdate.setInvariantUUID(currentInvariantUuid);
915 validateAndUpdateEcompNaming(currentService, serviceUpdate);
917 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
919 return Either.left(currentService);
923 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
924 Boolean isEcompoGeneratedCurr = currentService.isEcompGeneratedNaming();
925 Boolean isEcompoGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
926 if (isEcompoGeneratedUpdate != null && isEcompoGeneratedCurr.equals(isEcompoGeneratedUpdate)) {
927 currentService.setEcompGeneratedNaming(isEcompoGeneratedUpdate);
929 String namingPolicyUpd = serviceUpdate.getNamingPolicy();
930 if (!currentService.isEcompGeneratedNaming()) {
931 if (ValidationUtils.validateStringNotEmpty(namingPolicyUpd)) {
932 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
933 currentService.setNamingPolicy("");
935 currentService.setNamingPolicy(namingPolicyUpd);
938 currentService.setNamingPolicy(namingPolicyUpd);
942 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
943 String contactIdUpdated = serviceUpdate.getContactId();
944 String contactIdCurrent = currentService.getContactId();
945 if (!contactIdCurrent.equals(contactIdUpdated)) {
946 Either<Boolean, ResponseFormat> validatContactId = validateContactId(user, serviceUpdate, audatingAction);
947 if (validatContactId.isRight()) {
948 ResponseFormat errorRespons = validatContactId.right().value();
949 return Either.right(errorRespons);
951 currentService.setContactId(contactIdUpdated.toLowerCase());
953 return Either.left(true);
956 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
957 List<String> tagsUpdated = serviceUpdate.getTags();
958 List<String> tagsCurrent = currentService.getTags();
959 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
960 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
961 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
962 return Either.right(responseFormat);
965 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
966 Either<Boolean, ResponseFormat> validatResponse = validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
967 if (validatResponse.isRight()) {
968 ResponseFormat errorRespons = validatResponse.right().value();
969 return Either.right(errorRespons);
971 currentService.setTags(tagsUpdated);
973 return Either.left(true);
976 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
977 String descriptionUpdated = serviceUpdate.getDescription();
978 String descriptionCurrent = currentService.getDescription();
979 if (!descriptionCurrent.equals(descriptionUpdated)) {
980 Either<Boolean, ResponseFormat> validateDescriptionResponse = validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
981 if (validateDescriptionResponse.isRight()) {
982 ResponseFormat errorRespons = validateDescriptionResponse.right().value();
983 return Either.right(errorRespons);
985 currentService.setDescription(serviceUpdate.getDescription());
987 return Either.left(true);
990 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
991 String projectCodeUpdated = serviceUpdate.getProjectCode();
992 String projectCodeCurrent = currentService.getProjectCode();
993 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
995 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
996 if (validatProjectCodeResponse.isRight()) {
997 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
998 return Either.right(errorRespons);
1000 currentService.setProjectCode(projectCodeUpdated);
1003 return Either.left(true);
1006 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1007 String iconUpdated = serviceUpdate.getIcon();
1008 String iconCurrent = currentService.getIcon();
1009 if (!iconCurrent.equals(iconUpdated)) {
1010 if (!hasBeenCertified) {
1011 Either<Boolean, ResponseFormat> validatIconResponse = validateIcon(user, serviceUpdate, audatingAction);
1012 if (validatIconResponse.isRight()) {
1013 ResponseFormat errorRespons = validatIconResponse.right().value();
1014 return Either.right(errorRespons);
1016 currentService.setIcon(iconUpdated);
1018 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1019 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1020 return Either.right(errorResponse);
1023 return Either.left(true);
1026 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1027 String serviceNameUpdated = serviceUpdate.getName();
1028 String serviceNameCurrent = currentService.getName();
1029 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1030 if (!hasBeenCertified) {
1031 Either<Boolean, ResponseFormat> validatServiceNameResponse = validateComponentName(user, serviceUpdate, auditingAction);
1032 if (validatServiceNameResponse.isRight()) {
1033 ResponseFormat errorRespons = validatServiceNameResponse.right().value();
1034 return Either.right(errorRespons);
1037 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
1038 if (serviceNameUniquenessValidation.isRight()) {
1039 return serviceNameUniquenessValidation;
1041 currentService.setName(serviceNameUpdated);
1042 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1043 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1046 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1047 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1048 return Either.right(errorResponse);
1051 return Either.left(true);
1054 private Either<Boolean, ResponseFormat> validateAndUpdateServiceType(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1055 String updatedServiceType = updatedService.getServiceType();
1056 String currentServiceType = currentService.getServiceType();
1057 if (!currentServiceType.equals(updatedServiceType)) {
1058 Either<Boolean, ResponseFormat> validateServiceType = validateServiceTypeAndCleanup(user, updatedService , auditingAction);
1059 if (validateServiceType.isRight()) {
1060 ResponseFormat errorResponse = validateServiceType.right().value();
1061 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1062 return Either.right(errorResponse);
1064 currentService.setServiceType(updatedServiceType);
1066 return Either.left(true);
1069 protected Either<Boolean, ResponseFormat> validateServiceTypeAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1070 String serviceType = ((Service)component).getServiceType();
1071 if (serviceType != null){
1072 serviceType = cleanUpText(serviceType);
1073 Either<Boolean, ResponseFormat> validateServiceType = validateServiceType(serviceType);
1074 if (validateServiceType.isRight()) {
1075 ResponseFormat responseFormat = validateServiceType.right().value();
1076 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1077 return Either.right(responseFormat);
1079 return Either.left(true);
1081 return Either.left(false);
1086 private Either<Boolean, ResponseFormat> validateServiceType(String serviceType) {
1087 if (serviceType.equals("")){
1088 return Either.left(true);
1090 if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
1091 log.info("service type exceeds limit.");
1092 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
1093 return Either.right(errorResponse);
1096 if (!ValidationUtils.validateIsEnglish(serviceType)) {
1097 log.info("service type is not valid.");
1098 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_TYPE);
1099 return Either.right(errorResponse);
1101 return Either.left(true);
1105 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1106 String updatedServiceRole = updatedService.getServiceRole();
1107 String currentServiceRole = currentService.getServiceRole();
1108 if (!currentServiceRole.equals(updatedServiceRole)) {
1109 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
1110 if (validateServiceRole.isRight()) {
1111 ResponseFormat errorResponse = validateServiceRole.right().value();
1112 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1113 return Either.right(errorResponse);
1115 currentService.setServiceRole(updatedServiceRole);
1117 return Either.left(true);
1120 protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1121 String serviceRole = ((Service)component).getServiceRole();
1122 if (serviceRole != null){
1123 serviceRole = cleanUpText(serviceRole);
1125 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
1126 if (validateServiceRole.isRight()) {
1127 ResponseFormat responseFormat = validateServiceRole.right().value();
1128 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1129 return Either.right(responseFormat);
1131 return Either.left(true);
1133 return Either.left(false);
1138 private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1139 if (serviceRole.equals("")){
1140 return Either.left(true);
1142 if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1143 log.info("service role exceeds limit.");
1144 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1145 return Either.right(errorResponse);
1148 if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1149 log.info("service role is not valid.");
1150 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1151 return Either.right(errorResponse);
1153 return Either.left(true);
1159 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1160 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1161 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1162 Either<Boolean, ResponseFormat> validatCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1163 if (validatCategoryResponse.isRight()) {
1164 ResponseFormat errorRespons = validatCategoryResponse.right().value();
1165 return Either.right(errorRespons);
1167 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1168 if (!hasBeenCertified) {
1169 currentService.setCategories(categoryUpdated);
1171 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1172 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1173 return Either.right(errorResponse);
1176 return Either.left(true);
1180 public Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1182 if (list.size() > 1) {
1183 log.debug("Must be only one category for service");
1184 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1185 return Either.right(responseFormat);
1187 CategoryDefinition category = list.get(0);
1188 if (category.getSubcategories() != null) {
1189 log.debug("Subcategories cannot be defined for service");
1190 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1191 return Either.right(responseFormat);
1193 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1194 log.debug("Resource category is empty");
1195 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1196 return Either.right(responseFormat);
1199 log.debug("validating service category {} against valid categories list", list);
1200 Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1201 if (categorys.isRight()) {
1202 log.debug("failed to retrive service categories from Titan");
1203 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1204 return Either.right(responseFormat);
1206 List<CategoryDefinition> categoryList = categorys.left().value();
1207 for (CategoryDefinition value : categoryList) {
1208 if (value.getName().equals(category.getName())) {
1209 return Either.left(true);
1212 log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1213 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1215 return Either.left(false);
1218 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1219 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1220 if (serviceResponseFormatEither.isRight()){
1221 return Either.right(serviceResponseFormatEither.right().value());
1223 final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1224 return Either.left(serviceRelations);
1227 }public ResponseFormat deleteService(String serviceId, User user) {
1228 ResponseFormat responseFormat;
1229 String ecompErrorContext = "delete service";
1231 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1232 if (eitherCreator.isRight()) {
1233 return eitherCreator.right().value();
1235 user = eitherCreator.left().value();
1237 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1238 if (serviceStatus.isRight()) {
1239 log.debug("failed to get service {}", serviceId);
1240 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1243 Service service = serviceStatus.left().value();
1245 StorageOperationStatus result = StorageOperationStatus.OK;
1246 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1247 if (lockResult.isRight()) {
1248 result = StorageOperationStatus.GENERAL_ERROR;
1249 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1254 result = markComponentToDelete(service);
1255 if (result.equals(StorageOperationStatus.OK)) {
1256 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1258 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1259 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1261 return responseFormat;
1264 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1265 log.warn("operation failed. do rollback");
1266 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1267 titanDao.rollback();
1269 log.debug("operation success. do commit");
1272 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1276 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1277 ResponseFormat responseFormat;
1278 String ecompErrorContext = "delete service";
1279 Either<User, ResponseFormat> validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext);
1280 if (validateEmptyResult.isRight()) {
1281 return validateEmptyResult.right().value();
1284 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1285 if (eitherCreator.isRight()) {
1286 return eitherCreator.right().value();
1288 user = eitherCreator.left().value();
1290 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1291 if (getResult.isRight()) {
1292 return getResult.right().value();
1294 Service service = getResult.left().value();
1296 StorageOperationStatus result = StorageOperationStatus.OK;
1297 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1298 if (lockResult.isRight()) {
1299 result = StorageOperationStatus.GENERAL_ERROR;
1300 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1304 result = markComponentToDelete(service);
1305 if (result.equals(StorageOperationStatus.OK)) {
1306 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1308 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1309 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1311 return responseFormat;
1314 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1315 log.warn("operation failed. do rollback");
1316 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1317 titanDao.rollback();
1319 log.debug("operation success. do commit");
1322 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1326 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1327 String ecompErrorContext = "Get service";
1328 Either<User, ResponseFormat> validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext);
1329 if (validateEmptyResult.isRight()) {
1330 return Either.right(validateEmptyResult.right().value());
1333 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1334 if (eitherCreator.isRight()) {
1335 return Either.right(eitherCreator.right().value());
1338 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1339 if (storageStatus.isRight()) {
1340 log.debug("failed to get service by id {}", serviceId);
1341 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1344 if(!(storageStatus.left().value() instanceof Service)){
1345 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1347 Service service = storageStatus.left().value();
1348 return Either.left(service);
1355 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1356 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Service By Name And Version", false);
1357 if (resp.isRight()) {
1358 return Either.right(resp.right().value());
1360 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1361 if (storageStatus.isRight()) {
1362 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1363 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1365 Service service = storageStatus.left().value();
1366 return Either.left(service);
1369 @SuppressWarnings("unchecked")
1370 private void createMandatoryArtifactsData(Service service, User user) {
1371 // create mandatory artifacts
1373 // TODO it must be removed after that artifact uniqueId creation will be
1374 // moved to ArtifactOperation
1375 String serviceUniqueId = service.getUniqueId();
1376 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1377 if (artifactMap == null)
1378 artifactMap = new HashMap<String, ArtifactDefinition>();
1380 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1381 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1383 String category = service.getCategories().get(0).getName();
1384 boolean isCreateArtifact = true;
1385 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1386 for (String exlude : exludeServiceCategory) {
1387 if (exlude.equalsIgnoreCase(category)) {
1388 isCreateArtifact = false;
1395 if (informationalServiceArtifacts != null && isCreateArtifact) {
1396 Set<String> keys = informationalServiceArtifacts.keySet();
1397 for (String informationalServiceArtifactName : keys) {
1398 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1399 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1400 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1404 service.setArtifacts(artifactMap);
1408 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1410 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1413 artifactInfo.setMandatory(false);
1414 artifactInfo.setServiceApi(true);
1416 return artifactInfo;
1419 private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition, User user) {
1420 DistributionTransitionEnum transitionEnum = null;
1422 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1423 if (transitionEnum == null) {
1424 BeEcompErrorManager.getInstance().logBeSystemError("Change Service Distribution");
1425 log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1426 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1427 return Either.right(error);
1430 return Either.left(transitionEnum);
1433 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment, User user, AuditingActionEnum auditAction) {
1434 String data = comment.getUserRemarks();
1436 if (data == null || data.trim().isEmpty()) {
1437 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution");
1438 log.debug("user comment cannot be empty or null.");
1439 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1441 data = ValidationUtils.removeNoneUtf8Chars(data);
1442 data = ValidationUtils.removeHtmlTags(data);
1443 data = ValidationUtils.normaliseWhitespace(data);
1444 data = ValidationUtils.stripOctets(data);
1446 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1447 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution");
1448 log.debug("user comment exceeds limit.");
1449 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1451 if (!ValidationUtils.validateIsEnglish(data)) {
1452 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1454 return Either.left(data);
1457 private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1458 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1459 if (storageStatus.isRight()) {
1460 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1461 log.debug("audit before sending response");
1462 componentsUtils.auditComponent(responseFormat, user, auditAction, serviceId, ComponentTypeEnum.SERVICE, comment);
1463 return Either.right(responseFormat);
1465 Service service = storageStatus.left().value();
1467 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1468 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1469 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1470 createAudit(user, auditAction, comment, service, responseFormat);
1471 return Either.right(responseFormat);
1473 return Either.left(service);
1476 private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1477 log.debug("get user from DB");
1480 Either<User, ResponseFormat> eitherCreator = validateUser(user, "Activate Distribution", service, auditAction, false);
1481 if (eitherCreator.isRight()) {
1482 return Either.right(eitherCreator.right().value());
1484 user = eitherCreator.left().value();
1486 // validate user role
1487 List<Role> roles = new ArrayList<>();
1488 roles.add(Role.ADMIN);
1489 roles.add(Role.GOVERNOR);
1490 roles.add(Role.OPS);
1491 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, roles, auditAction, comment);
1492 if (validateRes.isRight()) {
1493 return Either.right(validateRes.right().value());
1495 return Either.left(user);
1498 private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1499 log.debug("audit before sending response");
1500 componentsUtils.auditComponent(responseFormat, user, component, auditAction, ComponentTypeEnum.SERVICE,
1501 ResourceAuditData.newBuilder().state(component.getLifecycleState().name()).version(component.getVersion()).build(), comment);
1504 private String getEnvNameFromConfiguration() {
1505 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1506 log.trace("Update environment name to be {}", configuredEnvName);
1507 return configuredEnvName;
1510 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1512 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1513 if (activationRequestInformationEither.isRight()) {
1514 return Either.right(activationRequestInformationEither.right().value());
1517 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1519 Either<String, ResponseFormat> result = null;
1520 ResponseFormat response = null;
1521 String did = ThreadLocalsHolder.getUuid();
1522 Service service = activationRequestInformation.getServiceToActivate();
1524 StorageOperationStatus readyForDistribution = distributionEngine.verifyServiceHasDeploymentArtifacts(service);
1525 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1526 result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1528 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), service.getName(), envId);
1529 result = Either.right(response);
1534 public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1535 String envName = getEnvNameFromConfiguration();
1536 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1537 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier.getUserId(), modifier.getFullName());
1538 if (notifyServiceResponse == ActionStatus.OK) {
1539 return Either.left(did);
1541 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1542 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1543 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1544 return Either.right(error);
1548 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1550 Either<User, ResponseFormat> eitherCreator = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1551 if (eitherCreator.isRight()) {
1552 return Either.right(eitherCreator.right().value());
1555 User user = eitherCreator.left().value();
1557 Either<Service, ResponseFormat> result = null;
1558 ResponseFormat response = null;
1559 Service updatedService = null;
1560 String did = ThreadLocalsHolder.getUuid();
1562 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1563 if (configuredEnvName != null && false == envName.equals(configuredEnvName)) {
1564 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1565 envName = configuredEnvName;
1569 ServletContext servletContext = request.getSession().getServletContext();
1570 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1571 if (!isDistributionEngineUp) {
1572 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1573 log.debug("Distribution Engine is DOWN");
1574 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1575 return Either.right(response);
1578 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1579 if (serviceRes.isRight()) {
1580 log.debug("failed retrieving service");
1581 response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1582 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE,
1583 ResourceAuditData.newBuilder().build(), did);
1584 return Either.right(response);
1586 Service service = serviceRes.left().value();
1587 String dcurrStatus = service.getDistributionStatus().name();
1588 String updatedStatus = dcurrStatus;
1589 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(service, envName);
1590 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1591 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1592 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user.getUserId(), user.getFullName());
1593 if (notifyServiceResponse == ActionStatus.OK) {
1594 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1595 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1596 updatedService = updateStateRes.left().value();
1597 updatedStatus = updatedService.getDistributionStatus().name();
1599 // The response is not relevant
1600 updatedService = service;
1602 ASDCKpiApi.countActivatedDistribution();
1603 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1604 result = Either.left(updatedService);
1606 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1607 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1608 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1609 result = Either.right(response);
1612 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), service.getName(), envName);
1613 result = Either.right(response);
1615 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE,
1616 ResourceAuditData.newBuilder().distributionStatus(dcurrStatus).build(),
1617 ResourceAuditData.newBuilder().distributionStatus(updatedStatus).build(), service.getName(),
1622 // convert to private after deletion of temp url
1623 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1625 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1626 if (resp.isRight()) {
1627 return Either.right(resp.right().value());
1630 String serviceId = service.getUniqueId();
1631 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1632 if (lockResult.isRight()) {
1633 return Either.right(lockResult.right().value());
1636 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1637 if (result.isRight()) {
1638 titanDao.rollback();
1639 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1640 log.debug("service {} change distribution status failed", serviceId);
1641 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1644 return Either.left(result.left().value());
1646 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1650 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1652 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
1653 if (resp.isRight()) {
1654 return Either.right(resp.right().value());
1657 log.debug("mark distribution deployed");
1659 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1660 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1661 if (getServiceResponse.isRight()) {
1662 BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1663 log.debug("service {} not found", serviceId);
1664 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1666 return Either.right(responseFormat);
1669 Service service = getServiceResponse.left().value();
1671 Either<User, ResponseFormat> validateRoleForDeploy = validateRoleForDeploy(did, user, auditAction, service);
1672 if (validateRoleForDeploy.isRight()) {
1673 return Either.right(validateRoleForDeploy.right().value());
1675 user = validateRoleForDeploy.left().value();
1677 return checkDistributionAndDeploy(did, user, auditAction, service);
1681 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1682 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1683 // Only one VF Module Artifact per instance - add it to a list of one
1684 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1686 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1690 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
1691 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<ArtifactGenerator<ArtifactDefinition>>();
1693 if (ri.getOriginType() == OriginTypeEnum.VF) {
1694 asList = Arrays.asList(new VfModuleArtifacGenerator(modifier, ri, service, shouldLock, inTransaction));
1699 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF, Wrapper<ResponseFormat> responseWrapper) {
1700 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1701 if(currVF.getGroupInstances() != null){
1702 currVF.getGroupInstances().stream().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1704 return currVF.getGroupInstances();
1707 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, User modifier, List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
1708 ArtifactDefinition vfModuleAertifact = null;
1709 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1710 Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
1711 if (optionalVfModuleArtifact.isPresent()) {
1712 vfModuleAertifact = optionalVfModuleArtifact.get();
1715 if (vfModuleAertifact == null) {
1716 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(modifier, currVF, service, payloadWrapper.getInnerElement());
1717 if (createVfModuleArtifact.isLeft()) {
1718 vfModuleAertifact = createVfModuleArtifact.left().value();
1720 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1723 return vfModuleAertifact;
1726 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1727 // Converts GroupDefinition to VfModuleArtifactPayload which is the
1728 // format used in the payload
1730 List<VfModuleArtifactPayload> vfModulePayloadForCurrVF = new ArrayList<VfModuleArtifactPayload>();
1731 if (groupsForCurrVF != null) {
1732 for (GroupInstance groupInstance : groupsForCurrVF) {
1733 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1734 vfModulePayloadForCurrVF.add(modulePayload);
1736 Collections.sort(vfModulePayloadForCurrVF, (art1, art2) -> VfModuleArtifactPayload.compareByGroupName(art1, art2));
1738 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1740 String vfModulePayloadString = gson.toJson(vfModulePayloadForCurrVF);
1741 payloadWrapper.setInnerElement(vfModulePayloadString);
1746 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
1747 ArtifactDefinition vfModuleAertifact = null;
1748 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1749 Wrapper<String> payloadWrapper = new Wrapper<>();
1750 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance, responseWrapper);
1751 if (responseWrapper.isEmpty()) {
1752 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1754 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1755 vfModuleAertifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, modifier, groupsForCurrVF, payloadWrapper, responseWrapper);
1757 if (responseWrapper.isEmpty() && vfModuleAertifact != null) {
1758 vfModuleAertifact = fillVfModulePayload(modifier, currVFInstance, vfModuleAertifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
1761 Either<ArtifactDefinition, ResponseFormat> result;
1762 if (responseWrapper.isEmpty()) {
1763 result = Either.left(vfModuleAertifact);
1765 result = Either.right(responseWrapper.getInnerElement());
1771 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
1772 ArtifactDefinition result = null;
1773 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, () -> System.currentTimeMillis(),
1774 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
1775 if (eitherPayload.isLeft()) {
1776 result = eitherPayload.left().value();
1778 responseWrapper.setInnerElement(eitherPayload.right().value());
1780 if (result == null) {
1781 result = vfModuleArtifact;
1787 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(User modifier, ComponentInstance currVF, Service service, String vfModulePayloadString) {
1789 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
1790 String newCheckSum = null;
1792 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
1793 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
1794 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
1795 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
1796 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
1797 vfModuleArtifactDefinition.setTimeout(0);
1798 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
1799 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
1800 if (vfModulePayloadString != null) {
1801 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
1803 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
1805 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
1807 Either<ArtifactDefinition, ResponseFormat> result;
1808 if (addArifactToComponent.isLeft()) {
1809 result = Either.left(addArifactToComponent.left().value());
1811 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
1817 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1819 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1820 // Get All Deployment Artifacts
1821 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1822 // Filter in Only Heat Env
1823 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1824 // Create ArtifactGenerator from those Artifacts
1825 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
1827 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1831 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1833 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1835 if (service.getComponentInstances() != null) {
1836 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1837 if (artifactGenList != null && !artifactGenList.isEmpty()) {
1838 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1839 Either<CallVal, ResponseFormat> callRes;
1841 callRes = entry.call();
1842 if (callRes.isRight()) {
1843 log.debug("Failed to generate artifact error : {}", callRes.right().value());
1844 return Either.right(callRes.right().value());
1846 } catch (Exception e) {
1847 log.debug("Failed to generate artifact exception : {}", e);
1848 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1853 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1854 if (storageStatus.isRight()) {
1855 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1858 Service currentService = storageStatus.left().value();
1860 return Either.left(currentService);
1864 abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
1868 class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
1869 ArtifactDefinition artifactDefinition;
1871 String resourceInstanceName;
1875 boolean inTransaction;
1877 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
1878 this.artifactDefinition = artifactDefinition;
1879 this.service = service;
1880 this.resourceInstanceName = resourceInstanceName;
1881 this.modifier = modifier;
1882 this.shouldLock = shouldLock;
1883 this.instanceId = instanceId;
1884 this.inTransaction = inTransaction;
1888 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1889 return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
1892 public ArtifactDefinition getArtifactDefinition() {
1893 return artifactDefinition;
1898 class VfModuleArtifacGenerator extends ArtifactGenerator<ArtifactDefinition> {
1900 private ComponentInstance componentInstance;
1901 private Service service;
1903 boolean inTransaction;
1906 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1907 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
1910 private VfModuleArtifacGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
1913 this.componentInstance = componentInstance;
1914 this.service = service;
1915 this.shouldLock = shouldLock;
1916 this.inTransaction = inTransaction;
1921 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
1922 boolean isDeployed = isDistributionDeployed(did, service);
1924 return Either.left(service);
1926 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(did, user, auditAction, service);
1927 if (distributionSuccess.isRight()) {
1928 return Either.right(distributionSuccess.right().value());
1931 log.debug("mark distribution {} as deployed - success", did);
1932 componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, STATUS_DEPLOYED, "OK", user);
1933 return Either.left(service);
1936 private boolean isDistributionDeployed(String did, Service service) {
1937 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(did, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1939 boolean isDeployed = false;
1940 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1942 log.debug("distribution {} is already deployed", did);
1948 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1950 log.trace("checkDistributionSuccess");
1951 // get all "DRequest" records for this distribution
1953 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1954 if (distRequestsResponse.isRight()) {
1955 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1956 return Either.right(error);
1959 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1960 if (distributionRequests.isEmpty()) {
1961 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1962 log.info("distribution {} is not found", did);
1963 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1964 return Either.right(error);
1966 boolean isRequestSucceeded = false;
1967 for (ResourceAdminEvent event : distributionRequests) {
1968 String eventStatus = event.getStatus();
1969 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1970 isRequestSucceeded = true;
1975 // get all "DNotify" records for this distribution
1976 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1977 if (distNotificationsResponse.isRight()) {
1978 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1979 return Either.right(error);
1982 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1983 boolean isNotificationsSucceeded = false;
1984 for (DistributionNotificationEvent event : distributionNotifications) {
1985 String eventStatus = event.getStatus();
1986 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1987 isNotificationsSucceeded = true;
1992 // if request failed OR there are notifications that failed
1993 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1995 log.info("distribution {} has failed", did);
1996 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1997 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1998 return Either.right(error);
2000 return Either.left(true);
2003 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2005 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2006 String message = "";
2007 if (error.getMessageId() != null) {
2008 message = error.getMessageId() + ": ";
2010 message += error.getFormattedMessage();
2012 if (service != null) {
2013 componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2015 componentsUtils.auditServiceDistributionDeployed(auditAction, "", "", "", did, error.getStatus().toString(), message, user);
2020 private Either<User, ResponseFormat> validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2021 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
2022 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
2023 BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
2024 log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
2025 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
2026 auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
2027 return Either.right(responseFormat);
2029 user = eitherCreator.left().value();
2030 log.debug("validate user role");
2031 List<Role> roles = new ArrayList<>();
2032 roles.add(Role.ADMIN);
2033 roles.add(Role.OPS);
2034 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, roles, auditAction, null);
2035 if (validateRes.isRight()) {
2036 log.info("role {} is not allowed to perform this action", user.getRole());
2037 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2038 auditDeployError(did, user, auditAction, service, ActionStatus.RESTRICTED_OPERATION);
2039 return Either.right(responseFormat);
2041 return Either.left(user);
2046 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2051 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2052 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2055 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2056 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2057 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2058 HealthCheckBusinessLogic healthCheckBl = webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2059 return healthCheckBl;
2063 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2064 return componentInstanceBusinessLogic;
2068 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText) {
2070 Either<User, ResponseFormat> resp = validateUserExists(userId, "Get Component Instances", false);
2071 if (resp.isRight()) {
2072 return Either.right(resp.right().value());
2074 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2075 if (getComponentRes.isRight()) {
2076 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2077 return Either.right(responseFormat);
2080 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2082 return Either.left(componentInstances);
2085 public ICacheMangerOperation getCacheManagerOperation() {
2086 return cacheManagerOperation;
2089 public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
2090 this.cacheManagerOperation = cacheManagerOperation;
2093 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2094 this.forwardingPathOperation = forwardingPathOperation;
2098 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
2099 this.toscaOperationFacade = toscaOperationFacade;
2101 * 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
2105 * @param componentInstanceId
2106 * @param groupInstanceId
2107 * @param newProperties
2110 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2112 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2113 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2114 Component component = null;
2115 Either<Boolean, ResponseFormat> lockResult = null;
2116 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2118 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2119 if (validateUserAndComponentRes.isRight()) {
2120 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2121 actionResult = Either.right(validateUserAndComponentRes.right().value());
2123 if (actionResult == null) {
2124 component = validateUserAndComponentRes.left().value().getKey();
2125 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2126 if (lockResult.isRight()) {
2127 log.debug("Failed to lock service {}. Response is {}. ", component.getName(), lockResult.right().value().getFormattedMessage());
2128 actionResult = Either.right(lockResult.right().value());
2130 log.debug("The service with system name {} locked. ", component.getSystemName());
2133 if (actionResult == null) {
2134 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2135 if (actionResult.isRight()) {
2136 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2139 } catch (Exception e) {
2140 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2141 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2143 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2144 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2147 return actionResult;
2150 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2152 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2153 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2154 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2155 ComponentInstance relatedComponentInstance = null;
2156 GroupInstance oldGroupInstance = null;
2157 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2158 GroupInstance updatedGroupInstance = null;
2159 boolean inTransaction = true;
2160 boolean shouldCloseTransaction = true;
2161 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2162 if (findGroupInstanceRes.isRight()) {
2163 log.debug("Group instance {} not found. ", groupInstanceId);
2164 actionResult = Either.right(findGroupInstanceRes.right().value());
2166 if (actionResult == null) {
2167 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2168 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2169 updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties, inTransaction);
2170 if (updateGroupInstanceResult.isRight()) {
2171 log.debug("Failed to update group instance {} property values. ", oldGroupInstance.getName());
2172 actionResult = Either.right(updateGroupInstanceResult.right().value());
2175 if (actionResult == null) {
2176 updatedGroupInstance = updateGroupInstanceResult.left().value();
2177 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2178 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction, shouldCloseTransaction);
2179 if (updateParentsModificationTimeRes.isRight()) {
2180 log.debug("Failed to update modification time. ", oldGroupInstance.getName());
2181 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2185 if (actionResult == null) {
2186 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2188 return actionResult;
2191 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2192 boolean inTranscation, boolean shouldCloseTransaction) {
2194 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2195 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2196 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2197 updatedGroupInstance.getModificationTime(), inTranscation);
2198 if (updateComponentInstanceRes.isRight()) {
2199 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2200 actionResult = Either.right(updateComponentInstanceRes.right().value());
2202 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component, updatedGroupInstance.getModificationTime());
2203 if (serviceMetadataUpdateResult.isRight()) {
2204 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2205 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2207 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2210 return actionResult;
2213 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2215 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2216 Either<Component, ResponseFormat> validateComponentExistsRes = null;
2217 User currUser = null;
2218 Component component = null;
2219 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2220 if (validationUserResult.isRight()) {
2221 log.debug("Failed to validate user with userId for update service {}. ", modifier.getUserId(), serviceId);
2222 result = Either.right(validationUserResult.right().value());
2224 if (result == null) {
2225 currUser = validationUserResult.left().value();
2226 validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2227 if (validateComponentExistsRes.isRight()) {
2228 log.debug("Failed to validate service existing {}. ", serviceId);
2229 result = Either.right(validateComponentExistsRes.right().value());
2232 if (result == null) {
2233 component = validateComponentExistsRes.left().value();
2234 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2235 log.info("Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2236 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2239 if (result == null) {
2240 result = Either.left(new ImmutablePair<>(component, currUser));
2245 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2247 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2248 GroupInstance groupInstance = null;
2249 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2250 if (foundComponentInstance == null) {
2251 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2252 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2253 } else if (!CollectionUtils.isEmpty(foundComponentInstance.getGroupInstances())) {
2254 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2255 if (groupInstance == null) {
2256 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2257 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2260 if (actionResult == null) {
2261 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2263 return actionResult;
2266 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2267 ComponentInstance componentInstance = null;
2268 if (!CollectionUtils.isEmpty(component.getComponentInstances())) {
2269 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2271 return componentInstance;
2274 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2275 Either<User, ResponseFormat> result = validateUser(modifier, ecompErrorContext, null, null, false);
2276 if (result.isLeft()) {
2277 List<Role> roles = new ArrayList<>();
2278 roles.add(Role.ADMIN);
2279 roles.add(Role.DESIGNER);
2280 Either<Boolean, ResponseFormat> validationRoleRes = validateUserRole(result.left().value(), roles);
2281 if (validationRoleRes.isRight()) {
2282 result = Either.right(validationRoleRes.right().value());
2288 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2290 ComponentParametersView paramsToRetuen = new ComponentParametersView(dataParamsToReturn);
2291 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToRetuen);
2293 if (serviceResultEither.isRight()) {
2294 if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2295 log.debug("Failed to found service with id {} ", serviceId);
2296 Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2299 log.debug("failed to get service by id {} with filters {}", serviceId, dataParamsToReturn.toString());
2300 return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2303 Service service = serviceResultEither.left().value();
2304 UiComponentDataTransfer dataTransfer = UiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2305 return Either.left(dataTransfer);