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.annotations.VisibleForTesting;
24 import com.google.common.base.Strings;
25 import com.google.gson.Gson;
26 import com.google.gson.GsonBuilder;
27 import fj.data.Either;
28 import org.apache.commons.collections.MapUtils;
29 import org.apache.commons.lang3.StringUtils;
30 import org.apache.commons.lang3.tuple.ImmutablePair;
31 import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine;
32 import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
33 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
34 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
35 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
36 import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
37 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
38 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
39 import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
40 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
41 import org.openecomp.sdc.be.config.BeEcompErrorManager;
42 import org.openecomp.sdc.be.config.ConfigurationManager;
43 import org.openecomp.sdc.be.dao.api.ActionStatus;
44 import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
45 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
46 import org.openecomp.sdc.be.datamodel.ServiceRelations;
47 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
48 import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
49 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
51 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
52 import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
53 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
54 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
55 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
56 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
57 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
58 import org.openecomp.sdc.be.model.*;
59 import org.openecomp.sdc.be.model.category.CategoryDefinition;
60 import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
61 import org.openecomp.sdc.be.model.jsontitan.operations.NodeFilterOperation;
62 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
63 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
64 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
65 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
66 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
67 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
68 import org.openecomp.sdc.be.resources.data.ComponentInstanceData;
69 import org.openecomp.sdc.be.resources.data.ComponentMetadataData;
70 import org.openecomp.sdc.be.resources.data.auditing.*;
71 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
72 import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
73 import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer;
74 import org.openecomp.sdc.be.user.Role;
75 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
76 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
77 import org.openecomp.sdc.common.api.Constants;
78 import org.openecomp.sdc.common.datastructure.Wrapper;
79 import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
80 import org.openecomp.sdc.common.log.wrappers.Logger;
81 import org.openecomp.sdc.common.util.GeneralUtility;
82 import org.openecomp.sdc.common.util.ThreadLocalsHolder;
83 import org.openecomp.sdc.common.util.ValidationUtils;
84 import org.openecomp.sdc.exception.ResponseFormat;
85 import org.springframework.beans.factory.annotation.Autowired;
86 import org.springframework.web.context.WebApplicationContext;
88 import javax.servlet.ServletContext;
89 import javax.servlet.http.HttpServletRequest;
90 import java.nio.charset.StandardCharsets;
92 import java.util.concurrent.Callable;
93 import java.util.function.Function;
94 import java.util.stream.Collectors;
96 import static org.apache.commons.collections.CollectionUtils.isEmpty;
97 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
98 import static org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum.UPDATE_SERVICE_METADATA;
100 @org.springframework.stereotype.Component("serviceBusinessLogic")
101 public class ServiceBusinessLogic extends ComponentBusinessLogic {
103 private static final String CHANGE_SERVICE_DISTRIBUTION = "Change Service Distribution";
104 private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
105 private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
106 private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
107 private static final Logger log = Logger.getLogger(ServiceBusinessLogic.class);
108 private static final String INITIAL_VERSION = "0.1";
109 private static final String STATUS_SUCCESS_200 = "200";
110 private static final String STATUS_DEPLOYED = "DEPLOYED";
112 private IDistributionEngine distributionEngine;
114 private AuditCassandraDao auditCassandraDao;
116 private ComponentInstanceBusinessLogic componentInstanceBusinessLogic;
118 private ICacheMangerOperation cacheManagerOperation;
120 private ServiceDistributionValidation serviceDistributionValidation;
123 private ForwardingPathOperation forwardingPathOperation;
125 private ForwardingPathValidator forwardingPathValidator;
127 private UiComponentDataConverter uiComponentDataConverter;
129 private NodeFilterOperation serviceFilterOperation;
131 private NodeFilterValidator serviceFilterValidator;
133 public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
135 validateUserExists(user.getUserId(), "change Service Distribution State", false);
137 log.debug("check request state");
138 Either<DistributionTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(state);
139 if (validateEnum.isRight()) {
140 return Either.right(validateEnum.right().value());
142 DistributionTransitionEnum distributionTransition = validateEnum.left().value();
143 AuditingActionEnum auditAction = distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT;
144 Either<String, ResponseFormat> commentResponse = validateComment(commentObj);
145 if (commentResponse.isRight()) {
146 return Either.right(commentResponse.right().value());
148 String comment = commentResponse.left().value();
150 Either<Service, ResponseFormat> validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment);
151 if (validateService.isRight()) {
152 return Either.right(validateService.right().value());
154 Service service = validateService.left().value();
155 Either<User, ResponseFormat> validateUser = validateUserDistributionChange(user, service, auditAction, comment);
156 if (validateUser.isRight()) {
157 return Either.right(validateUser.right().value());
159 user = validateUser.left().value();
163 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState");
164 if (lockResult.isRight()) {
165 ResponseFormat responseFormat = lockResult.right().value();
166 createAudit(user, auditAction, comment, service, responseFormat);
167 return Either.right(responseFormat);
172 DistributionStatusEnum newState;
173 if (distributionTransition == DistributionTransitionEnum.APPROVE) {
174 newState = DistributionStatusEnum.DISTRIBUTION_APPROVED;
176 newState = DistributionStatusEnum.DISTRIBUTION_REJECTED;
178 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, newState);
179 if (result.isRight()) {
181 BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState");
182 log.debug("service {} is change destribuation status failed", service.getUniqueId());
183 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName());
184 createAudit(user, auditAction, comment, service, responseFormat);
185 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
188 Service updatedService = result.left().value();
189 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK);
190 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
191 componentsUtils.auditComponent(responseFormat, user, updatedService, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()), ResourceVersionInfo.newBuilder().build(), comment);
192 return Either.left(result.left().value());
194 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
199 public Either<List<Map<String, Object>>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) {
200 validateUserExists(userId, "get Component Audit Records", false);
201 Either<List<Map<String, Object>>, ActionStatus> result;
205 if (componentVersion.endsWith(".0")) {
206 Either<List<ResourceAdminEvent>, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID);
207 if (eitherAuditingForCertified.isLeft()) {
208 result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value()));
210 result = Either.right(eitherAuditingForCertified.right().value());
213 // Uncertified Version
215 result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion);
217 } catch (Exception e) {
218 log.debug("get Audit Records failed with exception {}", e);
219 result = Either.right(ActionStatus.GENERAL_ERROR);
222 if (result.isRight()) {
223 return Either.right(componentsUtils.getResponseFormat(result.right().value()));
225 return Either.left(result.left().value());
230 private Either<List<Map<String, Object>>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) {
232 Either<List<ResourceAdminEvent>, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion);
234 if (eitherprevVerAudit.isRight()) {
235 return Either.right(eitherprevVerAudit.right().value());
239 Either<List<ResourceAdminEvent>, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion);
240 if (eitherCurrVerAudit.isRight()) {
241 return Either.right(eitherCurrVerAudit.right().value());
245 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveRestoreList = getArchiveRestoreEventList(componentUUID);
246 if (eitherArchiveRestoreList.isRight()) {
247 return Either.right(eitherArchiveRestoreList.right().value());
250 List<Map<String, Object>> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value());
251 List<Map<String, Object>> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value());
253 List<Map<String, Object>> duplicateElements = new ArrayList<>();
254 duplicateElements.addAll(prevVerAuditList);
255 duplicateElements.retainAll(currVerAuditList);
257 List<Map<String, Object>> joinedNonDuplicatedList = new ArrayList<>();
258 joinedNonDuplicatedList.addAll(prevVerAuditList);
259 joinedNonDuplicatedList.removeAll(duplicateElements);
260 joinedNonDuplicatedList.addAll(currVerAuditList);
261 joinedNonDuplicatedList.addAll(getAuditingFieldsList(eitherArchiveRestoreList.left().value()));
264 return Either.left(joinedNonDuplicatedList);
267 private Either<List<ResourceAdminEvent>, ActionStatus> getArchiveRestoreEventList(String componentUUID) {
269 Either<List<ResourceAdminEvent>, ActionStatus> eitherArchiveAudit = auditCassandraDao.getArchiveAuditByServiceInstanceId(componentUUID);
270 if (eitherArchiveAudit.isRight()) {
271 return Either.right(eitherArchiveAudit.right().value());
275 Either<List<ResourceAdminEvent>, ActionStatus> eitherRestoreAudit = auditCassandraDao.getRestoreAuditByServiceInstanceId(componentUUID);
276 if (eitherRestoreAudit.isRight()) {
277 return Either.right(eitherRestoreAudit.right().value());
280 List<ResourceAdminEvent> archiveAudit = new ArrayList<>();
281 archiveAudit.addAll(eitherArchiveAudit.left().value());
282 archiveAudit.addAll(eitherRestoreAudit.left().value());
284 return Either.left(archiveAudit);
287 private List<Map<String, Object>> getAuditingFieldsList(List<? extends AuditingGenericEvent> prevVerAuditList) {
289 List<Map<String, Object>> prevVerAudit = new ArrayList<>();
290 for (AuditingGenericEvent auditEvent : prevVerAuditList) {
291 auditEvent.fillFields();
292 prevVerAudit.add(auditEvent.getFields());
303 * - modifier data (userId)
304 * @return Either<Service, responseFormat>
306 public Either<Service, ResponseFormat> createService(Service service, User user) {
309 user = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false);
310 // validate user role
311 validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
312 service.setCreatorUserId(user.getUserId());
313 // warn on overridden fields
314 checkFieldsForOverideAttampt(service);
316 log.debug("enrich service with version and state");
317 service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
318 service.setVersion(INITIAL_VERSION);
319 service.setConformanceLevel(ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
320 service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED);
322 Either<Service, ResponseFormat> createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE);
323 if (createServiceResponse.isRight()) {
324 return createServiceResponse;
326 return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, user);
329 private void checkFieldsForOverideAttampt(Service service) {
330 checkComponentFieldsForOverrideAttempt(service);
331 if (service.getDistributionStatus() != null) {
332 log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
336 private Either<Service, ResponseFormat> createServiceByDao(Service service, AuditingActionEnum actionEnum, User user) {
337 log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName());
339 Either<Boolean, ResponseFormat> lockResult = lockComponentByName(service.getSystemName(), service, "Create Service");
340 if (lockResult.isRight()) {
341 ResponseFormat responseFormat = lockResult.right().value();
342 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
343 return Either.right(responseFormat);
346 log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult);
350 createMandatoryArtifactsData(service, user);
351 createServiceApiArtifactsData(service, user);
352 setToscaArtifactsPlaceHolders(service, user);
353 generateAndAddInputsFromGenericTypeProperties(service, fetchAndSetDerivedFromGenericType(service));
355 Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
357 // service created successfully!!!
358 if (dataModelResponse.isLeft()) {
359 log.debug("Service created successfully!!!");
360 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED);
361 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
362 ASDCKpiApi.countCreatedServicesKPI();
363 return Either.left(dataModelResponse.left().value());
366 ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE);
367 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
368 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
369 return Either.right(responseFormat);
372 graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service);
376 @SuppressWarnings("unchecked")
377 private void createServiceApiArtifactsData(Service service, User user) {
378 // create mandatory artifacts
380 // TODO it must be removed after that artifact uniqueId creation will be
381 // moved to ArtifactOperation
382 String serviceUniqueId = service.getUniqueId();
383 Map<String, ArtifactDefinition> artifactMap = service.getServiceApiArtifacts();
384 if (artifactMap == null)
385 artifactMap = new HashMap<>();
387 Map<String, Object> serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts();
388 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
390 List<CategoryDefinition> categories = service.getCategories();
391 boolean isCreateArtifact = true;
392 if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
393 for (String exlude : exludeServiceCategory) {
394 if (exlude.equalsIgnoreCase(categories.get(0).getName())) {
395 isCreateArtifact = false;
402 if (serviceApiArtifacts != null && isCreateArtifact) {
403 Set<String> keys = serviceApiArtifacts.keySet();
404 for (String serviceApiArtifactName : keys) {
405 Map<String, Object> artifactInfoMap = (Map<String, Object>) serviceApiArtifacts.get(serviceApiArtifactName);
406 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true);
407 artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API);
408 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
411 service.setServiceApiArtifacts(artifactMap);
415 private Either<Service, ResponseFormat> validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) {
417 Either<Boolean, ResponseFormat> validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum);
418 if (validationResponse.isRight()) {
419 return Either.right(validationResponse.right().value());
421 service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
422 service.setContactId(service.getContactId().toLowerCase());
424 // Generate invariant UUID - must be here and not in operation since it
425 // should stay constant during clone
426 String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
427 service.setInvariantUUID(invariantUUID);
429 return Either.left(service);
434 private Either<Boolean, ResponseFormat> validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) {
436 validateComponentFieldsBeforeCreate(user, service, actionEnum);
438 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum);
439 if (serviceNameUniquenessValidation.isRight()) {
440 throw new ComponentException(serviceNameUniquenessValidation.right().value());
442 Either<Boolean, ResponseFormat> categoryValidation = validateServiceCategory(user, service, actionEnum);
443 if (categoryValidation.isRight()) {
444 return categoryValidation;
446 Either<Boolean, ResponseFormat> projectCodeValidation = validateProjectCode(user, service, actionEnum);
447 if (projectCodeValidation.isRight()) {
448 return projectCodeValidation;
450 validateServiceTypeAndCleanup(service);
452 Either<Boolean, ResponseFormat> serviceRoleValidation = validateServiceRoleAndCleanup(user, service, actionEnum);
453 if (serviceRoleValidation.isRight()) {
454 return serviceRoleValidation;
456 return validateInstantiationTypeValue(user, service, actionEnum);
457 } catch (ComponentException exception) {
458 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
459 componentsUtils.auditComponentAdmin(responseFormat, user, service,
460 AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
461 return Either.right(responseFormat);
465 private Either<Boolean, ResponseFormat> validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) {
466 log.debug("validate Service category");
467 if (isEmpty(service.getCategories())) {
468 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
469 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
470 return Either.right(errorResponse);
472 Either<Boolean, ResponseFormat> validatCategory = validateServiceCategory(service.getCategories());
473 if (validatCategory.isRight()) {
474 ResponseFormat responseFormat = validatCategory.right().value();
475 componentsUtils.auditComponentAdmin(responseFormat, user, service, actionEnum, ComponentTypeEnum.SERVICE);
476 return Either.right(responseFormat);
478 return Either.left(true);
481 public Either<Map<String, Boolean>, ResponseFormat> validateServiceNameExists(String serviceName, String userId) {
482 validateUserExists(userId, "validate Service Name Exists", false);
484 Either<Boolean, StorageOperationStatus> dataModelResponse = toscaOperationFacade.validateComponentNameUniqueness(serviceName, null, ComponentTypeEnum.SERVICE);
488 if (dataModelResponse.isLeft()) {
489 Map<String, Boolean> result = new HashMap<>();
490 result.put("isValid", dataModelResponse.left().value());
491 log.debug("validation was successfully performed.");
492 return Either.left(result);
494 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()));
495 return Either.right(responseFormat);
498 public void setElementDao(IElementOperation elementDao) {
499 this.elementDao = elementDao;
502 public void setCassandraAuditingDao(AuditCassandraDao auditingDao) {
503 this.auditCassandraDao = auditingDao;
506 public ArtifactsBusinessLogic getArtifactBl() {
507 return artifactsBusinessLogic;
510 public void setArtifactBl(ArtifactsBusinessLogic artifactBl) {
511 this.artifactsBusinessLogic = artifactBl;
514 public Either<Service, ResponseFormat> updateServiceMetadata(String serviceId, Service serviceUpdate, User user) {
515 user = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false);
516 // validate user role
517 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
519 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
520 if (storageStatus.isRight()) {
521 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
524 Service currentService = storageStatus.left().value();
526 if (!ComponentValidationUtils.canWorkOnComponent(currentService, user.getUserId())) {
527 log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
528 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
531 Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
532 if (validationRsponse.isRight()) {
533 log.info("service update metadata: validations field.");
534 return validationRsponse;
536 Service serviceToUpdate = validationRsponse.left().value();
539 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, currentService, "Update Service Metadata");
540 if (lockResult.isRight()) {
541 return Either.right(lockResult.right().value());
544 Either<Service, StorageOperationStatus> updateResponse = toscaOperationFacade.updateToscaElement(serviceToUpdate);
545 if (updateResponse.isRight()) {
547 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
548 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
549 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
552 return Either.left(updateResponse.left().value());
554 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
558 public Either<Set<String>, ResponseFormat> deleteForwardingPaths(String serviceId, Set<String> pathIdsToDelete, User user, boolean lock) {
559 Service serviceToDelete = initServiceToDeletePaths(serviceId, pathIdsToDelete);
560 user = validateUser(user, "deleteForwardingPaths", serviceToDelete, null, false);
561 // validate user role
562 validateUserRole(user, serviceToDelete, new ArrayList<>(), null, null);
563 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
564 if (storageStatus.isRight()) {
565 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
567 Service service = storageStatus.left().value();
568 Either<Set<String>, StorageOperationStatus> result = null;
570 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Forwarding Path on Service");
571 if (lockResult.isRight()) {
573 return Either.right(componentsUtils.getResponseFormat(componentsUtils
574 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
578 result = forwardingPathOperation.deleteForwardingPath(service ,pathIdsToDelete);
579 if (result.isRight()) {
580 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, service.getName(), result.right().value());
582 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
585 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, service.getSystemName());
587 } catch (Exception e){
588 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
590 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
592 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
594 return Either.left(result.left().value());
597 private Service initServiceToDeletePaths(String serviceId, Collection<String> pathIdsToDelete) {
598 Service serviceToDelete = new Service();
599 serviceToDelete.setUniqueId(serviceId);
600 serviceToDelete.setForwardingPaths(new HashMap<>());
601 pathIdsToDelete.forEach(pathIdToDelete -> serviceToDelete.getForwardingPaths().put(pathIdToDelete, new ForwardingPathDataDefinition()));
602 return serviceToDelete;
605 public Either<Service, ResponseFormat> updateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
606 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, true,"updateForwardingPath", lock);
609 public Either<Service, ResponseFormat> createForwardingPath(String serviceId, Service serviceUpdate, User user, boolean lock) {
610 return createOrUpdateForwardingPath(serviceId, serviceUpdate, user, false, "createForwardingPath", lock);
613 private ForwardingPathDataDefinition getTrimmedValues(ForwardingPathDataDefinition path){
614 ForwardingPathDataDefinition dataDefinition = new ForwardingPathDataDefinition(path.getName());
615 dataDefinition.setName(Strings.nullToEmpty(path.getName()).trim());
616 dataDefinition.setProtocol(Strings.nullToEmpty(path.getProtocol()).trim());
617 dataDefinition.setDestinationPortNumber(Strings.nullToEmpty(path.getDestinationPortNumber()).trim());
618 dataDefinition.setUniqueId(path.getUniqueId());
619 dataDefinition.setPathElements(path.getPathElements());
620 dataDefinition.setDescription(path.getDescription());
621 dataDefinition.setToscaResourceName(path.getToscaResourceName());
622 return dataDefinition;
625 private Either<Service, ResponseFormat> createOrUpdateForwardingPath(String serviceId, Service serviceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) {
626 validateUserAndRole(serviceUpdate, user, errorContext);
628 Map<String, ForwardingPathDataDefinition> forwardingPaths = serviceUpdate.getForwardingPaths();
630 Map<String, ForwardingPathDataDefinition> trimmedForwardingPaths =
631 forwardingPaths.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey,
632 entry -> new ForwardingPathDataDefinition(getTrimmedValues(entry.getValue()))));
634 Either<Boolean, ResponseFormat> booleanResponseFormatEither = forwardingPathValidator.validateForwardingPaths(trimmedForwardingPaths.values(),
635 serviceId, isUpdate);
636 if(booleanResponseFormatEither.isRight()){
637 return Either.right(booleanResponseFormatEither.right().value());
640 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
642 if(serviceStorageOperationStatusEither.isRight()){
643 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
644 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
645 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
647 Service storedService = serviceStorageOperationStatusEither.left().value();
649 Either<ForwardingPathDataDefinition, StorageOperationStatus> result;
650 Either<Component, StorageOperationStatus> forwardingPathOrigin = toscaOperationFacade.getLatestByName(ForwardingPathUtils.FORWARDING_PATH_NODE_NAME);
651 if (forwardingPathOrigin.isRight()) {
652 StorageOperationStatus errorStatus = forwardingPathOrigin.right().value();
653 log.debug("Failed to fetch normative forwarding path resource by tosca name, error {}", errorStatus);
654 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
656 Component component = forwardingPathOrigin.left().value();
657 final String toscaResourceName;
658 if ( component.getComponentType() == ComponentTypeEnum.RESOURCE) {
659 toscaResourceName = ((Resource) component).getToscaResourceName();
661 toscaResourceName = "";
663 Either<Boolean, ResponseFormat> lockResult = null;
666 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Forwarding Path on Service");
667 if (lockResult.isRight()) {
668 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, storedService.getName(),
669 lockResult.right().value().getFormattedMessage());
670 return Either.right(lockResult.right().value());
672 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, storedService.getSystemName());
675 Map<String, ForwardingPathDataDefinition> resultMap = new HashMap<>();
677 trimmedForwardingPaths.values().forEach(fp -> fp.setToscaResourceName(toscaResourceName));
680 for (ForwardingPathDataDefinition forwardingPathDataDefinition : trimmedForwardingPaths.values()) {
682 result = forwardingPathOperation.updateForwardingPath(serviceId, forwardingPathDataDefinition);
684 result = forwardingPathOperation.addForwardingPath(serviceId, forwardingPathDataDefinition);
686 if (result.isRight()) {
688 return Either.right(componentsUtils.getResponseFormat(
689 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
692 ForwardingPathDataDefinition fpDataDefinition = result.left().value();
693 resultMap.put(fpDataDefinition.getUniqueId(), forwardingPathDataDefinition);
697 } catch (Exception e) {
699 log.error("Exception occurred during add or update forwarding path property values: {}", e.getMessage(),
701 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
705 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
706 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
709 Service service = createServiceWithForwardingPathForResponse(serviceId, resultMap);
710 return Either.left(service);
713 private Service createServiceWithForwardingPathForResponse(String serviceId, Map<String,ForwardingPathDataDefinition> forwardingPathDataDefinitionMap) {
714 Service service = new Service();
715 service.setUniqueId(serviceId);
716 service.setForwardingPaths(forwardingPathDataDefinitionMap);
720 private void validateUserAndRole(Service serviceUpdate, User user, String errorContext) {
721 user = validateUser(user, errorContext, serviceUpdate, null, false);
722 validateUserRole(user, serviceUpdate, new ArrayList<>(), null, null);
727 Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
730 boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
731 Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
732 if (response.isRight()) {
733 ResponseFormat errorResponse = response.right().value();
734 return Either.right(errorResponse);
737 verifyValuesAreIdentical(serviceUpdate.getCreatorUserId(), currentService.getCreatorUserId(), "creatorUserId");
738 verifyValuesAreIdentical(serviceUpdate.getCreatorFullName(), currentService.getCreatorFullName(), "creatorFullName");
739 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterUserId(), currentService.getLastUpdaterUserId(), "lastUpdaterUserId");
740 verifyValuesAreIdentical(serviceUpdate.getLastUpdaterFullName(), currentService.getLastUpdaterFullName(), "lastUpdaterFullName");
742 response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null);
743 if (response.isRight()) {
744 return Either.right(response.right().value());
747 verifyValuesAreIdentical(serviceUpdate.getDistributionStatus(), currentService.getDistributionStatus(), "distributionStatus");
749 if (serviceUpdate.getProjectCode() != null) {
750 response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
751 if (response.isRight()) {
752 return Either.right(response.right().value());
756 response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, UPDATE_SERVICE_METADATA);
757 if (response.isRight()) {
758 return Either.right(response.right().value());
761 verifyValuesAreIdentical(serviceUpdate.getCreationDate(), currentService.getCreationDate(), "creationDate");
762 verifyValuesAreIdentical(serviceUpdate.getVersion(), currentService.getVersion(), "version");
764 response = validateAndUpdateDescription(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
765 if (response.isRight()) {
766 return Either.right(response.right().value());
769 response = validateAndUpdateTags(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
770 if (response.isRight()) {
771 return Either.right(response.right().value());
774 response = validateAndUpdateContactId(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
775 if (response.isRight()) {
776 return Either.right(response.right().value());
779 verifyValuesAreIdentical(serviceUpdate.getLastUpdateDate(), currentService.getLastUpdateDate(), "lastUpdateDate");
780 verifyValuesAreIdentical(serviceUpdate.getLifecycleState(), currentService.getLifecycleState(), "lifecycleState");
781 verifyValuesAreIdentical(serviceUpdate.isHighestVersion(), currentService.isHighestVersion(), "isHighestVersion");
782 verifyValuesAreIdentical(serviceUpdate.getUUID(), currentService.getUUID(), "uuid");
784 validateAndUpdateServiceType(currentService, serviceUpdate);
786 response = validateAndUpdateServiceRole(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
787 if (response.isRight()) {
788 return Either.right(response.right().value());
791 response = validateAndUpdateInstantiationTypeValue(user, currentService, serviceUpdate, UPDATE_SERVICE_METADATA);
792 if (response.isRight()) {
793 return Either.right(response.right().value());
796 verifyValuesAreIdentical(serviceUpdate.getInvariantUUID(), currentService.getInvariantUUID(), "invariantUUID");
798 validateAndUpdateEcompNaming(currentService, serviceUpdate);
800 currentService.setEnvironmentContext(serviceUpdate.getEnvironmentContext());
801 return Either.left(currentService);
803 } catch (ComponentException exception) {
804 ResponseFormat responseFormat = componentsUtils.getResponseFormat(exception);
805 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate,
806 AuditingActionEnum.UPDATE_SERVICE_METADATA, ComponentTypeEnum.SERVICE);
807 return Either.right(responseFormat);
811 private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
812 if (updatedValue != null && !updatedValue.equals(originalValue)) {
813 log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
817 private void validateAndUpdateEcompNaming(Service currentService, Service serviceUpdate) {
818 Boolean isEcompGeneratedCurr = currentService.isEcompGeneratedNaming();
819 Boolean isEcompGeneratedUpdate = serviceUpdate.isEcompGeneratedNaming();
820 if (isEcompGeneratedUpdate != null && !isEcompGeneratedUpdate.equals(isEcompGeneratedCurr)) {
821 currentService.setEcompGeneratedNaming(isEcompGeneratedUpdate);
823 String namingPolicyUpdate = serviceUpdate.getNamingPolicy();
824 if (currentService.isEcompGeneratedNaming()) {
825 currentService.setNamingPolicy(namingPolicyUpdate);
827 if (!StringUtils.isEmpty(namingPolicyUpdate)) {
828 log.warn("NamingPolicy must be empty for EcompGeneratedNaming=false");
830 currentService.setNamingPolicy("");
834 private Either<Boolean, ResponseFormat> validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
835 String contactIdUpdated = serviceUpdate.getContactId();
836 String contactIdCurrent = currentService.getContactId();
837 if (!contactIdCurrent.equals(contactIdUpdated)) {
838 validateContactId(user, serviceUpdate, audatingAction);
839 currentService.setContactId(contactIdUpdated.toLowerCase());
841 return Either.left(true);
844 private Either<Boolean, ResponseFormat> validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
845 List<String> tagsUpdated = serviceUpdate.getTags();
846 List<String> tagsCurrent = currentService.getTags();
847 if (tagsUpdated == null || tagsUpdated.isEmpty()) {
848 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS);
849 componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, audatingAction, ComponentTypeEnum.SERVICE);
850 return Either.right(responseFormat);
853 if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) {
854 validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction);
855 currentService.setTags(tagsUpdated);
857 return Either.left(true);
860 private Either<Boolean, ResponseFormat> validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
861 String descriptionUpdated = serviceUpdate.getDescription();
862 String descriptionCurrent = currentService.getDescription();
863 if (!descriptionCurrent.equals(descriptionUpdated)) {
864 validateDescriptionAndCleanup(user, serviceUpdate, audatingAction);
865 currentService.setDescription(serviceUpdate.getDescription());
867 return Either.left(true);
870 private Either<Boolean, ResponseFormat> validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) {
871 String projectCodeUpdated = serviceUpdate.getProjectCode();
872 String projectCodeCurrent = currentService.getProjectCode();
873 if (!projectCodeCurrent.equals(projectCodeUpdated)) {
875 Either<Boolean, ResponseFormat> validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction);
876 if (validatProjectCodeResponse.isRight()) {
877 ResponseFormat errorRespons = validatProjectCodeResponse.right().value();
878 return Either.right(errorRespons);
880 currentService.setProjectCode(projectCodeUpdated);
883 return Either.left(true);
886 private Either<Boolean, ResponseFormat> validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
887 String iconUpdated = serviceUpdate.getIcon();
888 String iconCurrent = currentService.getIcon();
889 if (!iconCurrent.equals(iconUpdated)) {
890 if (!hasBeenCertified) {
891 validateIcon(user, serviceUpdate, audatingAction);
892 currentService.setIcon(iconUpdated);
894 log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated);
895 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED);
896 return Either.right(errorResponse);
899 return Either.left(true);
902 private Either<Boolean, ResponseFormat> validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum auditingAction) {
903 String serviceNameUpdated = serviceUpdate.getName();
904 String serviceNameCurrent = currentService.getName();
905 if (!serviceNameCurrent.equals(serviceNameUpdated)) {
906 if (!hasBeenCertified) {
907 validateComponentName(user, serviceUpdate, auditingAction);
908 Either<Boolean, ResponseFormat> serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, auditingAction);
909 if (serviceNameUniquenessValidation.isRight()) {
910 return serviceNameUniquenessValidation;
912 currentService.setName(serviceNameUpdated);
913 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated));
914 currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated));
917 log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated);
918 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED);
919 return Either.right(errorResponse);
922 return Either.left(true);
925 private void validateAndUpdateServiceType(Service currentService, Service updatedService) {
926 String updatedServiceType = updatedService.getServiceType();
927 String currentServiceType = currentService.getServiceType();
928 if (!currentServiceType.equals(updatedServiceType)) {
929 validateServiceTypeAndCleanup(updatedService);
930 currentService.setServiceType(updatedServiceType);
934 private void validateServiceTypeAndCleanup(Component component) {
935 log.debug("validate service type");
936 String serviceType = ((Service)component).getServiceType();
937 if (serviceType == null) {
938 log.info("service type is not valid.");
939 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
941 serviceType = cleanUpText(serviceType);
942 validateServiceType(serviceType);
946 private void validateServiceType(String serviceType) {
947 if (serviceType.isEmpty()) {
950 if (!ValidationUtils.validateServiceTypeLength(serviceType)) {
951 log.info("service type exceeds limit.");
952 throw new ComponentException(ActionStatus.SERVICE_TYPE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_TYPE_MAX_LENGTH);
954 if (!ValidationUtils.validateIsEnglish(serviceType)) {
955 log.info("service type is not valid.");
956 throw new ComponentException(ActionStatus.INVALID_SERVICE_TYPE);
960 private Either<Boolean, ResponseFormat> validateAndUpdateServiceRole(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
961 String updatedServiceRole = updatedService.getServiceRole();
962 String currentServiceRole = currentService.getServiceRole();
963 if (!currentServiceRole.equals(updatedServiceRole)) {
964 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRoleAndCleanup(user, updatedService , auditingAction);
965 if (validateServiceRole.isRight()) {
966 ResponseFormat errorResponse = validateServiceRole.right().value();
967 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
968 return Either.right(errorResponse);
970 currentService.setServiceRole(updatedServiceRole);
972 return Either.left(true);
975 protected Either<Boolean, ResponseFormat> validateServiceRoleAndCleanup(User user, Component component, AuditingActionEnum actionEnum) {
976 log.debug("validate service role");
977 String serviceRole = ((Service)component).getServiceRole();
978 if (serviceRole != null){
979 serviceRole = cleanUpText(serviceRole);
981 Either<Boolean, ResponseFormat> validateServiceRole = validateServiceRole(serviceRole);
982 if (validateServiceRole.isRight()) {
983 ResponseFormat responseFormat = validateServiceRole.right().value();
984 componentsUtils.auditComponentAdmin(responseFormat, user, component, actionEnum, ComponentTypeEnum.SERVICE);
985 return Either.right(responseFormat);
987 return Either.left(true);
989 return Either.left(false);
993 private Either<Boolean, ResponseFormat> validateAndUpdateInstantiationTypeValue(User user, Service currentService, Service updatedService, AuditingActionEnum auditingAction) {
994 String updatedInstaType= updatedService.getInstantiationType();
995 String currentInstaType = currentService.getInstantiationType();
996 if (!currentInstaType.equals(updatedInstaType)) {
997 Either<Boolean, ResponseFormat> validateInstantiationType = validateInstantiationTypeValue(user, updatedService , auditingAction);
998 if (validateInstantiationType.isRight()) {
999 ResponseFormat errorResponse = validateInstantiationType.right().value();
1000 componentsUtils.auditComponentAdmin(errorResponse, user, updatedService, auditingAction, ComponentTypeEnum.SERVICE);
1001 return Either.right(errorResponse);
1003 currentService.setInstantiationType(updatedInstaType);
1005 return Either.left(true);
1008 private Either<Boolean, ResponseFormat> validateInstantiationTypeValue(User user, Service service, AuditingActionEnum actionEnum) {
1009 log.debug("validate instantiation type");
1010 String instantiationType = service.getInstantiationType();
1011 if (!InstantiationTypes.containsName(instantiationType) || instantiationType == null){
1012 log.error("Recieved Instantiation type {} is not valid.", instantiationType);
1013 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_INSTANTIATION_TYPE);
1014 componentsUtils.auditComponentAdmin(errorResponse, user, service, actionEnum, ComponentTypeEnum.SERVICE);
1015 return Either.right(errorResponse);
1017 return Either.left(true);
1020 private Either<Boolean, ResponseFormat> validateServiceRole(String serviceRole) {
1021 if (serviceRole.equals("")){
1022 return Either.left(true);
1024 if (!ValidationUtils.validateServiceRoleLength(serviceRole)) {
1025 log.info("service role exceeds limit.");
1026 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ROLE_EXCEEDS_LIMIT, "" + ValidationUtils.SERVICE_ROLE_MAX_LENGTH);
1027 return Either.right(errorResponse);
1030 if (!ValidationUtils.validateIsEnglish(serviceRole)) {
1031 log.info("service role is not valid.");
1032 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_ROLE);
1033 return Either.right(errorResponse);
1035 return Either.left(true);
1039 private Either<Boolean, ResponseFormat> validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) {
1040 List<CategoryDefinition> categoryUpdated = serviceUpdate.getCategories();
1041 List<CategoryDefinition> categoryCurrent = currentService.getCategories();
1042 Either<Boolean, ResponseFormat> validateCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction);
1043 if (validateCategoryResponse.isRight()) {
1044 return Either.right(validateCategoryResponse.right().value());
1046 if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) {
1047 if (!hasBeenCertified) {
1048 currentService.setCategories(categoryUpdated);
1050 log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated);
1051 ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED);
1052 return Either.right(errorResponse);
1055 return Either.left(true);
1059 private Either<Boolean, ResponseFormat> validateServiceCategory(List<CategoryDefinition> list) {
1061 if (list.size() > 1) {
1062 log.debug("Must be only one category for service");
1063 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue());
1064 return Either.right(responseFormat);
1066 CategoryDefinition category = list.get(0);
1067 if (category.getSubcategories() != null) {
1068 log.debug("Subcategories cannot be defined for service");
1069 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY);
1070 return Either.right(responseFormat);
1072 if (!ValidationUtils.validateStringNotEmpty(category.getName())) {
1073 log.debug("Resource category is empty");
1074 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue());
1075 return Either.right(responseFormat);
1078 log.debug("validating service category {} against valid categories list", list);
1079 Either<List<CategoryDefinition>, ActionStatus> categorys = elementDao.getAllServiceCategories();
1080 if (categorys.isRight()) {
1081 log.debug("failed to retrive service categories from Titan");
1082 ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value());
1083 return Either.right(responseFormat);
1085 List<CategoryDefinition> categoryList = categorys.left().value();
1086 for (CategoryDefinition value : categoryList) {
1087 if (value.getName().equals(category.getName())) {
1088 return Either.left(true);
1091 log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList);
1092 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
1094 return Either.left(false);
1097 public Either<ServiceRelations, ResponseFormat> getServiceComponentsRelations(String serviceId, User user) {
1098 Either<Service, ResponseFormat> serviceResponseFormatEither = getService(serviceId, user);
1099 if (serviceResponseFormatEither.isRight()){
1100 return Either.right(serviceResponseFormatEither.right().value());
1102 final ServiceRelations serviceRelations = new ForwardingPathUtils().convertServiceToServiceRelations(serviceResponseFormatEither.left().value());
1103 return Either.left(serviceRelations);
1108 public ResponseFormat deleteService(String serviceId, User user) {
1109 ResponseFormat responseFormat;
1110 String ecompErrorContext = "delete service";
1112 validateUserExists(user, ecompErrorContext, false);
1113 Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
1114 if (serviceStatus.isRight()) {
1115 log.debug("failed to get service {}", serviceId);
1116 return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), "");
1119 Service service = serviceStatus.left().value();
1121 StorageOperationStatus result = StorageOperationStatus.OK;
1122 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1123 if (lockResult.isRight()) {
1124 return lockResult.right().value();
1127 result = markComponentToDelete(service);
1128 if (result.equals(StorageOperationStatus.OK)) {
1129 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1131 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1132 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1134 return responseFormat;
1136 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1137 log.warn("operation failed. do rollback");
1138 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1139 titanDao.rollback();
1141 log.debug("operation success. do commit");
1144 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1148 public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) {
1149 ResponseFormat responseFormat;
1150 String ecompErrorContext = "delete service";
1151 validateUserNotEmpty(user, ecompErrorContext);
1152 user = validateUserExists(user, ecompErrorContext, false);
1154 Either<Service, ResponseFormat> getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId());
1155 if (getResult.isRight()) {
1156 return getResult.right().value();
1158 Service service = getResult.left().value();
1160 StorageOperationStatus result = StorageOperationStatus.OK;
1161 Either<Boolean, ResponseFormat> lockResult = lockComponent(service, "Mark service to delete");
1162 if (lockResult.isRight()) {
1163 result = StorageOperationStatus.GENERAL_ERROR;
1164 return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1168 result = markComponentToDelete(service);
1169 if (result.equals(StorageOperationStatus.OK)) {
1170 responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT);
1172 ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result);
1173 responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName());
1175 return responseFormat;
1178 if (result == null || !result.equals(StorageOperationStatus.OK)) {
1179 log.warn("operation failed. do rollback");
1180 BeEcompErrorManager.getInstance().logBeSystemError("Delete Service");
1181 titanDao.rollback();
1183 log.debug("operation success. do commit");
1186 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
1190 public Either<Service, ResponseFormat> getService(String serviceId, User user) {
1191 String ecompErrorContext = "Get service";
1192 validateUserNotEmpty(user, ecompErrorContext);
1193 validateUserExists(user, ecompErrorContext, false);
1195 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1196 if (storageStatus.isRight()) {
1197 log.debug("failed to get service by id {}", serviceId);
1198 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId));
1201 if(!(storageStatus.left().value() instanceof Service)){
1202 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND), serviceId));
1204 Service service = storageStatus.left().value();
1205 return Either.left(service);
1212 public Either<Service, ResponseFormat> getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) {
1213 validateUserExists(userId, "get Service By Name And Version", false);
1214 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getComponentByNameAndVersion(ComponentTypeEnum.SERVICE, serviceName, serviceVersion);
1215 if (storageStatus.isRight()) {
1216 log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion);
1217 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName));
1219 Service service = storageStatus.left().value();
1220 return Either.left(service);
1223 @SuppressWarnings("unchecked")
1224 private void createMandatoryArtifactsData(Service service, User user) {
1225 // create mandatory artifacts
1227 // TODO it must be removed after that artifact uniqueId creation will be
1228 // moved to ArtifactOperation
1229 String serviceUniqueId = service.getUniqueId();
1230 Map<String, ArtifactDefinition> artifactMap = service.getArtifacts();
1231 if (artifactMap == null)
1232 artifactMap = new HashMap<>();
1234 Map<String, Object> informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts();
1235 List<String> exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory();
1237 String category = service.getCategories().get(0).getName();
1238 boolean isCreateArtifact = true;
1239 if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) {
1240 for (String exlude : exludeServiceCategory) {
1241 if (exlude.equalsIgnoreCase(category)) {
1242 isCreateArtifact = false;
1249 if (informationalServiceArtifacts != null && isCreateArtifact) {
1250 Set<String> keys = informationalServiceArtifacts.keySet();
1251 for (String informationalServiceArtifactName : keys) {
1252 Map<String, Object> artifactInfoMap = (Map<String, Object>) informationalServiceArtifacts.get(informationalServiceArtifactName);
1253 ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false);
1254 artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition);
1258 service.setArtifacts(artifactMap);
1262 private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map<String, Object> artifactInfoMap, User user, Boolean isServiceApi) {
1264 ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL);
1267 artifactInfo.setMandatory(false);
1268 artifactInfo.setServiceApi(true);
1270 return artifactInfo;
1273 private Either<DistributionTransitionEnum, ResponseFormat> validateTransitionEnum(String distributionTransition) {
1274 DistributionTransitionEnum transitionEnum = null;
1276 transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition);
1277 if (transitionEnum == null) {
1278 BeEcompErrorManager.getInstance().logBeSystemError(CHANGE_SERVICE_DISTRIBUTION);
1279 log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString());
1280 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1281 return Either.right(error);
1284 return Either.left(transitionEnum);
1287 private Either<String, ResponseFormat> validateComment(LifecycleChangeInfoWithAction comment) {
1288 String data = comment.getUserRemarks();
1290 if (data == null || data.trim().isEmpty()) {
1291 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1292 log.debug("user comment cannot be empty or null.");
1293 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1295 data = ValidationUtils.removeNoneUtf8Chars(data);
1296 data = ValidationUtils.removeHtmlTags(data);
1297 data = ValidationUtils.normaliseWhitespace(data);
1298 data = ValidationUtils.stripOctets(data);
1300 if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) {
1301 BeEcompErrorManager.getInstance().logBeInvalidJsonInput(CHANGE_SERVICE_DISTRIBUTION);
1302 log.debug("user comment exceeds limit.");
1303 return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH)));
1305 if (!ValidationUtils.validateIsEnglish(data)) {
1306 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
1308 return Either.left(data);
1311 private Either<Service, ResponseFormat> validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) {
1312 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
1313 if (storageStatus.isRight()) {
1314 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId);
1315 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1316 componentsUtils.auditComponent(responseFormat, user, auditAction, new ResourceCommonInfo(serviceId, ComponentTypeEnum.SERVICE.getValue()), comment);
1317 return Either.right(responseFormat);
1319 Service service = storageStatus.left().value();
1321 if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) {
1322 log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId());
1323 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName());
1324 createAudit(user, auditAction, comment, service, responseFormat);
1325 return Either.right(responseFormat);
1327 return Either.left(service);
1330 private Either<User, ResponseFormat> validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) {
1331 log.debug("get user from DB");
1334 user = validateUser(user, "Activate Distribution", service, auditAction, false);
1335 // validate user role
1336 List<Role> roles = new ArrayList<>();
1337 roles.add(Role.ADMIN);
1338 roles.add(Role.GOVERNOR);
1339 roles.add(Role.OPS);
1340 validateUserRole(user, service, roles, auditAction, comment);
1341 return Either.left(user);
1344 private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) {
1345 log.debug(AUDIT_BEFORE_SENDING_RESPONSE);
1346 componentsUtils.auditComponent(responseFormat, user, component, auditAction, new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1347 ResourceVersionInfo.newBuilder()
1348 .state(component.getLifecycleState().name())
1349 .version(component.getVersion())
1354 private String getEnvNameFromConfiguration() {
1355 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1356 log.trace("Update environment name to be {}", configuredEnvName);
1357 return configuredEnvName;
1360 public Either<String, ResponseFormat> activateServiceOnTenantEnvironment(String serviceId, String envId, User modifier, ServiceDistributionReqInfo data) {
1362 Either<ActivationRequestInformation, ResponseFormat> activationRequestInformationEither = serviceDistributionValidation.validateActivateServiceRequest(serviceId, envId, modifier, data);
1363 if (activationRequestInformationEither.isRight()) {
1364 return Either.right(activationRequestInformationEither.right().value());
1367 ActivationRequestInformation activationRequestInformation = activationRequestInformationEither.left().value();
1369 Either<String, ResponseFormat> result = null;
1370 String did = ThreadLocalsHolder.getUuid();
1371 Service service = activationRequestInformation.getServiceToActivate();
1372 result = buildAndSendServiceNotification(service, envId, did, activationRequestInformation.getWorkloadContext(), modifier);
1376 public Either<String, ResponseFormat> buildAndSendServiceNotification(Service service, String envId, String did, String workloadContext, User modifier) {
1377 String envName = getEnvNameFromConfiguration();
1378 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, workloadContext);
1379 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envId, envName, modifier);
1380 if (notifyServiceResponse == ActionStatus.OK) {
1381 return Either.left(did);
1383 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1384 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1385 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.INVALID_RESPONSE_FROM_PROXY);
1386 return Either.right(error);
1390 public Either<Service, ResponseFormat> activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) {
1392 User user = validateUserExists(modifier.getUserId(), "activate Distribution", false);
1393 Either<Service, ResponseFormat> result = null;
1394 ResponseFormat response = null;
1395 Service updatedService = null;
1396 String did = ThreadLocalsHolder.getUuid();
1398 String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0);
1399 if (configuredEnvName != null && !configuredEnvName.equals(envName)) {
1400 log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
1401 envName = configuredEnvName;
1405 ServletContext servletContext = request.getSession().getServletContext();
1406 boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
1407 if (!isDistributionEngineUp) {
1408 BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
1409 log.debug("Distribution Engine is DOWN");
1410 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1411 return Either.right(response);
1414 Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
1415 if (serviceRes.isRight()) {
1416 log.debug("failed retrieving service");
1417 response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId);
1418 componentsUtils.auditComponent(response, user, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1419 new ResourceCommonInfo(ComponentTypeEnum.SERVICE.getValue()),
1420 ResourceVersionInfo.newBuilder()
1423 return Either.right(response);
1425 Service service = serviceRes.left().value();
1426 String dcurrStatus = service.getDistributionStatus().name();
1427 String updatedStatus = dcurrStatus;
1428 StorageOperationStatus readyForDistribution = distributionEngine.isReadyForDistribution(envName);
1429 if (readyForDistribution.equals(StorageOperationStatus.OK)) {
1430 INotificationData notificationData = distributionEngine.buildServiceForDistribution(service, did, null);
1431 ActionStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user);
1432 if (notifyServiceResponse == ActionStatus.OK) {
1433 Either<Service, ResponseFormat> updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED);
1434 if (updateStateRes.isLeft() && updateStateRes.left().value() != null) {
1435 updatedService = updateStateRes.left().value();
1436 updatedStatus = updatedService.getDistributionStatus().name();
1438 // The response is not relevant
1439 updatedService = service;
1441 ASDCKpiApi.countActivatedDistribution();
1442 response = componentsUtils.getResponseFormat(ActionStatus.OK);
1443 result = Either.left(updatedService);
1445 BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification");
1446 log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse);
1447 response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
1448 result = Either.right(response);
1451 response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(readyForDistribution), envName);
1452 result = Either.right(response);
1454 componentsUtils.auditComponent(response, user, service, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST,
1455 new ResourceCommonInfo(service.getName(),ComponentTypeEnum.SERVICE.getValue()),
1456 ResourceVersionInfo.newBuilder()
1457 .distributionStatus(dcurrStatus)
1459 ResourceVersionInfo.newBuilder()
1460 .distributionStatus(updatedStatus)
1466 // convert to private after deletion of temp url
1467 public Either<Service, ResponseFormat> updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) {
1469 validateUserExists(user.getUserId(), "update Distribution Status For Activation", false);
1471 String serviceId = service.getUniqueId();
1472 Either<Boolean, ResponseFormat> lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation");
1473 if (lockResult.isRight()) {
1474 return Either.right(lockResult.right().value());
1477 Either<Service, StorageOperationStatus> result = toscaOperationFacade.updateDistributionStatus(service, user, state);
1478 if (result.isRight()) {
1479 titanDao.rollback();
1480 BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation");
1481 log.debug("service {} change distribution status failed", serviceId);
1482 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1485 return Either.left(result.left().value());
1487 graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
1491 public Either<Service, ResponseFormat> markDistributionAsDeployed(String serviceId, String did, User user) {
1493 validateUserExists(user.getUserId(), "mark Distribution As Deployed", false);
1494 log.debug("mark distribution deployed");
1496 AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY;
1497 Either<Service, StorageOperationStatus> getServiceResponse = toscaOperationFacade.getToscaElement(serviceId);
1498 if (getServiceResponse.isRight()) {
1499 BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId);
1500 log.debug("service {} not found", serviceId);
1501 ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), "");
1503 return Either.right(responseFormat);
1506 Service service = getServiceResponse.left().value();
1507 user = validateRoleForDeploy(did, user, auditAction, service);
1508 return checkDistributionAndDeploy(did, user, auditAction, service);
1512 public Either<Service, ResponseFormat> generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1513 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = ri ->
1514 // Only one VF Module Artifact per instance - add it to a list of one
1515 buildArtifactGenList(service, modifier, shouldLock, inTransaction, ri);
1517 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1521 private List<ArtifactGenerator<ArtifactDefinition>> buildArtifactGenList(Service service, User modifier, boolean shouldLock, boolean inTransaction, ComponentInstance ri) {
1522 List<ArtifactGenerator<ArtifactDefinition>> asList = new ArrayList<>();
1524 if (ri.getOriginType() == OriginTypeEnum.VF) {
1525 asList = Arrays.asList(new VfModuleArtifacGenerator(modifier, ri, service, shouldLock, inTransaction));
1530 private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
1531 Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
1532 if(currVF.getGroupInstances() != null){
1533 currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
1535 return currVF.getGroupInstances();
1538 private ArtifactDefinition getVfModuleInstArtifactForCompInstance(ComponentInstance currVF, Service service, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper) {
1539 ArtifactDefinition vfModuleAertifact = null;
1540 if (MapUtils.isNotEmpty(currVF.getDeploymentArtifacts())) {
1541 Optional<ArtifactDefinition> optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny();
1542 if (optionalVfModuleArtifact.isPresent()) {
1543 vfModuleAertifact = optionalVfModuleArtifact.get();
1546 if (vfModuleAertifact == null) {
1547 Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact = createVfModuleArtifact(currVF, service, payloadWrapper.getInnerElement());
1548 if (createVfModuleArtifact.isLeft()) {
1549 vfModuleAertifact = createVfModuleArtifact.left().value();
1551 responseWrapper.setInnerElement(createVfModuleArtifact.right().value());
1554 return vfModuleAertifact;
1557 private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
1558 List<VfModuleArtifactPayload> vfModulePayloads = new ArrayList<>();
1559 if (groupsForCurrVF != null) {
1560 for (GroupInstance groupInstance : groupsForCurrVF) {
1561 VfModuleArtifactPayload modulePayload = new VfModuleArtifactPayload(groupInstance);
1562 vfModulePayloads.add(modulePayload);
1564 vfModulePayloads.sort(VfModuleArtifactPayload::compareByGroupName);
1566 final Gson gson = new GsonBuilder().setPrettyPrinting().create();
1568 String vfModulePayloadString = gson.toJson(vfModulePayloads);
1569 payloadWrapper.setInnerElement(vfModulePayloadString);
1574 private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock, boolean inTransaction) {
1575 ArtifactDefinition vfModuleArtifact = null;
1576 Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
1577 Wrapper<String> payloadWrapper = new Wrapper<>();
1578 List<GroupInstance> groupsForCurrVF = collectGroupsInstanceForCompInstance(currVFInstance);
1579 if (responseWrapper.isEmpty()) {
1580 fillVfModuleInstHeatEnvPayload(groupsForCurrVF, payloadWrapper);
1582 if (responseWrapper.isEmpty() && payloadWrapper.getInnerElement() != null) {
1583 vfModuleArtifact = getVfModuleInstArtifactForCompInstance(currVFInstance, service, payloadWrapper, responseWrapper);
1585 if (responseWrapper.isEmpty() && vfModuleArtifact != null) {
1586 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper, responseWrapper, service);
1589 Either<ArtifactDefinition, ResponseFormat> result;
1590 if (responseWrapper.isEmpty()) {
1591 result = Either.left(vfModuleArtifact);
1593 result = Either.right(responseWrapper.getInnerElement());
1599 private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact, boolean shouldLock, boolean inTransaction, Wrapper<String> payloadWrapper, Wrapper<ResponseFormat> responseWrapper, Service service) {
1600 ArtifactDefinition result = null;
1601 Either<ArtifactDefinition, ResponseFormat> eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleArtifact, ComponentTypeEnum.RESOURCE_INSTANCE, service, currVF.getName(), modifier, shouldLock, inTransaction, System::currentTimeMillis,
1602 () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleArtifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8))), currVF.getUniqueId());
1603 if (eitherPayload.isLeft()) {
1604 result = eitherPayload.left().value();
1606 responseWrapper.setInnerElement(eitherPayload.right().value());
1608 if (result == null) {
1609 result = vfModuleArtifact;
1615 private Either<ArtifactDefinition, ResponseFormat> createVfModuleArtifact(ComponentInstance currVF, Service service, String vfModulePayloadString) {
1617 ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition();
1618 String newCheckSum = null;
1620 vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact");
1621 vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata");
1622 vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType());
1623 vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT);
1624 vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata");
1625 vfModuleArtifactDefinition.setTimeout(0);
1626 vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json");
1627 vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString);
1628 if (vfModulePayloadString != null) {
1629 newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(vfModulePayloadString.getBytes());
1631 vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
1633 Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent = artifactToscaOperation.addArifactToComponent(vfModuleArtifactDefinition, service.getUniqueId(), NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
1635 Either<ArtifactDefinition, ResponseFormat> result;
1636 if (addArifactToComponent.isLeft()) {
1637 result = Either.left(addArifactToComponent.left().value());
1639 result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value())));
1645 public Either<Service, ResponseFormat> generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock, boolean inTransaction) {
1647 Function<ComponentInstance, List<ArtifactGenerator<ArtifactDefinition>>> artifactTaskGeneratorCreator = resourceInstance ->
1648 // Get All Deployment Artifacts
1649 service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()).
1650 // Filter in Only Heat Env
1651 filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())).
1652 // Create ArtifactGenerator from those Artifacts
1653 map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock, inTransaction, resourceInstance.getUniqueId())).collect(Collectors.toList());
1655 return generateDeploymentArtifacts(service, artifactTaskGeneratorCreator);
1659 private <CallVal> Either<Service, ResponseFormat> generateDeploymentArtifacts(Service service, Function<ComponentInstance, List<ArtifactGenerator<CallVal>>> artifactTaskGeneratorCreator) {
1661 // Get Flat List of (Callable) ArtifactGenerator for all the RI in the
1663 if (service.getComponentInstances() != null) {
1664 List<ArtifactGenerator<CallVal>> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList());
1665 if (artifactGenList != null && !artifactGenList.isEmpty()) {
1666 for (ArtifactGenerator<CallVal> entry : artifactGenList) {
1667 Either<CallVal, ResponseFormat> callRes;
1669 callRes = entry.call();
1670 if (callRes.isRight()) {
1671 log.debug("Failed to generate artifact error : {}", callRes.right().value());
1672 return Either.right(callRes.right().value());
1674 } catch (Exception e) {
1675 log.debug("Failed to generate artifact exception : {}", e);
1676 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1681 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaFullElement(service.getUniqueId());
1682 if (storageStatus.isRight()) {
1683 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
1686 Service currentService = storageStatus.left().value();
1688 return Either.left(currentService);
1692 abstract class ArtifactGenerator<CallVal> implements Callable<Either<CallVal, ResponseFormat>> {
1696 class HeatEnvArtifactGenerator extends ArtifactGenerator<ArtifactDefinition> {
1697 ArtifactDefinition artifactDefinition;
1699 String resourceInstanceName;
1703 boolean inTransaction;
1705 HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock, boolean inTransaction, String instanceId) {
1706 this.artifactDefinition = artifactDefinition;
1707 this.service = service;
1708 this.resourceInstanceName = resourceInstanceName;
1709 this.modifier = modifier;
1710 this.shouldLock = shouldLock;
1711 this.instanceId = instanceId;
1712 this.inTransaction = inTransaction;
1716 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1717 return artifactsBusinessLogic.forceGenerateHeatEnvArtifact(artifactDefinition, ComponentTypeEnum.RESOURCE_INSTANCE, service, resourceInstanceName, modifier, shouldLock, inTransaction, instanceId);
1720 public ArtifactDefinition getArtifactDefinition() {
1721 return artifactDefinition;
1726 class VfModuleArtifacGenerator extends ArtifactGenerator<ArtifactDefinition> {
1728 private ComponentInstance componentInstance;
1729 private Service service;
1731 boolean inTransaction;
1734 public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
1735 return generateVfModuleInstanceArtifact(user, componentInstance, service, shouldLock, inTransaction);
1738 private VfModuleArtifacGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock, boolean inTransaction) {
1741 this.componentInstance = componentInstance;
1742 this.service = service;
1743 this.shouldLock = shouldLock;
1744 this.inTransaction = inTransaction;
1749 private synchronized Either<Service, ResponseFormat> checkDistributionAndDeploy(String distributionId, User user, AuditingActionEnum auditAction, Service service) {
1750 boolean isDeployed = isDistributionDeployed(distributionId);
1752 return Either.left(service);
1754 Either<Boolean, ResponseFormat> distributionSuccess = checkDistributionSuccess(distributionId, user, auditAction, service);
1755 if (distributionSuccess.isRight()) {
1756 return Either.right(distributionSuccess.right().value());
1759 log.debug("mark distribution {} as deployed - success", distributionId);
1760 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), distributionId, STATUS_DEPLOYED, "OK", user);
1761 return Either.left(service);
1764 private boolean isDistributionDeployed(String distributionId) {
1765 Either<List<DistributionDeployEvent>, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(distributionId, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED);
1767 boolean isDeployed = false;
1768 if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) {
1770 log.debug("distribution {} is already deployed", distributionId);
1776 protected Either<Boolean, ResponseFormat> checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) {
1778 log.trace("checkDistributionSuccess");
1779 // get all "DRequest" records for this distribution
1781 Either<List<ResourceAdminEvent>, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName());
1782 if (distRequestsResponse.isRight()) {
1783 ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value());
1784 return Either.right(error);
1787 List<ResourceAdminEvent> distributionRequests = distRequestsResponse.left().value();
1788 if (distributionRequests.isEmpty()) {
1789 BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did);
1790 log.info("distribution {} is not found", did);
1791 ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND);
1792 return Either.right(error);
1794 boolean isRequestSucceeded = false;
1795 for (ResourceAdminEvent event : distributionRequests) {
1796 String eventStatus = event.getStatus();
1797 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1798 isRequestSucceeded = true;
1803 // get all "DNotify" records for this distribution
1804 Either<List<DistributionNotificationEvent>, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName());
1805 if (distNotificationsResponse.isRight()) {
1806 ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value());
1807 return Either.right(error);
1810 List<DistributionNotificationEvent> distributionNotifications = distNotificationsResponse.left().value();
1811 boolean isNotificationsSucceeded = false;
1812 for (DistributionNotificationEvent event : distributionNotifications) {
1813 String eventStatus = event.getStatus();
1814 if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) {
1815 isNotificationsSucceeded = true;
1820 // if request failed OR there are notifications that failed
1821 if (!(isRequestSucceeded && isNotificationsSucceeded)) {
1823 log.info("distribution {} has failed", did);
1824 ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1825 auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did);
1826 return Either.right(error);
1828 return Either.left(true);
1831 private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) {
1833 ResponseFormat error = componentsUtils.getResponseFormat(status, params);
1834 String message = "";
1835 if (error.getMessageId() != null) {
1836 message = error.getMessageId() + ": ";
1838 message += error.getFormattedMessage();
1840 if (service != null) {
1841 componentsUtils.auditServiceDistributionDeployed(service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user);
1843 componentsUtils.auditServiceDistributionDeployed("", "", "", did, error.getStatus().toString(), message, user);
1848 private User validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) {
1849 Either<User, ActionStatus> eitherCreator = userAdmin.getUser(user.getUserId(), false);
1850 if (eitherCreator.isRight() || eitherCreator.left().value() == null) {
1851 BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId());
1852 log.debug("validateRoleForDeploy method - user is not listed. userId= {}", user.getUserId());
1853 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId());
1854 auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND);
1855 throw new ComponentException(ActionStatus.USER_NOT_FOUND, user.getUserId());
1857 user = eitherCreator.left().value();
1858 log.debug("validate user role");
1859 List<Role> roles = new ArrayList<>();
1860 roles.add(Role.ADMIN);
1861 roles.add(Role.OPS);
1863 validateUserRole(user, service, roles, auditAction, null);
1864 } catch (ComponentException e){
1865 log.info("role {} is not allowed to perform this action", user.getRole());
1866 auditDeployError(did, user, auditAction, service, e.getActionStatus());
1873 public void setDeploymentArtifactsPlaceHolder(Component component, User user) {
1878 public Either<List<String>, ResponseFormat> deleteMarkedComponents() {
1879 return deleteMarkedComponents(ComponentTypeEnum.SERVICE);
1882 private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) {
1883 WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR);
1884 WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context);
1885 return webApplicationContext.getBean(HealthCheckBusinessLogic.class);
1889 public ComponentInstanceBusinessLogic getComponentInstanceBL() {
1890 return componentInstanceBusinessLogic;
1894 public Either<List<ComponentInstance>, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, String userId) {
1896 validateUserExists(userId, "Get Component Instances", false);
1897 Either<Component, StorageOperationStatus> getComponentRes = toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
1898 if (getComponentRes.isRight()) {
1899 ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(getComponentRes.right().value()));
1900 return Either.right(responseFormat);
1903 List<ComponentInstance> componentInstances = getComponentRes.left().value().getComponentInstances();
1905 return Either.left(componentInstances);
1908 public ICacheMangerOperation getCacheManagerOperation() {
1909 return cacheManagerOperation;
1912 public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) {
1913 this.cacheManagerOperation = cacheManagerOperation;
1916 public void setForwardingPathOperation(ForwardingPathOperation forwardingPathOperation) {
1917 this.forwardingPathOperation = forwardingPathOperation;
1921 public void setToscaOperationFacade(ToscaOperationFacade toscaOperationFacade) {
1922 this.toscaOperationFacade = toscaOperationFacade;
1924 * updates group instance with new property values in case of successful update of group instance related component instance will be updated with new modification time and related service will be updated with new last update date
1927 public Either<List<GroupInstanceProperty>, ResponseFormat> updateGroupInstancePropertyValues(User modifier, String serviceId, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
1929 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
1930 Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponentRes;
1931 Component component = null;
1932 Either<Boolean, ResponseFormat> lockResult = null;
1933 log.debug("Going to update group instance {} of service {} with new property values. ", groupInstanceId, serviceId);
1935 validateUserAndComponentRes = validateUserAndComponent(serviceId, modifier);
1936 if (validateUserAndComponentRes.isRight()) {
1937 log.debug("Cannot update group instance {} of service {} with new property values. Validation failed. ", groupInstanceId, serviceId);
1938 actionResult = Either.right(validateUserAndComponentRes.right().value());
1940 if (actionResult == null) {
1941 component = validateUserAndComponentRes.left().value().getKey();
1942 lockResult = lockComponentByName(component.getSystemName(), component, "Update Group Instance on Service");
1943 if (lockResult.isRight()) {
1944 log.debug(FAILED_TO_LOCK_SERVICE_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage());
1945 actionResult = Either.right(lockResult.right().value());
1947 log.debug(THE_SERVICE_WITH_SYSTEM_NAME_LOCKED, component.getSystemName());
1950 if (actionResult == null) {
1951 actionResult = validateAndUpdateGroupInstancePropertyValuesAndContainingParents(component, componentInstanceId, groupInstanceId, newProperties);
1952 if (actionResult.isRight()) {
1953 log.debug("Failed to validate and update group instance {} property values and containing parents. The message is {}. ", groupInstanceId, actionResult.right().value().getFormattedMessage());
1956 } catch (Exception e) {
1957 log.error("Exception occured during update Group Instance property values: {}", e.getMessage(), e);
1958 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
1960 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
1961 graphLockOperation.unlockComponentByName(component.getSystemName(), component.getUniqueId(), NodeTypeEnum.Service);
1964 return actionResult;
1967 private Either<List<GroupInstanceProperty>, ResponseFormat> validateAndUpdateGroupInstancePropertyValuesAndContainingParents(Component component, String componentInstanceId, String groupInstanceId, List<GroupInstanceProperty> newProperties) {
1969 Either<List<GroupInstanceProperty>, ResponseFormat> actionResult = null;
1970 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceRes;
1971 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeRes;
1972 ComponentInstance relatedComponentInstance = null;
1973 GroupInstance oldGroupInstance = null;
1974 Either<GroupInstance, ResponseFormat> updateGroupInstanceResult = null;
1975 GroupInstance updatedGroupInstance = null;
1976 boolean inTransaction = true;
1977 findGroupInstanceRes = findGroupInstanceOnRelatedComponentInstance(component, componentInstanceId, groupInstanceId);
1978 if (findGroupInstanceRes.isRight()) {
1979 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Group instance {} not found. ", groupInstanceId);
1980 actionResult = Either.right(findGroupInstanceRes.right().value());
1982 if (actionResult == null) {
1983 oldGroupInstance = findGroupInstanceRes.left().value().getValue();
1984 relatedComponentInstance = findGroupInstanceRes.left().value().getKey();
1985 updateGroupInstanceResult = groupBusinessLogic.validateAndUpdateGroupInstancePropertyValues(component.getUniqueId(), componentInstanceId, oldGroupInstance, newProperties);
1986 if (updateGroupInstanceResult.isRight()) {
1987 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update group instance {} property values. ", oldGroupInstance.getName());
1988 actionResult = Either.right(updateGroupInstanceResult.right().value());
1991 if (actionResult == null) {
1992 updatedGroupInstance = updateGroupInstanceResult.left().value();
1993 if (!oldGroupInstance.getModificationTime().equals(updatedGroupInstance.getModificationTime())) {
1994 updateParentsModificationTimeRes = updateParentsModificationTimeAndCustomizationUuid(component, relatedComponentInstance, updatedGroupInstance, inTransaction);
1995 if (updateParentsModificationTimeRes.isRight()) {
1996 log.debug("#validateAndUpdateGroupInstancePropertyValuesAndContainingParents - Failed to update modification time for group instance {}. ", oldGroupInstance.getName());
1997 actionResult = Either.right(updateParentsModificationTimeRes.right().value());
2001 if (actionResult == null) {
2002 actionResult = Either.left(updatedGroupInstance.convertToGroupInstancesProperties());
2004 return actionResult;
2007 private Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> updateParentsModificationTimeAndCustomizationUuid(Component component, ComponentInstance relatedComponentInstance, GroupInstance updatedGroupInstance,
2008 boolean inTranscation) {
2010 Either<ImmutablePair<ComponentMetadataData, ComponentInstanceData>, ResponseFormat> actionResult;
2011 Either<ComponentMetadataData, StorageOperationStatus> serviceMetadataUpdateResult;
2012 Either<ComponentInstanceData, ResponseFormat> updateComponentInstanceRes = componentInstanceBusinessLogic.updateComponentInstanceModificationTimeAndCustomizationUuid(relatedComponentInstance, NodeTypeEnum.ResourceInstance,
2013 updatedGroupInstance.getModificationTime(), inTranscation);
2014 if (updateComponentInstanceRes.isRight()) {
2015 log.debug("Failed to update component instance {} after update of group instance {}. ", relatedComponentInstance.getName(), updatedGroupInstance.getName());
2016 actionResult = Either.right(updateComponentInstanceRes.right().value());
2018 serviceMetadataUpdateResult = toscaOperationFacade.updateComponentLastUpdateDateOnGraph(component);
2019 if (serviceMetadataUpdateResult.isRight()) {
2020 log.debug("Failed to update service {} after update of component instance {} with new property values of group instance {}. ", component.getName(), relatedComponentInstance.getName(), updatedGroupInstance.getName());
2021 actionResult = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceMetadataUpdateResult.right().value())));
2023 actionResult = Either.left(new ImmutablePair<>(serviceMetadataUpdateResult.left().value(), updateComponentInstanceRes.left().value()));
2026 return actionResult;
2029 private Either<ImmutablePair<Component, User>, ResponseFormat> validateUserAndComponent(String serviceId, User modifier) {
2031 Either<ImmutablePair<Component, User>, ResponseFormat> result = null;
2032 Either<Component, ResponseFormat> validateComponentExistsRes = null;
2033 User currUser = null;
2034 Component component = null;
2035 Either<User, ResponseFormat> validationUserResult = validateUserIgnoreAudit(modifier, "updateGroupInstancePropertyValues");
2036 if (validationUserResult.isRight()) {
2037 log.debug("#validateUserAndComponent - Failed to validate user with userId {}, for update service {}. ", modifier.getUserId(), serviceId);
2038 result = Either.right(validationUserResult.right().value());
2040 if (result == null) {
2041 currUser = validationUserResult.left().value();
2042 validateComponentExistsRes = validateComponentExists(serviceId, ComponentTypeEnum.SERVICE, null);
2043 if (validateComponentExistsRes.isRight()) {
2044 log.debug("#validateUserAndComponent - Failed to validate service existing {}. ", serviceId);
2045 result = Either.right(validateComponentExistsRes.right().value());
2048 if (result == null) {
2049 component = validateComponentExistsRes.left().value();
2050 if (!ComponentValidationUtils.canWorkOnComponent(component, currUser.getUserId())) {
2051 log.info("#validateUserAndComponent - Restricted operation for user: {}, on service: {}", currUser.getUserId(), component.getCreatorUserId());
2052 return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
2055 if (result == null) {
2056 result = Either.left(new ImmutablePair<>(component, currUser));
2061 private Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> findGroupInstanceOnRelatedComponentInstance(Component component, String componentInstanceId, String groupInstanceId) {
2063 Either<ImmutablePair<ComponentInstance, GroupInstance>, ResponseFormat> actionResult = null;
2064 GroupInstance groupInstance = null;
2065 ComponentInstance foundComponentInstance = findRelatedComponentInstance(component, componentInstanceId);
2066 if (foundComponentInstance == null) {
2067 log.debug("Component instance {} not found on service {}. ", componentInstanceId, component.getName());
2068 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstanceId, "resource instance", "service", component.getName()));
2070 else if (isNotEmpty(foundComponentInstance.getGroupInstances())) {
2071 groupInstance = foundComponentInstance.getGroupInstances().stream().filter(gi -> gi.getUniqueId().equals(groupInstanceId)).findFirst().orElse(null);
2072 if (groupInstance == null) {
2073 log.debug("Group instance {} not found on component instance {}. ", groupInstanceId, foundComponentInstance.getName());
2074 actionResult = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INSTANCE_NOT_FOUND_ON_COMPONENT_INSTANCE, groupInstanceId, foundComponentInstance.getName()));
2077 if (actionResult == null) {
2078 actionResult = Either.left(new ImmutablePair<>(foundComponentInstance, groupInstance));
2080 return actionResult;
2083 private ComponentInstance findRelatedComponentInstance(Component component, String componentInstanceId) {
2084 ComponentInstance componentInstance = null;
2085 if (isNotEmpty(component.getComponentInstances())) {
2086 componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getUniqueId().equals(componentInstanceId)).findFirst().orElse(null);
2088 return componentInstance;
2091 private Either<User, ResponseFormat> validateUserIgnoreAudit(User modifier, String ecompErrorContext) {
2092 User user = validateUser(modifier, ecompErrorContext, null, null, false);
2093 List<Role> roles = new ArrayList<>();
2094 roles.add(Role.ADMIN);
2095 roles.add(Role.DESIGNER);
2096 validateUserRole(user, roles);
2097 return Either.left(user);
2100 public Either<UiComponentDataTransfer, ResponseFormat> getUiComponentDataTransferByComponentId(String serviceId, List<String> dataParamsToReturn) {
2102 ComponentParametersView paramsToReturn = new ComponentParametersView(dataParamsToReturn);
2103 Either<Service, StorageOperationStatus> serviceResultEither = toscaOperationFacade.getToscaElement(serviceId, paramsToReturn);
2105 if (serviceResultEither.isRight()) {
2106 if(serviceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
2107 log.debug("#getUiComponentDataTransferByComponentId - Failed to find service with id {} ", serviceId);
2108 return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId));
2111 log.debug("#getUiComponentDataTransferByComponentId - failed to get service by id {} with filters {}", serviceId, dataParamsToReturn);
2112 return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(serviceResultEither.right().value()), ""));
2115 Service service = serviceResultEither.left().value();
2116 UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
2117 return Either.left(dataTransfer);
2120 public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
2121 Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
2122 User user = validateUserExists(userId, "Create service Filter", false);
2125 validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
2127 Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
2128 if (storageStatus.isRight()) {
2129 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2131 Service service = storageStatus.left().value();
2133 Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
2134 if (storageStatus.isRight()) {
2135 return Either.right(response.right().value());
2137 final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
2138 if (!optionalComponentInstance.isPresent() ){
2139 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2141 CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
2142 if (nodeFilter == null){
2143 return Either.left(resourceId);
2146 Either<String, StorageOperationStatus> result;
2148 Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
2149 if (lockResult.isRight()) {
2150 titanDao.rollback();
2151 return Either.right(componentsUtils.getResponseFormat(componentsUtils
2152 .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
2156 result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
2157 if (result.isRight()) {
2158 log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
2159 titanDao.rollback();
2160 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
2163 log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
2165 } catch (Exception e){
2166 log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
2167 titanDao.rollback();
2168 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2170 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2172 return Either.left(result.left().value());
2176 private Service initServiceToDeleteServiceFilter(String serviceId) {
2177 Service serviceToDelete = new Service();
2178 serviceToDelete.setUniqueId(serviceId);
2179 return serviceToDelete;
2183 public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
2184 String errorContext = "createIfNotAlreadyExistServiceFilter";
2185 User user = validateUserExists(userId, "Create service Filter", false);
2187 Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
2188 if (serviceEither.isRight()) {
2189 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
2191 final Service service = serviceEither.left().value();
2192 validateUserAndRole(service, user, errorContext);
2194 Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
2195 if (!optionalComponentInstance.isPresent()){
2196 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2198 ComponentInstance componentInstance = optionalComponentInstance.get();
2199 CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
2200 if (serviceFilter != null){
2201 return Either.left(serviceFilter);
2204 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2206 Either<Boolean, ResponseFormat> lockResult = null;
2209 lockComponent(service.getUniqueId(), service, "Create Service Filter");
2210 if (lockResult.isRight()) {
2211 log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
2212 lockResult.right().value().getFormattedMessage());
2213 return Either.right(lockResult.right().value());
2215 log.debug("The service with system name {} locked. ", service.getSystemName());
2218 CINodeFilterDataDefinition serviceFilterResult;
2220 result = serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
2221 if (result.isRight()) {
2222 titanDao.rollback();
2223 return Either.right(componentsUtils.getResponseFormat(
2224 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2227 serviceFilterResult = result.left().value();
2231 } catch (Exception e) {
2232 titanDao.rollback();
2233 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2235 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2238 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2239 graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
2242 return Either.left(serviceFilterResult);
2246 public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
2247 List<String> constraints, User inUser, boolean lock) {
2248 String errorContext = "createIfNotAlreadyExistServiceFilter";
2249 Either<?, ResponseFormat> eitherCreator1 = null;
2250 User user = validateUserExists(inUser, errorContext, true);
2251 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2252 if (eitherCreator1 != null && eitherCreator1.isRight()) {
2253 return Either.right(eitherCreator1.right().value());
2256 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2258 if(serviceStorageOperationStatusEither.isRight()){
2259 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2260 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2261 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2263 Service storedService = serviceStorageOperationStatusEither.left().value();
2265 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2266 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
2267 NodeFilterConstraintAction.UPDATE);
2268 if(booleanResponseFormatEither.isRight()){
2269 return Either.right(booleanResponseFormatEither.right().value());
2273 Either<Boolean, ResponseFormat> lockResult = null;
2276 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2277 if (lockResult.isRight()) {
2278 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2279 lockResult.right().value().getFormattedMessage());
2280 return Either.right(lockResult.right().value());
2282 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2285 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2286 if (!componentInstanceOptional.isPresent()){
2287 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2289 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2290 if(serviceFilter == null){
2291 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2293 CINodeFilterDataDefinition serviceFilterResult;
2295 List<RequirementNodeFilterPropertyDataDefinition> properties = (List<RequirementNodeFilterPropertyDataDefinition>) constraints.
2296 stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
2297 Either<CINodeFilterDataDefinition, StorageOperationStatus> result = serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
2299 if (result.isRight()) {
2300 titanDao.rollback();
2301 return Either.right(componentsUtils.getResponseFormat(
2302 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2305 serviceFilterResult = result.left().value();
2309 } catch (Exception e) {
2310 titanDao.rollback();
2311 log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
2313 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2316 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2317 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2320 return Either.left(serviceFilterResult);
2323 private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
2324 RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
2325 pdd.setConstraints(Arrays.asList(constraint));
2329 public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
2330 NodeFilterConstraintAction action, String constraint, int position, User inUser, boolean lock) {
2331 String errorContext = "createIfNotAlreadyExistServiceFilter";
2332 Either<?, ResponseFormat> eitherCreator1 = null;
2333 User user = validateUserExists(inUser, errorContext, true);
2334 validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
2335 if (eitherCreator1 != null && eitherCreator1.isRight()) {
2336 return Either.right(eitherCreator1.right().value());
2339 Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
2341 if(serviceStorageOperationStatusEither.isRight()){
2342 StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
2343 log.debug("Failed to fetch service information by service id, error {}", errorStatus);
2344 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
2346 Service storedService = serviceStorageOperationStatusEither.left().value();
2348 Either<Boolean, ResponseFormat> booleanResponseFormatEither =
2349 serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
2350 Collections.singletonList(constraint), action);
2351 if(booleanResponseFormatEither.isRight()){
2352 return Either.right(booleanResponseFormatEither.right().value());
2355 Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
2357 Either<Boolean, ResponseFormat> lockResult = null;
2360 lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
2361 if (lockResult.isRight()) {
2362 log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
2363 lockResult.right().value().getFormattedMessage());
2364 return Either.right(lockResult.right().value());
2366 log.debug("The service with system name {} locked. ", storedService.getSystemName());
2370 Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
2371 if (!componentInstanceOptional.isPresent()){
2372 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2374 CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
2375 if(serviceFilter == null){
2376 return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
2378 CINodeFilterDataDefinition serviceFilterResult;
2382 RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
2383 newProperty.setConstraints(Collections.singletonList(constraint));
2384 result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
2387 result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
2390 log.error("Unsupported operation "+action);
2391 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2395 if (result.isRight()) {
2396 titanDao.rollback();
2397 return Either.right(componentsUtils.getResponseFormat(
2398 componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
2401 serviceFilterResult = result.left().value();
2405 } catch (Exception e) {
2406 titanDao.rollback();
2407 log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
2409 return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
2412 if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
2413 graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
2416 return Either.left(serviceFilterResult);