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 com.google.common.base.Strings;
24 import com.google.gson.Gson;
25 import com.google.gson.GsonBuilder;
26 import fj.data.Either;
27 import org.apache.commons.collections.CollectionUtils;
28 import org.apache.commons.collections.MapUtils;
29 import org.apache.commons.lang3.tuple.ImmutablePair;
30 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
31 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
32 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
33 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
34 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
35 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
36 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
37 import org.openecomp.sdc.be.config.BeEcompErrorManager;
38 import org.openecomp.sdc.be.config.ConfigurationManager;
39 import org.openecomp.sdc.be.dao.api.ActionStatus;
40 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
41 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
42 import org.openecomp.sdc.be.datamodel.ServiceRelations;
43 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
44 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
45 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
46 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
47 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
48 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
49 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
50 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
51 import org.openecomp.sdc.be.model.ArtifactDefinition;
52 import org.openecomp.sdc.be.model.Component;
53 import org.openecomp.sdc.be.model.ComponentInstance;
54 import org.openecomp.sdc.be.model.ComponentParametersView;
55 import org.openecomp.sdc.be.model.DistributionStatusEnum;
56 import org.openecomp.sdc.be.model.DistributionTransitionEnum;
57 import org.openecomp.sdc.be.model.GroupInstance;
58 import org.openecomp.sdc.be.model.GroupInstanceProperty;
59 import org.openecomp.sdc.be.model.LifecycleStateEnum;
60 import org.openecomp.sdc.be.model.Resource;
61 import org.openecomp.sdc.be.model.Service;
62 import org.openecomp.sdc.be.model.User;
63 import org.openecomp.sdc.be.model.category.CategoryDefinition;
64 import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
65 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
66 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
67 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
68 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
69 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
70 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
71 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
72 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
73 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
74 import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
75 import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent;
76 import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent;
77 import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent;
78 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceAuditData;
79 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
80 import org.openecomp.sdc.be.user.Role;
81 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
82 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
83 import org.openecomp.sdc.common.api.Constants;
84 import org.openecomp.sdc.common.datastructure.Wrapper;
85 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
86 import org.openecomp.sdc.common.util.GeneralUtility;
87 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
88 import org.openecomp.sdc.common.util.ValidationUtils;
89 import org.openecomp.sdc.exception.ResponseFormat;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
92 import org.springframework.beans.factory.annotation.Autowired;
93 import org.springframework.web.context.WebApplicationContext;
95 import javax.servlet.ServletContext;
96 import javax.servlet.http.HttpServletRequest;
97 import java.nio.charset.StandardCharsets;
98 import java.util.ArrayList;
99 import java.util.Arrays;
100 import java.util.Collection;
101 import java.util.Collections;
102 import java.util.HashMap;
103 import java.util.List;
104 import java.util.Map;
105 import java.util.Optional;
106 import java.util.Set;
107 import java.util.concurrent.Callable;
108 import java.util.function.Function;
109 import java.util.stream.Collectors;
111 @org.springframework.stereotype.Component("serviceBusinessLogic")
112 public class ServiceBusinessLogic extends ComponentBusinessLogic {
114 private static final String STATUS_SUCCESS_200 = "200";
116 private static final String STATUS_DEPLOYED = "DEPLOYED";
119 private IElementOperation elementDao;
122 private IDistributionEngine distributionEngine;
125 private AuditCassandraDao auditCassandraDao;
128 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
131 private GroupBusinessLogic groupBusinessLogic;
134 private ICacheMangerOperation cacheManagerOperation;
137 private ServiceDistributionValidation serviceDistributionValidation;
139 private static final Logger log = LoggerFactory.getLogger(ServiceBusinessLogic.class);
140 private static final String INITIAL_VERSION = "0.1";
142 private ForwardingPathOperation forwardingPathOperation;
145 private ForwardingPathValidator forwardingPathValidator;
147 public ServiceBusinessLogic() {
148 log.debug("ServiceBusinessLogic started");
151 public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
153 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "change Service Distribution State", false);
154 if (resp.isRight()) {
155 return Either.right(resp.right().value());
158 log.debug("check request state");
159 Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state, user);
160 if (validateEnum.isRight()) {
161 return Either.right(validateEnum.right().value());
163 DistributionTransitionEnum distributionTransition = validateEnum.left().value();
164 AuditingActionEnum auditAction = distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT;
165 Either<String, ResponseFormat> commentResponse = validateComment(commentObj, user, auditAction);
166 if (commentResponse.isRight()) {
167 return Either.right(commentResponse.right().value());
169 String comment = commentResponse.left().value();
171 Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
172 if (validateService.isRight()) {
173 return Either.right(validateService.right().value());
175 Service service = validateService.left().value();
176 Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
177 if (validateUser.isRight()) {
178 return Either.right(validateUser.right().value());
180 user = validateUser.left().value();
184 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
185 if (lockResult.isRight()) {
186 ResponseFormat responseFormat = lockResult.right().value();
187 createAudit(user, auditAction, comment, service, responseFormat);
188 return Either.right(responseFormat);
193 DistributionStatusEnum newState;
194 if (distributionTransition == DistributionTransitionEnum.APPROVE) {
195 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
197 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
199 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
200 if (result.isRight()) {
202 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
203 log.debug("service {} is change destribuation status failed", service.getUniqueId());
204 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
205 createAudit(user, auditAction, comment, service, responseFormat);
206 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
209 Service updatedService = result.left().value();
210 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
211 log.debug("audit before sending response");
212 componentsUtils.auditComponent(responseFormat, user, updatedService, auditAction, ComponentTypeEnum.SERVICE, ResourceAuditData.newBuilder().build(), comment);
213 return Either.left(result.left().value());
215 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
220 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
221 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Component Audit Records", false);
222 if (resp.isRight()) {
223 return Either.right(resp.right().value());
225 Either<List<Map<String, Object>>, ActionStatus> result;
229 if (componentVersion.endsWith(".0")) {
230 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
231 if (eitherAuditingForCertified.isLeft()) {
232 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
234 result = Either.right(eitherAuditingForCertified.right().value());
237 // Uncertified Version
239 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
241 } catch (Exception e) {
242 log.debug("get Audit Records failed with exception {}", e);
243 result = Either.right(ActionStatus.GENERAL_ERROR);
246 if (result.isRight()) {
247 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
249 return Either.left(result.left().value());
254 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
256 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
258 if (eitherprevVerAudit.isRight()) {
259 return Either.right(eitherprevVerAudit.right().value());
263 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
264 if (eitherCurrVerAudit.isRight()) {
265 return Either.right(eitherCurrVerAudit.right().value());
268 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
269 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
271 List<Map<String, Object>> duplicateElements = new ArrayList<Map<String, Object>>();
272 duplicateElements.addAll(prevVerAuditList);
273 duplicateElements.retainAll(currVerAuditList);
275 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<Map<String, Object>>();
276 joinedNonDuplicatedList.addAll(prevVerAuditList);
277 joinedNonDuplicatedList.removeAll(duplicateElements);
278 joinedNonDuplicatedList.addAll(currVerAuditList);
280 return Either.left(joinedNonDuplicatedList);
283 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
285 List<Map<String, Object>> prevVerAudit = new ArrayList<Map<String, Object>>();
286 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
287 auditEvent.fillFields();
288 prevVerAudit.add(auditEvent.getFields());
299 * - modifier data (userId)
300 * @return Either<Service, responseFormat>
302 public Either<Service, ResponseFormat> createService(Service service, User user) {
305 Either<User, ResponseFormat> eitherCreator = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
306 if (eitherCreator.isRight()) {
307 return Either.right(eitherCreator.right().value());
309 user = eitherCreator.left().value();
311 // validate user role
312 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, new ArrayList<Role>(), AuditingActionEnum.CREATE_RESOURCE, null);
313 if (validateRes.isRight()) {
314 return Either.right(validateRes.right().value());
316 service.setCreatorUserId(user.getUserId());
318 // warn on overridden fields
319 checkFieldsForOverideAttampt(service);
321 log.debug("enrich service with version and state");
322 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
323 service.setVersion(INITIAL_VERSION);
324 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
325 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
327 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
328 if (createServiceResponse.isRight()) {
329 return createServiceResponse;
331 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
334 private void checkFieldsForOverideAttampt(Service service) {
335 checkComponentFieldsForOverrideAttempt(service);
336 if (service.getDistributionStatus() != null) {
337 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
341 private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
342 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
344 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
345 if (lockResult.isRight()) {
346 ResponseFormat responseFormat = lockResult.right().value();
347 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
348 return Either.right(responseFormat);
351 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
355 createMandatoryArtifactsData(service, user);
356 createServiceApiArtifactsData(service, user);
357 setToscaArtifactsPlaceHolders(service, user);
358 Either<Resource, ResponseFormat> genericServiceEither = fetchAndSetDerivedFromGenericType(service);
359 if (genericServiceEither.isRight())
360 return Either.right(genericServiceEither.right().value());
362 generateAndAddInputsFromGenericTypeProperties(service, genericServiceEither.left().value());
364 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
366 // service created successfully!!!
367 if (dataModelResponse.isLeft()) {
368 log.debug("Service created successfully!!!");
369 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
370 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
371 ASDCKpiApi.countCreatedServicesKPI();
372 return Either.left(dataModelResponse.left().value());
375 ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
376 log.debug("audit before sending response");
377 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
378 return Either.right(responseFormat);
381 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
385 @SuppressWarnings("unchecked")
386 private void createServiceApiArtifactsData(Service service, User user) {
387 // create mandatory artifacts
389 // TODO it must be removed after that artifact uniqueId creation will be
390 // moved to ArtifactOperation
391 String serviceUniqueId = service.getUniqueId();
392 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
393 if (artifactMap == null)
394 artifactMap = new HashMap<String, ArtifactDefinition>();
396 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
397 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
399 List<CategoryDefinition> categories = service.getCategories();
400 boolean isCreateArtifact = true;
401 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
402 for (String exlude : exludeServiceCategory) {
403 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
404 isCreateArtifact = false;
411 if (serviceApiArtifacts != null && isCreateArtifact) {
412 Set<String> keys = serviceApiArtifacts.keySet();
413 for (String serviceApiArtifactName : keys) {
414 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
415 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
416 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
417 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
420 service.setServiceApiArtifacts(artifactMap);
424 private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
426 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
427 if (validationResponse.isRight()) {
428 return Either.right(validationResponse.right().value());
430 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
431 service.setContactId(service.getContactId().toLowerCase());
433 // Generate invariant UUID - must be here and not in operation since it
434 // should stay constant during clone
435 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
436 service.setInvariantUUID(invariantUUID);
438 return Either.left(service);
441 private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
442 Either<Boolean, ResponseFormat> componentsFieldsValidation = validateComponentFieldsBeforeCreate(user, service, actionEnum);
443 if (componentsFieldsValidation.isRight()) {
444 return componentsFieldsValidation;
447 log.debug("validate service name uniqueness");
448 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
449 if (serviceNameUniquenessValidation.isRight()) {
450 return serviceNameUniquenessValidation;
453 log.debug("validate category");
454 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
455 if (categoryValidation.isRight()) {
456 return categoryValidation;
459 // validate project name (ProjectCode) - mandatory in service
460 log.debug("validate projectName");
461 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
462 if (projectCodeValidation.isRight()) {
463 return projectCodeValidation;
466 log.debug("validate service type");
467 Either<Boolean, ResponseFormat> serviceTypeValidation = validateServiceTypeAndCleanup(user, service, actionEnum);
468 if (serviceTypeValidation.isRight()) {
469 return serviceTypeValidation;
472 log.debug("validate service role");
473 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
474 if (serviceRoleValidation.isRight()) {
475 return serviceRoleValidation;
478 return Either.left(true);
482 private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
483 log.debug("validate Service category");
485 if (service.getCategories() == null || service.getCategories().size() == 0) {
486 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
487 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
488 return Either.right(errorResponse);
491 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
492 if (validatCategory.isRight()) {
493 ResponseFormat responseFormat = validatCategory.right().value();
494 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
495 return Either.right(responseFormat);
498 return Either.left(true);
501 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
503 Either<User, ResponseFormat> resp = validateUserExists(userId, "validate Service Name Exists", false);
504 if (resp.isRight()) {
505 return Either.right(resp.right().value());
508 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
513 if (dataModelResponse.isLeft()) {
514 Map<String, Boolean> result = new HashMap<>();
515 result.put("isValid", dataModelResponse.left().value());
516 log.debug("validation was successfully performed.");
517 return Either.left(result);
520 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
522 return Either.right(responseFormat);
525 public void setElementDao(IElementOperation elementDao) {
526 this.elementDao = elementDao;
529 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
530 this.auditCassandraDao = auditingDao;
533 public ArtifactsBusinessLogic getArtifactBl() {
534 return artifactsBusinessLogic;
537 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
538 this.artifactsBusinessLogic = artifactBl;
541 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
542 Either<User, ResponseFormat> eitherCreator = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
543 if (eitherCreator.isRight()) {
544 return Either.right(eitherCreator.right().value());
546 user = eitherCreator.left().value();
548 // validate user role
549 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
550 if (validateRes.isRight()) {
551 return Either.right(validateRes.right().value());
554 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
555 if (storageStatus.isRight()) {
556 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
559 Service currentService = storageStatus.left().value();
561 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
562 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
563 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
566 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
567 if (validationRsponse.isRight()) {
568 log.info("service update metadata: validations field.");
569 return validationRsponse;
571 Service serviceToUpdate = validationRsponse.left().value();
574 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
575 if (lockResult.isRight()) {
576 return Either.right(lockResult.right().value());
579 Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
580 if (updateResponse.isRight()) {
582 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
583 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
584 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
587 return Either.left(updateResponse.left().value());
589 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
593 public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
594 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
595 Either<User, ResponseFormat> eitherCreator = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
596 if (eitherCreator.isRight()) {
597 return Either.right(eitherCreator.right().value());
599 user = eitherCreator.left().value();
601 // validate user role
602 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
603 if (validateRes.isRight()) {
604 return Either.right(validateRes.right().value());
606 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
607 if (storageStatus.isRight()) {
608 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
610 Service service = storageStatus.left().value();
611 Either<Set<String>, StorageOperationStatus> result = null;
613 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
614 if (lockResult.isRight()) {
616 return Either.right(componentsUtils.getResponseFormat(componentsUtils
617 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
621 result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
622 if (result.isRight()) {
623 log.debug("Failed to lock service {}. Response is {}. ", service.getName(), result.right().value());
625 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
628 log.debug("The service with system name {} locked. ", service.getSystemName());
630 } catch (Exception e){
631 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
633 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
635 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
637 return Either.left(result.left().value());
640 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
641 Service serviceToDelete = new Service();
642 serviceToDelete.setUniqueId(serviceId);
643 serviceToDelete.setForwardingPaths(new HashMap<>());
644 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
645 return serviceToDelete;
648 public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
649 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
652 public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
653 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
656 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path){
657 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
658 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
659 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
660 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
661 dataDefinition.setUniqueId(path.getUniqueId());
662 dataDefinition.setPathElements(path.getPathElements());
663 dataDefinition.setDescription(path.getDescription());
664 dataDefinition.setToscaResourceName(path.getToscaResourceName());
665 return dataDefinition;
668 private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
669 Either<Service, ResponseFormat> eitherCreator1 = validateUserAndRole(serviceUpdate, user, errorContext);
670 if (eitherCreator1 != null) return eitherCreator1;
672 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
674 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
675 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
676 entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
678 Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
679 serviceId, isUpdate);
680 if(booleanResponseFormatEither.isRight()){
681 return Either.right(booleanResponseFormatEither.right().value());
684 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
686 if(serviceStorageOperationStatusEither.isRight()){
687 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
688 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
689 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
691 Service storedService = serviceStorageOperationStatusEither.left().value();
693 Set<ForwardingPathDataDefinition> forwardingPathDataDefinitions = trimmedForwardingPaths.entrySet().stream().map(entry -> entry.getValue())
694 .collect(Collectors.toSet());
696 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
697 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
698 if (forwardingPathOrigin.isRight()) {
699 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
700 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
701 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
703 Component component = forwardingPathOrigin.left().value();
704 final String toscaResourceName;
705 if ( component.getComponentType() == ComponentTypeEnum.RESOURCE) {
706 toscaResourceName = ((Resource) component).getToscaResourceName();
708 toscaResourceName = "";
710 Either<Boolean, ResponseFormat> lockResult = null;
713 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
714 if (lockResult.isRight()) {
715 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
716 lockResult.right().value().getFormattedMessage());
717 return Either.right(lockResult.right().value());
719 log.debug("The service with system name {} locked. ", storedService.getSystemName());
722 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
724 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
727 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
729 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
731 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
733 if (result.isRight()) {
735 return Either.right(componentsUtils.getResponseFormat(
736 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
739 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
740 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
744 } catch (Exception e) {
746 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
748 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
752 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
753 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
756 Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
757 return Either.left(service);
760 private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
761 Service service = new Service();
762 service.setUniqueId(serviceId);
763 service.setForwardingPaths(forwardingPathDataDefinitionMap);
767 private Either<Service, ResponseFormat> validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
768 Either<User, ResponseFormat> eitherCreator = validateUser(user, errorContext, serviceUpdate, null, false);
769 if (eitherCreator.isRight()) {
770 return Either.right(eitherCreator.right().value());
772 user = eitherCreator.left().value();
774 // validate user role
775 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
776 if (validateRes.isRight()) {
777 return Either.right(validateRes.right().value());
780 }private Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
782 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
783 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, null);
784 if (response.isRight()) {
785 ResponseFormat errorResponse = response.right().value();
786 return Either.right(errorResponse);
789 String creatorUserIdUpdated = serviceUpdate.getCreatorUserId();
790 String creatorUserIdCurrent = currentService.getCreatorUserId();
791 if (creatorUserIdUpdated != null && !creatorUserIdCurrent.equals(creatorUserIdUpdated)) {
792 log.info("update srvice: recived request to update creatorUserId to {} the field is not updatable ignoring.", creatorUserIdUpdated);
795 String creatorFullNameUpdated = serviceUpdate.getCreatorFullName();
796 String creatorFullNameCurrent = currentService.getCreatorFullName();
797 if (creatorFullNameUpdated != null && !creatorFullNameCurrent.equals(creatorFullNameUpdated)) {
798 log.info("update srvice: recived request to update creatorFullName to {} the field is not updatable ignoring.", creatorFullNameUpdated);
801 String lastUpdaterUserIdUpdated = serviceUpdate.getLastUpdaterUserId();
802 String lastUpdaterUserIdCurrent = currentService.getLastUpdaterUserId();
803 if (lastUpdaterUserIdUpdated != null && !lastUpdaterUserIdCurrent.equals(lastUpdaterUserIdUpdated)) {
804 log.info("update srvice: recived request to update lastUpdaterUserId to {} the field is not updatable ignoring.", lastUpdaterUserIdUpdated);
807 String lastUpdaterFullNameUpdated = serviceUpdate.getLastUpdaterFullName();
808 String lastUpdaterFullNameCurrent = currentService.getLastUpdaterFullName();
809 if (lastUpdaterFullNameUpdated != null && !lastUpdaterFullNameCurrent.equals(lastUpdaterFullNameUpdated)) {
810 log.info("update srvice: recived request to update lastUpdaterFullName to {} the field is not updatable ignoring.", lastUpdaterFullNameUpdated);
813 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
814 if (response.isRight()) {
815 ResponseFormat errorResponse = response.right().value();
816 return Either.right(errorResponse);
819 DistributionStatusEnum distributionStatusUpdated = serviceUpdate.getDistributionStatus();
820 DistributionStatusEnum distributionStatusCurrent = currentService.getDistributionStatus();
821 if (distributionStatusUpdated != null && !distributionStatusUpdated.name().equals(distributionStatusCurrent != null ? distributionStatusCurrent.name() : null)) {
822 log.info("update service: received request to update distributionStatus to {}. the field is read only, ignoring.", distributionStatusUpdated);
825 if (serviceUpdate.getProjectCode() != null) {
826 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, null);
827 if (response.isRight()) {
828 ResponseFormat errorResponse = response.right().value();
829 return Either.right(errorResponse);
833 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, null);
834 if (response.isRight()) {
835 ResponseFormat errorResponse = response.right().value();
836 return Either.right(errorResponse);
839 Long creationDateUpdated = serviceUpdate.getCreationDate();
840 Long creationDateCurrent = currentService.getCreationDate();
841 if (creationDateUpdated != null && !creationDateCurrent.equals(creationDateUpdated)) {
842 log.info("update srvice: recived request to update creationDate to {} the field is not updatable ignoring.", creationDateUpdated);
845 String versionUpdated = serviceUpdate.getVersion();
846 String versionCurrent = currentService.getVersion();
847 if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) {
848 log.info("update srvice: recived request to update version to {} the field is not updatable ignoring.", versionUpdated);
851 response = validateAndUpdateDescription(user, currentService, serviceUpdate, hasBeenCertified, null);
852 if (response.isRight()) {
853 ResponseFormat errorResponse = response.right().value();
854 return Either.right(errorResponse);
857 response = validateAndUpdateTags(user, currentService, serviceUpdate, hasBeenCertified, null);
858 if (response.isRight()) {
859 ResponseFormat errorResponse = response.right().value();
860 return Either.right(errorResponse);
863 response = validateAndUpdateContactId(user, currentService, serviceUpdate, null);
864 if (response.isRight()) {
865 ResponseFormat errorResponse = response.right().value();
866 return Either.right(errorResponse);
869 Long lastUpdateDateUpdated = serviceUpdate.getLastUpdateDate();
870 Long lastUpdateDateCurrent = currentService.getLastUpdateDate();
871 if (lastUpdateDateUpdated != null && !lastUpdateDateCurrent.equals(lastUpdateDateUpdated)) {
872 log.info("update srvice: recived request to update lastUpdateDate to {} the field is not updatable ignoring.", lastUpdateDateUpdated);
875 LifecycleStateEnum lifecycleStateUpdated = serviceUpdate.getLifecycleState();
876 LifecycleStateEnum lifecycleStateCurrent = currentService.getLifecycleState();
877 if (lifecycleStateUpdated != null && !lifecycleStateCurrent.name().equals(lifecycleStateUpdated.name())) {
878 log.info("update srvice: recived request to update lifecycleState to {} the field is not updatable ignoring.", lifecycleStateUpdated);
881 Boolean isHighestVersionUpdated = serviceUpdate.isHighestVersion();
882 Boolean isHighestVersionCurrent = currentService.isHighestVersion();
883 if (isHighestVersionUpdated != null && !isHighestVersionCurrent.equals(isHighestVersionUpdated)) {
884 log.info("update srvice: recived request to update isHighestVersion to {} the field is not updatable ignoring.", isHighestVersionUpdated);
887 String uuidUpdated = serviceUpdate.getUUID();
888 String uuidCurrent = currentService.getUUID();
889 if (!uuidCurrent.equals(uuidUpdated)) {
890 log.info("update service: recived request to update uuid to {} the field is not updatable ignoring.", uuidUpdated);
893 response = validateAndUpdateServiceType(user, currentService, serviceUpdate, null);
894 if (response.isRight()) {
895 ResponseFormat errorResponse = response.right().value();
896 return Either.right(errorResponse);
899 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, null);
900 if (response.isRight()) {
901 ResponseFormat errorResponse = response.right().value();
902 return Either.right(errorResponse);
905 String currentInvariantUuid = currentService.getInvariantUUID();
906 String updatedInvariantUuid = serviceUpdate.getInvariantUUID();
908 if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) {
909 log.warn("Product invariant UUID is automatically set and cannot be updated");
910 serviceUpdate.setInvariantUUID(currentInvariantUuid);
912 validateAndUpdateEcompNaming(currentService, serviceUpdate);
914 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
916 return Either.left(currentService);
920 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
921 Boolean isEcompoGeneratedCurr = currentService.isEcompGeneratedNaming();
922 Boolean isEcompoGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
923 if (isEcompoGeneratedUpdate != null && isEcompoGeneratedCurr.equals(isEcompoGeneratedUpdate)) {
924 currentService.setEcompGeneratedNaming(isEcompoGeneratedUpdate);
926 String namingPolicyUpd = serviceUpdate.getNamingPolicy();
927 if (!currentService.isEcompGeneratedNaming()) {
928 if (ValidationUtils.validateStringNotEmpty(namingPolicyUpd)) {
929 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
930 currentService.setNamingPolicy("");
932 currentService.setNamingPolicy(namingPolicyUpd);
935 currentService.setNamingPolicy(namingPolicyUpd);
939 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
940 String contactIdUpdated = serviceUpdate.getContactId();
941 String contactIdCurrent = currentService.getContactId();
942 if (!contactIdCurrent.equals(contactIdUpdated)) {
943 Either<Boolean, ResponseFormat> validatContactId = validateContactId(user, serviceUpdate, audatingAction);
944 if (validatContactId.isRight()) {
945 ResponseFormat errorRespons = validatContactId.right().value();
946 return Either.right(errorRespons);
948 currentService.setContactId(contactIdUpdated.toLowerCase());
950 return Either.left(true);
953 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
954 List<String> tagsUpdated = serviceUpdate.getTags();
955 List<String> tagsCurrent = currentService.getTags();
956 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
957 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
958 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
959 return Either.right(responseFormat);
962 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
963 Either<Boolean, ResponseFormat> validatResponse = validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
964 if (validatResponse.isRight()) {
965 ResponseFormat errorRespons = validatResponse.right().value();
966 return Either.right(errorRespons);
968 currentService.setTags(tagsUpdated);
970 return Either.left(true);
973 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
974 String descriptionUpdated = serviceUpdate.getDescription();
975 String descriptionCurrent = currentService.getDescription();
976 if (!descriptionCurrent.equals(descriptionUpdated)) {
977 Either<Boolean, ResponseFormat> validateDescriptionResponse = validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
978 if (validateDescriptionResponse.isRight()) {
979 ResponseFormat errorRespons = validateDescriptionResponse.right().value();
980 return Either.right(errorRespons);
982 currentService.setDescription(serviceUpdate.getDescription());
984 return Either.left(true);
987 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
988 String projectCodeUpdated = serviceUpdate.getProjectCode();
989 String projectCodeCurrent = currentService.getProjectCode();
990 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
992 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
993 if (validatProjectCodeResponse.isRight()) {
994 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
995 return Either.right(errorRespons);
997 currentService.setProjectCode(projectCodeUpdated);
1000 return Either.left(true);
1003 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1004 String iconUpdated = serviceUpdate.getIcon();
1005 String iconCurrent = currentService.getIcon();
1006 if (!iconCurrent.equals(iconUpdated)) {
1007 if (!hasBeenCertified) {
1008 Either<Boolean, ResponseFormat> validatIconResponse = validateIcon(user, serviceUpdate, audatingAction);
1009 if (validatIconResponse.isRight()) {
1010 ResponseFormat errorRespons = validatIconResponse.right().value();
1011 return Either.right(errorRespons);
1013 currentService.setIcon(iconUpdated);
1015 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
1016 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
1017 return Either.right(errorResponse);
1020 return Either.left(true);
1023 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
1024 String serviceNameUpdated = serviceUpdate.getName();
1025 String serviceNameCurrent = currentService.getName();
1026 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
1027 if (!hasBeenCertified) {
1028 Either<Boolean, ResponseFormat> validatServiceNameResponse = validateComponentName(user, serviceUpdate, auditingAction);
1029 if (validatServiceNameResponse.isRight()) {
1030 ResponseFormat errorRespons = validatServiceNameResponse.right().value();
1031 return Either.right(errorRespons);
1034 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
1035 if (serviceNameUniquenessValidation.isRight()) {
1036 return serviceNameUniquenessValidation;
1038 currentService.setName(serviceNameUpdated);
1039 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
1040 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
1043 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
1044 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
1045 return Either.right(errorResponse);
1048 return Either.left(true);
1051 private Either<Boolean, ResponseFormat> validateAndUpdateServiceType(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1052 String updatedServiceType = updatedService.getServiceType();
1053 String currentServiceType = currentService.getServiceType();
1054 if (!currentServiceType.equals(updatedServiceType)) {
1055 Either<Boolean, ResponseFormat> validateServiceType = validateServiceTypeAndCleanup(user, updatedService , auditingAction);
1056 if (validateServiceType.isRight()) {
1057 ResponseFormat errorResponse = validateServiceType.right().value();
1058 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1059 return Either.right(errorResponse);
1061 currentService.setServiceType(updatedServiceType);
1063 return Either.left(true);
1066 protected Either<Boolean, ResponseFormat> validateServiceTypeAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1067 String serviceType = ((Service)component).getServiceType();
1068 if (serviceType != null){
1069 serviceType = cleanUpText(serviceType);
1070 Either<Boolean, ResponseFormat> validateServiceType = validateServiceType(serviceType);
1071 if (validateServiceType.isRight()) {
1072 ResponseFormat responseFormat = validateServiceType.right().value();
1073 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1074 return Either.right(responseFormat);
1076 return Either.left(true);
1078 return Either.left(false);
1083 private Either<Boolean, ResponseFormat> validateServiceType(String serviceType) {
1084 if (serviceType.equals("")){
1085 return Either.left(true);
1087 if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
1088 log.info("service type exceeds limit.");
1089 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
1090 return Either.right(errorResponse);
1093 if (!ValidationUtils.validateIsEnglish(serviceType)) {
1094 log.info("service type is not valid.");
1095 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_TYPE);
1096 return Either.right(errorResponse);
1098 return Either.left(true);
1102 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
1103 String updatedServiceRole = updatedService.getServiceRole();
1104 String currentServiceRole = currentService.getServiceRole();
1105 if (!currentServiceRole.equals(updatedServiceRole)) {
1106 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
1107 if (validateServiceRole.isRight()) {
1108 ResponseFormat errorResponse = validateServiceRole.right().value();
1109 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1110 return Either.right(errorResponse);
1112 currentService.setServiceRole(updatedServiceRole);
1114 return Either.left(true);
1117 protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
1118 String serviceRole = ((Service)component).getServiceRole();
1119 if (serviceRole != null){
1120 serviceRole = cleanUpText(serviceRole);
1122 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
1123 if (validateServiceRole.isRight()) {
1124 ResponseFormat responseFormat = validateServiceRole.right().value();
1125 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
1126 return Either.right(responseFormat);
1128 return Either.left(true);
1130 return Either.left(false);
1135 private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1136 if (serviceRole.equals("")){
1137 return Either.left(true);
1139 if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1140 log.info("service role exceeds limit.");
1141 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1142 return Either.right(errorResponse);
1145 if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1146 log.info("service role is not valid.");
1147 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1148 return Either.right(errorResponse);
1150 return Either.left(true);
1156 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1157 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1158 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1159 Either<Boolean, ResponseFormat> validatCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1160 if (validatCategoryResponse.isRight()) {
1161 ResponseFormat errorRespons = validatCategoryResponse.right().value();
1162 return Either.right(errorRespons);
1164 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1165 if (!hasBeenCertified) {
1166 currentService.setCategories(categoryUpdated);
1168 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1169 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1170 return Either.right(errorResponse);
1173 return Either.left(true);
1177 public Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1179 if (list.size() > 1) {
1180 log.debug("Must be only one category for service");
1181 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1182 return Either.right(responseFormat);
1184 CategoryDefinition category = list.get(0);
1185 if (category.getSubcategories() != null) {
1186 log.debug("Subcategories cannot be defined for service");
1187 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1188 return Either.right(responseFormat);
1190 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1191 log.debug("Resource category is empty");
1192 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1193 return Either.right(responseFormat);
1196 log.debug("validating service category {} against valid categories list", list);
1197 Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1198 if (categorys.isRight()) {
1199 log.debug("failed to retrive service categories from Titan");
1200 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1201 return Either.right(responseFormat);
1203 List<CategoryDefinition> categoryList = categorys.left().value();
1204 for (CategoryDefinition value : categoryList) {
1205 if (value.getName().equals(category.getName())) {
1206 return Either.left(true);
1209 log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1210 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1212 return Either.left(false);
1215 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1216 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1217 if (serviceResponseFormatEither.isRight()){
1218 return Either.right(serviceResponseFormatEither.right().value());
1220 final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1221 return Either.left(serviceRelations);
1224 }public ResponseFormat deleteService(String serviceId, User user) {
1225 ResponseFormat responseFormat;
1226 String ecompErrorContext = "delete service";
1228 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1229 if (eitherCreator.isRight()) {
1230 return eitherCreator.right().value();
1232 user = eitherCreator.left().value();
1234 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1235 if (serviceStatus.isRight()) {
1236 log.debug("failed to get service {}", serviceId);
1237 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1240 Service service = serviceStatus.left().value();
1242 StorageOperationStatus result = StorageOperationStatus.OK;
1243 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1244 if (lockResult.isRight()) {
1245 result = StorageOperationStatus.GENERAL_ERROR;
1246 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1251 result = markComponentToDelete(service);
1252 if (result.equals(StorageOperationStatus.OK)) {
1253 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1255 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1256 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1258 return responseFormat;
1261 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1262 log.warn("operation failed. do rollback");
1263 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1264 titanDao.rollback();
1266 log.debug("operation success. do commit");
1269 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1273 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1274 ResponseFormat responseFormat;
1275 String ecompErrorContext = "delete service";
1276 Either<User, ResponseFormat> validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext);
1277 if (validateEmptyResult.isRight()) {
1278 return validateEmptyResult.right().value();
1281 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1282 if (eitherCreator.isRight()) {
1283 return eitherCreator.right().value();
1285 user = eitherCreator.left().value();
1287 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1288 if (getResult.isRight()) {
1289 return getResult.right().value();
1291 Service service = getResult.left().value();
1293 StorageOperationStatus result = StorageOperationStatus.OK;
1294 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1295 if (lockResult.isRight()) {
1296 result = StorageOperationStatus.GENERAL_ERROR;
1297 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1301 result = markComponentToDelete(service);
1302 if (result.equals(StorageOperationStatus.OK)) {
1303 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1305 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1306 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1308 return responseFormat;
1311 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1312 log.warn("operation failed. do rollback");
1313 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1314 titanDao.rollback();
1316 log.debug("operation success. do commit");
1319 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1323 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1324 String ecompErrorContext = "Get service";
1325 Either<User, ResponseFormat> validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext);
1326 if (validateEmptyResult.isRight()) {
1327 return Either.right(validateEmptyResult.right().value());
1330 Either<User, ResponseFormat> eitherCreator = validateUserExists(user, ecompErrorContext, false);
1331 if (eitherCreator.isRight()) {
1332 return Either.right(eitherCreator.right().value());
1335 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1336 if (storageStatus.isRight()) {
1337 log.debug("failed to get service by id {}", serviceId);
1338 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1341 if(!(storageStatus.left().value() instanceof Service)){
1342 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1344 Service service = storageStatus.left().value();
1345 return Either.left(service);
1352 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1353 Either<User, ResponseFormat> resp = validateUserExists(userId, "get Service By Name And Version", false);
1354 if (resp.isRight()) {
1355 return Either.right(resp.right().value());
1357 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1358 if (storageStatus.isRight()) {
1359 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1360 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1362 Service service = storageStatus.left().value();
1363 return Either.left(service);
1366 @SuppressWarnings("unchecked")
1367 private void createMandatoryArtifactsData(Service service, User user) {
1368 // create mandatory artifacts
1370 // TODO it must be removed after that artifact uniqueId creation will be
1371 // moved to ArtifactOperation
1372 String serviceUniqueId = service.getUniqueId();
1373 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1374 if (artifactMap == null)
1375 artifactMap = new HashMap<String, ArtifactDefinition>();
1377 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1378 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1380 String category = service.getCategories().get(0).getName();
1381 boolean isCreateArtifact = true;
1382 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1383 for (String exlude : exludeServiceCategory) {
1384 if (exlude.equalsIgnoreCase(category)) {
1385 isCreateArtifact = false;
1392 if (informationalServiceArtifacts != null && isCreateArtifact) {
1393 Set<String> keys = informationalServiceArtifacts.keySet();
1394 for (String informationalServiceArtifactName : keys) {
1395 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1396 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1397 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1401 service.setArtifacts(artifactMap);
1405 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1407 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1410 artifactInfo.setMandatory(false);
1411 artifactInfo.setServiceApi(true);
1413 return artifactInfo;
1416 private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition, User user) {
1417 DistributionTransitionEnum transitionEnum = null;
1419 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1420 if (transitionEnum == null) {
1421 BeEcompErrorManager.getInstance().logBeSystemError("Change Service Distribution");
1422 log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1423 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1424 return Either.right(error);
1427 return Either.left(transitionEnum);
1430 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment, User user, AuditingActionEnum auditAction) {
1431 String data = comment.getUserRemarks();
1433 if (data == null || data.trim().isEmpty()) {
1434 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution");
1435 log.debug("user comment cannot be empty or null.");
1436 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1438 data = ValidationUtils.removeNoneUtf8Chars(data);
1439 data = ValidationUtils.removeHtmlTags(data);
1440 data = ValidationUtils.normaliseWhitespace(data);
1441 data = ValidationUtils.stripOctets(data);
1443 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1444 BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution");
1445 log.debug("user comment exceeds limit.");
1446 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1448 if (!ValidationUtils.validateIsEnglish(data)) {
1449 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1451 return Either.left(data);
1454 private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1455 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1456 if (storageStatus.isRight()) {
1457 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1458 log.debug("audit before sending response");
1459 componentsUtils.auditComponent(responseFormat, user, auditAction, serviceId, ComponentTypeEnum.SERVICE, comment);
1460 return Either.right(responseFormat);
1462 Service service = storageStatus.left().value();
1464 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1465 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1466 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1467 createAudit(user, auditAction, comment, service, responseFormat);
1468 return Either.right(responseFormat);
1470 return Either.left(service);
1473 private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1474 log.debug("get user from DB");
1477 Either<User, ResponseFormat> eitherCreator = validateUser(user, "Activate Distribution", service, auditAction, false);
1478 if (eitherCreator.isRight()) {
1479 return Either.right(eitherCreator.right().value());
1481 user = eitherCreator.left().value();
1483 // validate user role
1484 List<Role> roles = new ArrayList<>();
1485 roles.add(Role.ADMIN);
1486 roles.add(Role.GOVERNOR);
1487 roles.add(Role.OPS);
1488 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, roles, auditAction, comment);
1489 if (validateRes.isRight()) {
1490 return Either.right(validateRes.right().value());
1492 return Either.left(user);
1495 private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1496 log.debug("audit before sending response");
1497 componentsUtils.auditComponent(responseFormat, user, component, auditAction, ComponentTypeEnum.SERVICE,
1498 ResourceAuditData.newBuilder().state(component.getLifecycleState().name()).version(component.getVersion()).build(), comment);
1501 private String getEnvNameFromConfiguration() {
1502 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1503 log.trace("Update environment name to be {}", configuredEnvName);
1504 return configuredEnvName;
1507 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1509 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1510 if (activationRequestInformationEither.isRight()) {
1511 return Either.right(activationRequestInformationEither.right().value());
1514 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1516 Either<String, ResponseFormat> result = null;
1517 ResponseFormat response = null;
1518 String did = ThreadLocalsHolder.getUuid();
1519 Service service = activationRequestInformation.getServiceToActivate();
1521 StorageOperationStatus readyForDistribution = distributionEngine.verifyServiceHasDeploymentArtifacts(service);
1522 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1523 result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1525 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), service.getName(), envId);
1526 result = Either.right(response);
1531 public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1532 String envName = getEnvNameFromConfiguration();
1533 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1534 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier.getUserId(), modifier.getFullName());
1535 if (notifyServiceResponse == ActionStatus.OK) {
1536 return Either.left(did);
1538 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1539 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1540 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1541 return Either.right(error);
1545 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1547 Either<User, ResponseFormat> eitherCreator = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1548 if (eitherCreator.isRight()) {
1549 return Either.right(eitherCreator.right().value());
1552 User user = eitherCreator.left().value();
1554 Either<Service, ResponseFormat> result = null;
1555 ResponseFormat response = null;
1556 Service updatedService = null;
1557 String did = ThreadLocalsHolder.getUuid();
1559 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1560 if (configuredEnvName != null && false == envName.equals(configuredEnvName)) {
1561 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1562 envName = configuredEnvName;
1566 ServletContext servletContext = request.getSession().getServletContext();
1567 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1568 if (!isDistributionEngineUp) {
1569 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1570 log.debug("Distribution Engine is DOWN");
1571 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1572 return Either.right(response);
1575 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1576 if (serviceRes.isRight()) {
1577 log.debug("failed retrieving service");
1578 response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1579 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE,
1580 ResourceAuditData.newBuilder().build(), did);
1581 return Either.right(response);
1583 Service service = serviceRes.left().value();
1584 String dcurrStatus = service.getDistributionStatus().name();
1585 String updatedStatus = dcurrStatus;
1586 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(service, envName);
1587 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1588 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1589 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user.getUserId(), user.getFullName());
1590 if (notifyServiceResponse == ActionStatus.OK) {
1591 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1592 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1593 updatedService = updateStateRes.left().value();
1594 updatedStatus = updatedService.getDistributionStatus().name();
1596 // The response is not relevant
1597 updatedService = service;
1599 ASDCKpiApi.countActivatedDistribution();
1600 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1601 result = Either.left(updatedService);
1603 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1604 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1605 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1606 result = Either.right(response);
1609 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), service.getName(), envName);
1610 result = Either.right(response);
1612 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE,
1613 ResourceAuditData.newBuilder().distributionStatus(dcurrStatus).build(),
1614 ResourceAuditData.newBuilder().distributionStatus(updatedStatus).build(), service.getName(),
1619 // convert to private after deletion of temp url
1620 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1622 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1623 if (resp.isRight()) {
1624 return Either.right(resp.right().value());
1627 String serviceId = service.getUniqueId();
1628 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1629 if (lockResult.isRight()) {
1630 return Either.right(lockResult.right().value());
1633 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1634 if (result.isRight()) {
1635 titanDao.rollback();
1636 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1637 log.debug("service {} change distribution status failed", serviceId);
1638 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1641 return Either.left(result.left().value());
1643 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1647 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1649 Either<User, ResponseFormat> resp = validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
1650 if (resp.isRight()) {
1651 return Either.right(resp.right().value());
1654 log.debug("mark distribution deployed");
1656 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1657 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1658 if (getServiceResponse.isRight()) {
1659 BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1660 log.debug("service {} not found", serviceId);
1661 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1663 return Either.right(responseFormat);
1666 Service service = getServiceResponse.left().value();
1668 Either<User, ResponseFormat> validateRoleForDeploy = validateRoleForDeploy(did, user, auditAction, service);
1669 if (validateRoleForDeploy.isRight()) {
1670 return Either.right(validateRoleForDeploy.right().value());
1672 user = validateRoleForDeploy.left().value();
1674 return checkDistributionAndDeploy(did, user, auditAction, service);
1678 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1679 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1680 // Only one VF Module Artifact per instance - add it to a list of one
1681 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1683 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1687 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
1688 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<ArtifactGenerator<ArtifactDefinition>>();
1690 if (ri.getOriginType() == OriginTypeEnum.VF) {
1691 asList = Arrays.asList(new VfModuleArtifacGenerator(modifier, ri, service, shouldLock, inTransaction));
1696 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF, Wrapper<ResponseFormat> responseWrapper) {
1697 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1698 if(currVF.getGroupInstances() != null){
1699 currVF.getGroupInstances().stream().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1701 return currVF.getGroupInstances();
1704 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, User modifier, List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
1705 ArtifactDefinition vfModuleAertifact = null;
1706 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1707 Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
1708 if (optionalVfModuleArtifact.isPresent()) {
1709 vfModuleAertifact = optionalVfModuleArtifact.get();
1712 if (vfModuleAertifact == null) {
1713 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(modifier, currVF, service, payloadWrapper.getInnerElement());
1714 if (createVfModuleArtifact.isLeft()) {
1715 vfModuleAertifact = createVfModuleArtifact.left().value();
1717 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1720 return vfModuleAertifact;
1723 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1724 // Converts GroupDefinition to VfModuleArtifactPayload which is the
1725 // format used in the payload
1727 List<VfModuleArtifactPayload> vfModulePayloadForCurrVF = new ArrayList<VfModuleArtifactPayload>();
1728 if (groupsForCurrVF != null) {
1729 for (GroupInstance groupInstance : groupsForCurrVF) {
1730 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1731 vfModulePayloadForCurrVF.add(modulePayload);
1733 Collections.sort(vfModulePayloadForCurrVF, (art1, art2) -> VfModuleArtifactPayload.compareByGroupName(art1, art2));
1735 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1737 String vfModulePayloadString = gson.toJson(vfModulePayloadForCurrVF);
1738 payloadWrapper.setInnerElement(vfModulePayloadString);
1743 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
1744 ArtifactDefinition vfModuleAertifact = null;
1745 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1746 Wrapper<String> payloadWrapper = new Wrapper<>();
1747 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance, responseWrapper);
1748 if (responseWrapper.isEmpty()) {
1749 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1751 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1752 vfModuleAertifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, modifier, groupsForCurrVF, payloadWrapper, responseWrapper);
1754 if (responseWrapper.isEmpty() && vfModuleAertifact != null) {
1755 vfModuleAertifact = fillVfModulePayload(modifier, currVFInstance, vfModuleAertifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
1758 Either<ArtifactDefinition, ResponseFormat> result;
1759 if (responseWrapper.isEmpty()) {
1760 result = Either.left(vfModuleAertifact);
1762 result = Either.right(responseWrapper.getInnerElement());
1768 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
1769 ArtifactDefinition result = null;
1770 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, () -> System.currentTimeMillis(),
1771 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
1772 if (eitherPayload.isLeft()) {
1773 result = eitherPayload.left().value();
1775 responseWrapper.setInnerElement(eitherPayload.right().value());
1777 if (result == null) {
1778 result = vfModuleArtifact;
1784 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(User modifier, ComponentInstance currVF, Service service, String vfModulePayloadString) {
1786 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
1787 String newCheckSum = null;
1789 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
1790 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
1791 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
1792 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
1793 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
1794 vfModuleArtifactDefinition.setTimeout(0);
1795 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
1796 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
1797 if (vfModulePayloadString != null) {
1798 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
1800 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
1802 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
1804 Either<ArtifactDefinition, ResponseFormat> result;
1805 if (addArifactToComponent.isLeft()) {
1806 result = Either.left(addArifactToComponent.left().value());
1808 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
1814 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1816 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1817 // Get All Deployment Artifacts
1818 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1819 // Filter in Only Heat Env
1820 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1821 // Create ArtifactGenerator from those Artifacts
1822 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
1824 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1828 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1830 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1832 if (service.getComponentInstances() != null) {
1833 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1834 if (artifactGenList != null && !artifactGenList.isEmpty()) {
1835 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1836 Either<CallVal, ResponseFormat> callRes;
1838 callRes = entry.call();
1839 if (callRes.isRight()) {
1840 log.debug("Failed to generate artifact error : {}", callRes.right().value());
1841 return Either.right(callRes.right().value());
1843 } catch (Exception e) {
1844 log.debug("Failed to generate artifact exception : {}", e);
1845 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1850 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1851 if (storageStatus.isRight()) {
1852 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1855 Service currentService = storageStatus.left().value();
1857 return Either.left(currentService);
1861 abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
1865 class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
1866 ArtifactDefinition artifactDefinition;
1868 String resourceInstanceName;
1872 boolean inTransaction;
1874 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
1875 this.artifactDefinition = artifactDefinition;
1876 this.service = service;
1877 this.resourceInstanceName = resourceInstanceName;
1878 this.modifier = modifier;
1879 this.shouldLock = shouldLock;
1880 this.instanceId = instanceId;
1881 this.inTransaction = inTransaction;
1885 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1886 return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
1889 public ArtifactDefinition getArtifactDefinition() {
1890 return artifactDefinition;
1895 class VfModuleArtifacGenerator extends ArtifactGenerator<ArtifactDefinition> {
1897 private ComponentInstance componentInstance;
1898 private Service service;
1900 boolean inTransaction;
1903 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1904 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
1907 private VfModuleArtifacGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
1910 this.componentInstance = componentInstance;
1911 this.service = service;
1912 this.shouldLock = shouldLock;
1913 this.inTransaction = inTransaction;
1918 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
1919 boolean isDeployed = isDistributionDeployed(did, service);
1921 return Either.left(service);
1923 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(did, user, auditAction, service);
1924 if (distributionSuccess.isRight()) {
1925 return Either.right(distributionSuccess.right().value());
1928 log.debug("mark distribution {} as deployed - success", did);
1929 componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, STATUS_DEPLOYED, "OK", user);
1930 return Either.left(service);
1933 private boolean isDistributionDeployed(String did, Service service) {
1934 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(did, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1936 boolean isDeployed = false;
1937 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1939 log.debug("distribution {} is already deployed", did);
1945 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1947 log.trace("checkDistributionSuccess");
1948 // get all "DRequest" records for this distribution
1950 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1951 if (distRequestsResponse.isRight()) {
1952 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1953 return Either.right(error);
1956 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1957 if (distributionRequests.isEmpty()) {
1958 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1959 log.info("distribution {} is not found", did);
1960 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1961 return Either.right(error);
1963 boolean isRequestSucceeded = false;
1964 for (ResourceAdminEvent event : distributionRequests) {
1965 String eventStatus = event.getStatus();
1966 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1967 isRequestSucceeded = true;
1972 // get all "DNotify" records for this distribution
1973 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1974 if (distNotificationsResponse.isRight()) {
1975 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1976 return Either.right(error);
1979 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1980 boolean isNotificationsSucceeded = false;
1981 for (DistributionNotificationEvent event : distributionNotifications) {
1982 String eventStatus = event.getStatus();
1983 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1984 isNotificationsSucceeded = true;
1989 // if request failed OR there are notifications that failed
1990 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1992 log.info("distribution {} has failed", did);
1993 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1994 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1995 return Either.right(error);
1997 return Either.left(true);
2000 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
2002 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
2003 String message = "";
2004 if (error.getMessageId() != null) {
2005 message = error.getMessageId() + ": ";
2007 message += error.getFormattedMessage();
2009 if (service != null) {
2010 componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
2012 componentsUtils.auditServiceDistributionDeployed(auditAction, "", "", "", did, error.getStatus().toString(), message, user);
2017 private Either<User, ResponseFormat> validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
2018 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
2019 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
2020 BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
2021 log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
2022 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
2023 auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
2024 return Either.right(responseFormat);
2026 user = eitherCreator.left().value();
2027 log.debug("validate user role");
2028 List<Role> roles = new ArrayList<>();
2029 roles.add(Role.ADMIN);
2030 roles.add(Role.OPS);
2031 Either<Boolean, ResponseFormat> validateRes = validateUserRole(user, service, roles, auditAction, null);
2032 if (validateRes.isRight()) {
2033 log.info("role {} is not allowed to perform this action", user.getRole());
2034 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION);
2035 auditDeployError(did, user, auditAction, service, ActionStatus.RESTRICTED_OPERATION);
2036 return Either.right(responseFormat);
2038 return Either.left(user);
2043 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
2048 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
2049 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
2052 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
2053 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
2054 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
2055 HealthCheckBusinessLogic healthCheckBl = webApplicationContext.getBean(HealthCheckBusinessLogic.class);
2056 return healthCheckBl;
2060 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
2061 return componentInstanceBusinessLogic;
2065 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText) {
2067 Either<User, ResponseFormat> resp = validateUserExists(userId, "Get Component Instances", false);
2068 if (resp.isRight()) {
2069 return Either.right(resp.right().value());
2071 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
2072 if (getComponentRes.isRight()) {
2073 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
2074 return Either.right(responseFormat);
2077 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
2079 return Either.left(componentInstances);
2082 public ICacheMangerOperation getCacheManagerOperation() {
2083 return cacheManagerOperation;
2086 public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
2087 this.cacheManagerOperation = cacheManagerOperation;
2090 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
2091 this.forwardingPathOperation = forwardingPathOperation;
2095 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
2096 this.toscaOperationFacade = toscaOperationFacade;
2098 * 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
2102 * @param componentInstanceId
2103 * @param groupInstanceId
2104 * @param newProperties
2107 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2109 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2110 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
2111 Component component = null;
2112 Either<Boolean, ResponseFormat> lockResult = null;
2113 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
2115 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
2116 if (validateUserAndComponentRes.isRight()) {
2117 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
2118 actionResult = Either.right(validateUserAndComponentRes.right().value());
2120 if (actionResult == null) {
2121 component = validateUserAndComponentRes.left().value().getKey();
2122 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
2123 if (lockResult.isRight()) {
2124 log.debug("Failed to lock service {}. Response is {}. ", component.getName(), lockResult.right().value().getFormattedMessage());
2125 actionResult = Either.right(lockResult.right().value());
2127 log.debug("The service with system name {} locked. ", component.getSystemName());
2130 if (actionResult == null) {
2131 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
2132 if (actionResult.isRight()) {
2133 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
2136 } catch (Exception e) {
2137 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
2138 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2140 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2141 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
2144 return actionResult;
2147 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
2149 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
2150 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
2151 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
2152 ComponentInstance relatedComponentInstance = null;
2153 GroupInstance oldGroupInstance = null;
2154 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
2155 GroupInstance updatedGroupInstance = null;
2156 boolean inTransaction = true;
2157 boolean shouldCloseTransaction = true;
2158 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
2159 if (findGroupInstanceRes.isRight()) {
2160 log.debug("Group instance {} not found. ", groupInstanceId);
2161 actionResult = Either.right(findGroupInstanceRes.right().value());
2163 if (actionResult == null) {
2164 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
2165 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
2166 updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties, inTransaction);
2167 if (updateGroupInstanceResult.isRight()) {
2168 log.debug("Failed to update group instance {} property values. ", oldGroupInstance.getName());
2169 actionResult = Either.right(updateGroupInstanceResult.right().value());
2172 if (actionResult == null) {
2173 updatedGroupInstance = updateGroupInstanceResult.left().value();
2174 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
2175 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction, shouldCloseTransaction);
2176 if (updateParentsModificationTimeRes.isRight()) {
2177 log.debug("Failed to update modification time. ", oldGroupInstance.getName());
2178 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2182 if (actionResult == null) {
2183 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2185 return actionResult;
2188 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2189 boolean inTranscation, boolean shouldCloseTransaction) {
2191 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2192 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2193 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2194 updatedGroupInstance.getModificationTime(), inTranscation);
2195 if (updateComponentInstanceRes.isRight()) {
2196 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2197 actionResult = Either.right(updateComponentInstanceRes.right().value());
2199 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component, updatedGroupInstance.getModificationTime());
2200 if (serviceMetadataUpdateResult.isRight()) {
2201 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2202 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2204 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2207 return actionResult;
2210 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2212 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2213 Either<Component, ResponseFormat> validateComponentExistsRes = null;
2214 User currUser = null;
2215 Component component = null;
2216 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2217 if (validationUserResult.isRight()) {
2218 log.debug("Failed to validate user with userId for update service {}. ", modifier.getUserId(), serviceId);
2219 result = Either.right(validationUserResult.right().value());
2221 if (result == null) {
2222 currUser = validationUserResult.left().value();
2223 validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2224 if (validateComponentExistsRes.isRight()) {
2225 log.debug("Failed to validate service existing {}. ", serviceId);
2226 result = Either.right(validateComponentExistsRes.right().value());
2229 if (result == null) {
2230 component = validateComponentExistsRes.left().value();
2231 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2232 log.info("Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2233 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2236 if (result == null) {
2237 result = Either.left(new ImmutablePair<>(component, currUser));
2242 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2244 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2245 GroupInstance groupInstance = null;
2246 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2247 if (foundComponentInstance == null) {
2248 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2249 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2250 } else if (!CollectionUtils.isEmpty(foundComponentInstance.getGroupInstances())) {
2251 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2252 if (groupInstance == null) {
2253 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2254 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2257 if (actionResult == null) {
2258 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2260 return actionResult;
2263 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2264 ComponentInstance componentInstance = null;
2265 if (!CollectionUtils.isEmpty(component.getComponentInstances())) {
2266 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2268 return componentInstance;
2271 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2272 Either<User, ResponseFormat> result = validateUser(modifier, ecompErrorContext, null, null, false);
2273 if (result.isLeft()) {
2274 List<Role> roles = new ArrayList<>();
2275 roles.add(Role.ADMIN);
2276 roles.add(Role.DESIGNER);
2277 Either<Boolean, ResponseFormat> validationRoleRes = validateUserRole(result.left().value(), roles);
2278 if (validationRoleRes.isRight()) {
2279 result = Either.right(validationRoleRes.right().value());
2285 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2287 ComponentParametersView paramsToRetuen = new ComponentParametersView(dataParamsToReturn);
2288 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToRetuen);
2290 if (serviceResultEither.isRight()) {
2291 if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2292 log.debug("Failed to found service with id {} ", serviceId);
2293 Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2296 log.debug("failed to get service by id {} with filters {}", serviceId, dataParamsToReturn.toString());
2297 return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2300 Service service = serviceResultEither.left().value();
2301 UiComponentDataTransfer dataTransfer = UiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2302 return Either.left(dataTransfer);