Search in sources :

Example 1 with ServerErrorException

use of org.pmiops.workbench.exceptions.ServerErrorException in project workbench by all-of-us.

the class ProfileController method createFirecloudUserAndBillingProject.

private String createFirecloudUserAndBillingProject(User user) {
    try {
        // If the user is already registered, their profile will get updated.
        fireCloudService.registerUser(user.getContactEmail(), user.getGivenName(), user.getFamilyName());
    } catch (ApiException e) {
        log.log(Level.SEVERE, String.format("Error registering user: %s", e.getResponseBody()), e);
        // We don't expect this to happen.
        throw new ServerErrorException("Error registering user", e);
    }
    WorkbenchConfig workbenchConfig = workbenchConfigProvider.get();
    long suffix;
    if (workbenchEnvironment.isDevelopment()) {
        // For local development, make one billing project per account based on a hash of the account
        // email, and reuse it across database resets. (Assume we won't have any collisions;
        // if we discover that somebody starts using our namespace, change it up.)
        suffix = user.getEmail().hashCode();
    } else {
        // In other environments, create a suffix based on the user ID from the database. We will
        // add a suffix if that billing project is already taken. (If the database is reset, we
        // should consider switching the prefix.)
        suffix = user.getUserId();
    }
    // GCP billing project names must be <= 30 characters. The per-user hash, an integer,
    // is <= 10 chars.
    String billingProjectNamePrefix = workbenchConfig.firecloud.billingProjectPrefix + suffix;
    String billingProjectName = billingProjectNamePrefix;
    int numAttempts = 0;
    while (numAttempts < MAX_BILLING_PROJECT_CREATION_ATTEMPTS) {
        try {
            fireCloudService.createAllOfUsBillingProject(billingProjectName);
            break;
        } catch (ApiException e) {
            if (e.getCode() == HttpStatus.CONFLICT.value()) {
                if (workbenchEnvironment.isDevelopment()) {
                    // In local development, just re-use existing projects for the account. (We don't
                    // want to create a new billing project every time the database is reset.)
                    log.log(Level.WARNING, String.format("Project with name '%s' already exists; using it.", billingProjectName));
                    break;
                } else {
                    numAttempts++;
                    // In cloud environments, keep trying billing project names until we find one
                    // that hasn't been used before, or we hit MAX_BILLING_PROJECT_CREATION_ATTEMPTS.
                    billingProjectName = billingProjectNamePrefix + "-" + numAttempts;
                }
            } else {
                log.log(Level.SEVERE, String.format("Error creating billing project: %s", e.getResponseBody()), e);
                throw new ServerErrorException("Error creating billing project", e);
            }
        }
    }
    if (numAttempts == MAX_BILLING_PROJECT_CREATION_ATTEMPTS) {
        throw new ServerErrorException(String.format("Encountered %d billing project name " + "collisions; giving up", MAX_BILLING_PROJECT_CREATION_ATTEMPTS));
    }
    try {
        // If the user is already a member of the billing project, this will have no effect.
        fireCloudService.addUserToBillingProject(user.getEmail(), billingProjectName);
    } catch (ApiException e) {
        if (e.getCode() == HttpStatus.FORBIDDEN.value()) {
            // AofU is not the owner of the billing project. This should only happen in local
            // environments (and hopefully never, given the prefix we're using.) If it happens,
            // we may need to pick a different prefix.
            log.log(Level.SEVERE, String.format("Unable to add user to billing project %s: %s; " + "consider changing billing project prefix", billingProjectName, e.getResponseBody()), e);
            throw new ServerErrorException("Unable to add user to billing project", e);
        } else {
            log.log(Level.SEVERE, String.format("Error adding user to billing project: %s", e.getResponseBody()), e);
            throw new ServerErrorException("Error adding user to billing project", e);
        }
    }
    return billingProjectName;
}
Also used : WorkbenchConfig(org.pmiops.workbench.config.WorkbenchConfig) ServerErrorException(org.pmiops.workbench.exceptions.ServerErrorException) ApiException(org.pmiops.workbench.firecloud.ApiException)

Example 2 with ServerErrorException

use of org.pmiops.workbench.exceptions.ServerErrorException in project workbench by all-of-us.

the class WorkspacesController method getNoteBookList.

@Override
public ResponseEntity<List<FileDetail>> getNoteBookList(String workspaceNamespace, String workspaceId) {
    List<FileDetail> fileList = new ArrayList<>();
    try {
        org.pmiops.workbench.firecloud.model.Workspace fireCloudWorkspace = fireCloudService.getWorkspace(workspaceNamespace, workspaceId).getWorkspace();
        String bucketName = fireCloudWorkspace.getBucketName();
        fileList = getFilesFromNotebooks(bucketName);
    } catch (org.pmiops.workbench.firecloud.ApiException e) {
        if (e.getCode() == 404) {
            throw new NotFoundException(String.format("Workspace %s/%s not found", workspaceNamespace, workspaceId));
        }
        throw new ServerErrorException(e);
    }
    return ResponseEntity.ok(fileList);
}
Also used : FileDetail(org.pmiops.workbench.model.FileDetail) ArrayList(java.util.ArrayList) NotFoundException(org.pmiops.workbench.exceptions.NotFoundException) ApiException(org.pmiops.workbench.firecloud.ApiException) ServerErrorException(org.pmiops.workbench.exceptions.ServerErrorException)

Example 3 with ServerErrorException

use of org.pmiops.workbench.exceptions.ServerErrorException in project workbench by all-of-us.

the class ProfileControllerTest method testMe_userBeforeSuccessCloudProjectTooManyConflicts.

@Test
public void testMe_userBeforeSuccessCloudProjectTooManyConflicts() throws Exception {
    createUser();
    when(fireCloudService.isRequesterEnabledInFirecloud()).thenReturn(true);
    String projectName = BILLING_PROJECT_PREFIX + user.getUserId();
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName);
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName + "-1");
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName + "-2");
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName + "-3");
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName + "-4");
    try {
        cloudProfileController.getMe();
        fail("ServerErrorException expected");
    } catch (ServerErrorException e) {
    // expected
    }
    // When too many conflicts occur, the user doesn't have their project name set or first
    // sign in time.
    assertUser(PRIMARY_EMAIL, CONTACT_EMAIL, FAMILY_NAME, GIVEN_NAME, DataAccessLevel.UNREGISTERED, null, null);
    verify(fireCloudService).registerUser(CONTACT_EMAIL, GIVEN_NAME, FAMILY_NAME);
    verify(fireCloudService).createAllOfUsBillingProject(projectName);
    verify(fireCloudService).createAllOfUsBillingProject(projectName + "-1");
    verify(fireCloudService).createAllOfUsBillingProject(projectName + "-2");
    verify(fireCloudService).createAllOfUsBillingProject(projectName + "-3");
    verify(fireCloudService).createAllOfUsBillingProject(projectName + "-4");
}
Also used : ServerErrorException(org.pmiops.workbench.exceptions.ServerErrorException) ApiException(org.pmiops.workbench.firecloud.ApiException) DataJpaTest(org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest) Test(org.junit.Test)

Example 4 with ServerErrorException

use of org.pmiops.workbench.exceptions.ServerErrorException in project workbench by all-of-us.

the class FireCloudConfig method allOfUsApiClient.

@Bean(name = ALL_OF_US_API_CLIENT)
@RequestScope(proxyMode = ScopedProxyMode.DEFAULT)
public ApiClient allOfUsApiClient(WorkbenchEnvironment workbenchEnvironment, WorkbenchConfig workbenchConfig) {
    ApiClient apiClient = new ApiClient();
    try {
        apiClient.setAccessToken(getWorkbenchServiceAccountAccessToken(workbenchEnvironment));
        apiClient.setDebugging(workbenchConfig.firecloud.debugEndpoints);
    } catch (IOException e) {
        throw new ServerErrorException(e);
    }
    return apiClient;
}
Also used : IOException(java.io.IOException) ServerErrorException(org.pmiops.workbench.exceptions.ServerErrorException) RequestScope(org.springframework.web.context.annotation.RequestScope) Bean(org.springframework.context.annotation.Bean)

Example 5 with ServerErrorException

use of org.pmiops.workbench.exceptions.ServerErrorException in project workbench by all-of-us.

the class WorkspaceServiceImpl method updateUserRoles.

@Override
public Workspace updateUserRoles(Workspace workspace, Set<WorkspaceUserRole> userRoleSet) {
    Map<Long, WorkspaceUserRole> userRoleMap = new HashMap<Long, WorkspaceUserRole>();
    for (WorkspaceUserRole userRole : userRoleSet) {
        userRole.setWorkspace(workspace);
        userRoleMap.put(userRole.getUser().getUserId(), userRole);
    }
    ArrayList<WorkspaceACLUpdate> updateACLRequestList = new ArrayList<WorkspaceACLUpdate>();
    Iterator<WorkspaceUserRole> dbUserRoles = workspace.getWorkspaceUserRoles().iterator();
    while (dbUserRoles.hasNext()) {
        WorkspaceUserRole currentUserRole = dbUserRoles.next();
        WorkspaceUserRole mapValue = userRoleMap.get(currentUserRole.getUser().getUserId());
        if (mapValue != null) {
            currentUserRole.setRole(mapValue.getRole());
            userRoleMap.remove(currentUserRole.getUser().getUserId());
        } else {
            // This is how to remove a user from the FireCloud ACL:
            // Pass along an update request with NO ACCESS as the given access level.
            WorkspaceACLUpdate removedUser = new WorkspaceACLUpdate();
            removedUser.setEmail(currentUserRole.getUser().getEmail());
            removedUser.setCanCompute(false);
            removedUser.setCanShare(false);
            removedUser.setAccessLevel(WorkspaceAccessLevel.NO_ACCESS.toString());
            updateACLRequestList.add(removedUser);
            dbUserRoles.remove();
        }
    }
    for (Entry<Long, WorkspaceUserRole> remainingRole : userRoleMap.entrySet()) {
        workspace.getWorkspaceUserRoles().add(remainingRole.getValue());
    }
    for (WorkspaceUserRole currentWorkspaceUser : workspace.getWorkspaceUserRoles()) {
        WorkspaceACLUpdate currentUpdate = new WorkspaceACLUpdate();
        currentUpdate.setEmail(currentWorkspaceUser.getUser().getEmail());
        currentUpdate.setCanCompute(false);
        if (currentWorkspaceUser.getRole() == WorkspaceAccessLevel.OWNER) {
            currentUpdate.setCanShare(true);
            currentUpdate.setAccessLevel(WorkspaceAccessLevel.OWNER.toString());
        } else if (currentWorkspaceUser.getRole() == WorkspaceAccessLevel.WRITER) {
            currentUpdate.setCanShare(false);
            currentUpdate.setAccessLevel(WorkspaceAccessLevel.WRITER.toString());
        } else {
            currentUpdate.setCanShare(false);
            currentUpdate.setAccessLevel(WorkspaceAccessLevel.READER.toString());
        }
        updateACLRequestList.add(currentUpdate);
    }
    try {
        WorkspaceACLUpdateResponseList fireCloudResponse = fireCloudService.updateWorkspaceACL(workspace.getWorkspaceNamespace(), workspace.getFirecloudName(), updateACLRequestList);
        if (fireCloudResponse.getUsersNotFound().size() != 0) {
            String usersNotFound = "";
            for (int i = 0; i < fireCloudResponse.getUsersNotFound().size(); i++) {
                if (i > 0) {
                    usersNotFound += ", ";
                }
                usersNotFound += fireCloudResponse.getUsersNotFound().get(i).getEmail();
            }
            throw new BadRequestException(usersNotFound);
        }
    } catch (ApiException e) {
        if (e.getCode() == 400) {
            throw new BadRequestException(e.getResponseBody());
        } else if (e.getCode() == 404) {
            throw new NotFoundException("Workspace not found.");
        } else if (e.getCode() == 500) {
            throw new ServerErrorException(e);
        } else {
            throw new ServerUnavailableException(e);
        }
    }
    return this.saveWithLastModified(workspace);
}
Also used : HashMap(java.util.HashMap) WorkspaceACLUpdateResponseList(org.pmiops.workbench.firecloud.model.WorkspaceACLUpdateResponseList) ArrayList(java.util.ArrayList) ServerUnavailableException(org.pmiops.workbench.exceptions.ServerUnavailableException) NotFoundException(org.pmiops.workbench.exceptions.NotFoundException) WorkspaceUserRole(org.pmiops.workbench.db.model.WorkspaceUserRole) BadRequestException(org.pmiops.workbench.exceptions.BadRequestException) ServerErrorException(org.pmiops.workbench.exceptions.ServerErrorException) WorkspaceACLUpdate(org.pmiops.workbench.firecloud.model.WorkspaceACLUpdate) ApiException(org.pmiops.workbench.firecloud.ApiException)

Aggregations

ServerErrorException (org.pmiops.workbench.exceptions.ServerErrorException)10 ApiException (org.pmiops.workbench.firecloud.ApiException)7 NotFoundException (org.pmiops.workbench.exceptions.NotFoundException)4 ArrayList (java.util.ArrayList)3 BadRequestException (org.pmiops.workbench.exceptions.BadRequestException)3 WorkspaceUserRole (org.pmiops.workbench.db.model.WorkspaceUserRole)2 ServerUnavailableException (org.pmiops.workbench.exceptions.ServerUnavailableException)2 CloneWorkspaceResponse (org.pmiops.workbench.model.CloneWorkspaceResponse)2 BigQueryException (com.google.cloud.bigquery.BigQueryException)1 FieldValue (com.google.cloud.bigquery.FieldValue)1 QueryJobConfiguration (com.google.cloud.bigquery.QueryJobConfiguration)1 QueryResult (com.google.cloud.bigquery.QueryResult)1 Blob (com.google.cloud.storage.Blob)1 IOException (java.io.IOException)1 Timestamp (java.sql.Timestamp)1 HashMap (java.util.HashMap)1 Test (org.junit.Test)1 ParticipantCriteria (org.pmiops.workbench.cohortbuilder.ParticipantCriteria)1 TableQueryAndConfig (org.pmiops.workbench.cohortbuilder.TableQueryAndConfig)1 WorkbenchConfig (org.pmiops.workbench.config.WorkbenchConfig)1