Skip to content

Commit

Permalink
Create new ISV user service -> getServiceDetailsByIdForIsv
Browse files Browse the repository at this point in the history
  • Loading branch information
WangLiNaruto committed Nov 15, 2023
1 parent d634058 commit 4dddd23
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.xpanse.modules.deployment.DeployService;
Expand All @@ -23,13 +24,15 @@
import org.eclipse.xpanse.modules.models.service.common.enums.Csp;
import org.eclipse.xpanse.modules.models.service.deploy.enums.ServiceDeploymentState;
import org.eclipse.xpanse.modules.models.service.query.ServiceQueryModel;
import org.eclipse.xpanse.modules.models.service.view.ServiceDetailVo;
import org.eclipse.xpanse.modules.models.service.view.ServiceVo;
import org.eclipse.xpanse.modules.security.IdentityProviderManager;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
Expand Down Expand Up @@ -78,6 +81,22 @@ public List<ServiceVo> listDeployedServicesOfIsv(
return this.deployService.listDeployedServicesOfIsv(query);
}

/**
* Get details of the managed service by id for ISV role.
*
* @return Details of the managed service.
*/
@Tag(name = "Service", description = "APIs to manage the service instances")
@Operation(description = "Get deployed service details by id.")
@GetMapping(value = "/isv/services/{id}",
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.OK)
public ServiceDetailVo getServiceDetailsByIdForIsv(
@Parameter(name = "id", description = "Task id of deployed service")
@PathVariable("id") String id) {
return this.deployService.getServiceDetailsByIdForIsv(UUID.fromString(id));
}

private ServiceQueryModel getServiceQueryModel(Category category, Csp csp,
String serviceName, String serviceVersion, ServiceDeploymentState state) {
ServiceQueryModel query = new ServiceQueryModel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.InvalidDeploymentVariableException;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.InvalidServiceStateException;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.PluginNotFoundException;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.ServiceDetailsNotAccessible;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.ServiceNotDeployedException;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.TerraformBootRequestFailedException;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.TerraformExecutorException;
Expand Down Expand Up @@ -157,4 +158,16 @@ public Response handleVariableInvalidException(
return Response.errorResponse(ResultType.VARIABLE_VALIDATION_FAILED,
Collections.singletonList(ex.getMessage()));
}

/**
* Exception handler for ServiceDetailsNotAccessible.
*/
@ExceptionHandler({ServiceDetailsNotAccessible.class})
@ResponseStatus(HttpStatus.FORBIDDEN)
@ResponseBody
public Response handleServiceDetailsNotAccessible(
ServiceDetailsNotAccessible ex) {
return Response.errorResponse(ResultType.SERVICE_DETAILS_NOT_ACCESSIBLE,
Collections.singletonList(ex.getMessage()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.xpanse.modules.database.resource.DeployResourceEntity;
import org.eclipse.xpanse.modules.database.service.DeployServiceEntity;
import org.eclipse.xpanse.modules.models.service.deploy.DeployResource;
import org.eclipse.xpanse.modules.models.service.view.ServiceDetailVo;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

Expand Down Expand Up @@ -44,4 +46,27 @@ public static List<DeployResource> transResourceEntity(List<DeployResourceEntity
return resources;
}

/**
* DeployServiceEntity converted to ServiceDetailVo.
*
* @param deployServiceEntity DeployServiceEntity.
* @return serviceDetailVo
*/
public static ServiceDetailVo transDeployServiceEntityToServiceDetailVo(
DeployServiceEntity deployServiceEntity) {
ServiceDetailVo serviceDetailVo = new ServiceDetailVo();
serviceDetailVo.setServiceHostingType(
deployServiceEntity.getDeployRequest().getServiceHostingType());
BeanUtils.copyProperties(deployServiceEntity, serviceDetailVo);
if (!CollectionUtils.isEmpty(deployServiceEntity.getDeployResourceList())) {
List<DeployResource> deployResources = transResourceEntity(
deployServiceEntity.getDeployResourceList());
serviceDetailVo.setDeployResources(deployResources);
}
if (!CollectionUtils.isEmpty(deployServiceEntity.getProperties())) {
serviceDetailVo.setDeployedServiceProperties(deployServiceEntity.getProperties());
}
return serviceDetailVo;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.DeployerNotFoundException;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.InvalidServiceStateException;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.PluginNotFoundException;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.ServiceDetailsNotAccessible;
import org.eclipse.xpanse.modules.models.service.deploy.exceptions.ServiceNotDeployedException;
import org.eclipse.xpanse.modules.models.service.query.ServiceQueryModel;
import org.eclipse.xpanse.modules.models.service.utils.ServiceVariablesJsonSchemaValidator;
Expand All @@ -46,6 +47,7 @@
import org.eclipse.xpanse.modules.models.servicetemplate.DeployVariable;
import org.eclipse.xpanse.modules.models.servicetemplate.enums.DeployerKind;
import org.eclipse.xpanse.modules.models.servicetemplate.enums.SensitiveScope;
import org.eclipse.xpanse.modules.models.servicetemplate.enums.ServiceHostingType;
import org.eclipse.xpanse.modules.models.servicetemplate.exceptions.ServiceTemplateNotRegistered;
import org.eclipse.xpanse.modules.orchestrator.OrchestratorPlugin;
import org.eclipse.xpanse.modules.orchestrator.PluginManager;
Expand Down Expand Up @@ -281,19 +283,7 @@ private List<DeployResourceEntity> getDeployResourceEntityList(
*/
public Deployment getDestroyHandler(DeployTask deployTask) {
// Find the deployed service.
DeployServiceEntity deployServiceEntity =
deployServiceStorage.findDeployServiceById(deployTask.getId());
if (Objects.isNull(deployServiceEntity)
|| Objects.isNull(deployServiceEntity.getDeployRequest())) {
String errorMsg = String.format("Service with id %s not found.", deployTask.getId());
log.error(errorMsg);
throw new ServiceNotDeployedException(errorMsg);
}
Optional<String> userIdOptional = identityProviderManager.getCurrentLoginUserId();
if (!StringUtils.equals(userIdOptional.orElse(null), deployServiceEntity.getUserId())) {
throw new AccessDeniedException(
"No permissions to destroy services belonging to other users.");
}
DeployServiceEntity deployServiceEntity = getDeployServiceEntity(deployTask.getId());
// Get state of service.
ServiceDeploymentState state = deployServiceEntity.getServiceDeploymentState();
if (state.equals(ServiceDeploymentState.DEPLOYING)
Expand Down Expand Up @@ -324,13 +314,7 @@ public void asyncDestroyService(Deployment deployment, DeployTask deployTask) {

private void destroy(Deployment deployment, DeployTask deployTask) {
MDC.put(TASK_ID, deployTask.getId().toString());
DeployServiceEntity deployServiceEntity =
deployServiceStorage.findDeployServiceById(deployTask.getId());
if (Objects.isNull(deployServiceEntity)) {
String errorMsg = String.format("Service with id %s not found.", deployTask.getId());
log.error(errorMsg);
throw new ServiceNotDeployedException("Service with id %s not found.");
}
DeployServiceEntity deployServiceEntity = getDeployServiceEntity(deployTask.getId());
try {
deployServiceEntity.setServiceDeploymentState(ServiceDeploymentState.DESTROYING);
deployServiceStorage.storeAndFlush(deployServiceEntity);
Expand Down Expand Up @@ -450,45 +434,15 @@ public List<ServiceVo> listDeployedServices(ServiceQueryModel query) {
* @return serviceDetailVo
*/
public ServiceDetailVo getDeployServiceDetails(UUID id) {
DeployServiceEntity deployServiceEntity = deployServiceStorage.findDeployServiceById(id);
if (Objects.isNull(deployServiceEntity)) {
String errorMsg = String.format("Service with id %s not found.", id);
log.error(errorMsg);
throw new ServiceNotDeployedException(errorMsg);
}
Optional<String> userIdOptional = identityProviderManager.getCurrentLoginUserId();
if (!StringUtils.equals(userIdOptional.orElse(null), deployServiceEntity.getUserId())) {
throw new AccessDeniedException(
"No permissions to view details of services belonging to other users.");
}

ServiceDetailVo serviceDetailVo = new ServiceDetailVo();
serviceDetailVo.setServiceHostingType(
deployServiceEntity.getDeployRequest().getServiceHostingType());
BeanUtils.copyProperties(deployServiceEntity, serviceDetailVo);
if (!CollectionUtils.isEmpty(deployServiceEntity.getDeployResourceList())) {
List<DeployResource> deployResources =
EntityTransUtils.transResourceEntity(
deployServiceEntity.getDeployResourceList());
serviceDetailVo.setDeployResources(deployResources);
}
if (!CollectionUtils.isEmpty(deployServiceEntity.getProperties())) {
serviceDetailVo.setDeployedServiceProperties(deployServiceEntity.getProperties());
}
return serviceDetailVo;
DeployServiceEntity deployServiceEntity = getDeployServiceEntity(id);
return EntityTransUtils.transDeployServiceEntityToServiceDetailVo(deployServiceEntity);
}

/**
* Callback method after deployment is complete.
*/
public void deployCallback(String taskId, TerraformResult result) {
DeployServiceEntity deployServiceEntity =
deployServiceStorage.findDeployServiceById(UUID.fromString(taskId));
if (Objects.isNull(deployServiceEntity)) {
String errorMsg = String.format("Service with id %s not found.", taskId);
log.error(errorMsg);
throw new ServiceNotDeployedException(errorMsg);
}
DeployServiceEntity deployServiceEntity = getDeployServiceEntity(UUID.fromString(taskId));
DeployResult deployResult = handlerDeployResource(result);
if (StringUtils.isNotBlank(result.getTerraformState())) {
getResourceHandler(deployServiceEntity.getCsp()).handler(deployResult);
Expand Down Expand Up @@ -526,13 +480,7 @@ private DeployTask getDeployTask(String taskId, DeployServiceEntity deployServic
* Callback method after the service is destroyed.
*/
public void destroyCallback(String taskId, TerraformResult result) {
DeployServiceEntity deployServiceEntity =
deployServiceStorage.findDeployServiceById(UUID.fromString(taskId));
if (Objects.isNull(deployServiceEntity)) {
String errorMsg = String.format("Service with id %s not found.", taskId);
log.error(errorMsg);
throw new ServiceNotDeployedException(errorMsg);
}
DeployServiceEntity deployServiceEntity = getDeployServiceEntity(UUID.fromString(taskId));
if (Boolean.TRUE.equals(result.getCommandSuccessful())) {
deployServiceEntity.setServiceDeploymentState(ServiceDeploymentState.DESTROY_SUCCESS);
deployServiceEntity.setProperties(new HashMap<>());
Expand Down Expand Up @@ -709,4 +657,42 @@ public List<ServiceVo> listDeployedServicesOfIsv(ServiceQueryModel query) {
.equals(deployServiceEntity.getNamespace()))
.map(this::convertToServiceVo).toList();
}

/**
* Get deploy service detail by id.
*
* @param id ID of deploy service.
* @return serviceDetailVo
*/
public ServiceDetailVo getServiceDetailsByIdForIsv(UUID id) {
DeployServiceEntity deployServiceEntity = getDeployServiceEntity(id);
ServiceHostingType serviceHostingType =
deployServiceEntity.getDeployRequest().getServiceHostingType();
if (ServiceHostingType.SERVICE_VENDOR != serviceHostingType) {
String errorMsg = String.format("the details of Service with id %s no accessible", id);
log.error(errorMsg);
throw new ServiceDetailsNotAccessible(errorMsg);
}
Optional<String> namespace = identityProviderManager.getUserNamespace();
if (namespace.isEmpty() || !namespace.get().equals(deployServiceEntity.getNamespace())) {
throw new AccessDeniedException(
"No permissions to view details of services belonging to other users.");
}
return EntityTransUtils.transDeployServiceEntityToServiceDetailVo(deployServiceEntity);
}

private DeployServiceEntity getDeployServiceEntity(UUID id) {
DeployServiceEntity deployServiceEntity = deployServiceStorage.findDeployServiceById(id);
if (Objects.isNull(deployServiceEntity)) {
String errorMsg = String.format("Service with id %s not found.", id);
log.error(errorMsg);
throw new ServiceNotDeployedException(errorMsg);
}
Optional<String> userIdOptional = identityProviderManager.getCurrentLoginUserId();
if (!StringUtils.equals(userIdOptional.orElse(null), deployServiceEntity.getUserId())) {
throw new AccessDeniedException(
"No permissions to view details of services belonging to other users.");
}
return deployServiceEntity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ void testAsyncDestroyService() {
String stateFile = deployServiceEntity.getPrivateProperties().get(STATE_FILE_NAME);
when(deployServiceStorage.findDeployServiceById(uuid)).thenReturn(deployServiceEntity);
when(deploymentMock.destroy(deployTask, stateFile)).thenReturn(deployResult);

when(identityProviderManager.getCurrentLoginUserId()).thenReturn(Optional.of(userId));
deployService.asyncDestroyService(deploymentMock, deployTask);

// Verify the expected interactions
Expand All @@ -311,7 +311,7 @@ void testAsyncDestroyService() {
@Test
void testAsyncDestroyService_Exception() {
when(deployServiceStorage.findDeployServiceById(uuid)).thenReturn(deployServiceEntity);

when(identityProviderManager.getCurrentLoginUserId()).thenReturn(Optional.of(userId));
deployService.asyncDestroyService(deploymentMock, deployTask);

doThrow(new RuntimeException()).when(deployServiceStorage)
Expand Down Expand Up @@ -339,7 +339,7 @@ void testAsyncDestroyService_resourcesEmpty() {

when(deployServiceStorage.findDeployServiceById(uuid)).thenReturn(deployServiceEntity);
when(deploymentMock.destroy(deployTask, stateFile)).thenReturn(deployResult);

when(identityProviderManager.getCurrentLoginUserId()).thenReturn(Optional.of(userId));
deployService.asyncDestroyService(deploymentMock, deployTask);

// Verify the expected interactions
Expand All @@ -357,7 +357,7 @@ void testAsyncDestroyService_DESTROY_FAILED() {

when(deployServiceStorage.findDeployServiceById(uuid)).thenReturn(deployServiceEntity);
when(deploymentMock.destroy(deployTask, stateFile)).thenReturn(deployResult);

when(identityProviderManager.getCurrentLoginUserId()).thenReturn(Optional.of(userId));
deployService.asyncDestroyService(deploymentMock, deployTask);

// Verify the expected interactions
Expand Down Expand Up @@ -518,7 +518,7 @@ void testPurgeServiceSuccess() {
when(deployServiceStorage.findDeployServiceById(uuid)).thenReturn(deployServiceEntity);
String stateFile = deployServiceEntity.getPrivateProperties().get(STATE_FILE_NAME);
when(deploymentMock.destroy(deployTask, stateFile)).thenReturn(deployResult);

when(identityProviderManager.getCurrentLoginUserId()).thenReturn(Optional.of(userId));
deployService.purgeService(deploymentMock, deployTask);
// Verify the expected interactions
verify(deployServiceStorage, times(2)).findDeployServiceById(uuid);
Expand All @@ -542,7 +542,7 @@ void testAsyncPurgeServiceSuccess() {
when(deployServiceStorage.findDeployServiceById(uuid)).thenReturn(deployServiceEntity);
String stateFile = deployServiceEntity.getPrivateProperties().get(STATE_FILE_NAME);
when(deploymentMock.destroy(deployTask, stateFile)).thenReturn(deployResult);

when(identityProviderManager.getCurrentLoginUserId()).thenReturn(Optional.of(userId));
deployService.asyncPurgeService(deploymentMock, deployTask, deployServiceEntity);

// Verify the expected interactions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public enum ResultType {
POLICY_DUPLICATE("Duplicate Policy"),
POLICY_VALIDATION_FAILED("Policy Validation Failed"),
POLICY_EVALUATION_FAILED("Policy Evaluation Failed"),
USER_NO_LOGIN_EXCEPTION("Current Login User No Found");
USER_NO_LOGIN_EXCEPTION("Current Login User No Found"),
SERVICE_DETAILS_NOT_ACCESSIBLE("Service Details No Accessible");

private final String value;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* SPDX-License-Identifier: Apache-2.0
* SPDX-FileCopyrightText: Huawei Inc.
*/

package org.eclipse.xpanse.modules.models.service.deploy.exceptions;

/**
* Exception is thrown when ISV users query deployed service details by ID.
*/
public class ServiceDetailsNotAccessible extends RuntimeException {
public ServiceDetailsNotAccessible(String message) {
super(message);
}
}

0 comments on commit 4dddd23

Please sign in to comment.