Search in sources :

Example 1 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class ClusterController method localize.

@Override
public ResponseEntity<ClusterLocalizeResponse> localize(String projectName, String clusterName, ClusterLocalizeRequest body) {
    String workspaceBucket;
    try {
        workspaceBucket = "gs://" + fireCloudService.getWorkspace(body.getWorkspaceNamespace(), body.getWorkspaceId()).getWorkspace().getBucketName();
    } catch (ApiException e) {
        if (e.getCode() == 404) {
            log.log(Level.INFO, "Firecloud workspace not found", e);
            throw new NotFoundException(String.format("workspace %s/%s not found or not accessible", body.getWorkspaceNamespace(), body.getWorkspaceId()));
        }
        throw ExceptionUtils.convertFirecloudException(e);
    }
    // For the common case where the notebook cluster matches the workspace
    // namespace, simply name the directory as the workspace ID; else we
    // include the namespace in the directory name to avoid possible conflicts
    // in workspace IDs.
    String workspacePath = body.getWorkspaceId();
    if (!projectName.equals(body.getWorkspaceNamespace())) {
        workspacePath = body.getWorkspaceNamespace() + ":" + body.getWorkspaceId();
    }
    String apiDir = String.join("/", "workspaces", workspacePath);
    String localDir = String.join("/", "~", apiDir);
    Map<String, String> toLocalize = body.getNotebookNames().stream().collect(Collectors.<String, String, String>toMap(name -> localDir + "/" + name, name -> String.join("/", workspaceBucket, "notebooks", name)));
    // TODO(calbach): Localize a delocalize config JSON file as well, once Leo supports this.
    toLocalize.put(localDir + "/.all_of_us_config.json", workspaceBucket + "/" + WorkspacesController.CONFIG_FILENAME);
    notebooksService.localize(projectName, clusterName, toLocalize);
    ClusterLocalizeResponse resp = new ClusterLocalizeResponse();
    resp.setClusterLocalDirectory(apiDir);
    return ResponseEntity.ok(resp);
}
Also used : ExceptionUtils(org.pmiops.workbench.exceptions.ExceptionUtils) ClusterLocalizeResponse(org.pmiops.workbench.model.ClusterLocalizeResponse) Provider(javax.inject.Provider) ImmutableMap(com.google.common.collect.ImmutableMap) FireCloudService(org.pmiops.workbench.firecloud.FireCloudService) ClusterListResponse(org.pmiops.workbench.model.ClusterListResponse) Autowired(org.springframework.beans.factory.annotation.Autowired) HashMap(java.util.HashMap) ApiException(org.pmiops.workbench.firecloud.ApiException) Logger(java.util.logging.Logger) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) RestController(org.springframework.web.bind.annotation.RestController) Level(java.util.logging.Level) WorkbenchConfig(org.pmiops.workbench.config.WorkbenchConfig) ClusterLocalizeRequest(org.pmiops.workbench.model.ClusterLocalizeRequest) Map(java.util.Map) NotFoundException(org.pmiops.workbench.exceptions.NotFoundException) NotebooksService(org.pmiops.workbench.notebooks.NotebooksService) ResponseEntity(org.springframework.http.ResponseEntity) Cluster(org.pmiops.workbench.model.Cluster) ClusterStatus(org.pmiops.workbench.model.ClusterStatus) User(org.pmiops.workbench.db.model.User) ClusterLocalizeResponse(org.pmiops.workbench.model.ClusterLocalizeResponse) NotFoundException(org.pmiops.workbench.exceptions.NotFoundException) ApiException(org.pmiops.workbench.firecloud.ApiException)

Example 2 with ApiException

use of org.pmiops.workbench.firecloud.ApiException 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 3 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class ProfileController method getIdVerificationsForReview.

@Override
@AuthorityRequired({ Authority.REVIEW_ID_VERIFICATION })
public ResponseEntity<IdVerificationListResponse> getIdVerificationsForReview() {
    IdVerificationListResponse response = new IdVerificationListResponse();
    List<Profile> responseList = new ArrayList<Profile>();
    try {
        for (User user : userService.getNonVerifiedUsers()) {
            responseList.add(profileService.getProfile(user));
        }
    } catch (ApiException e) {
        log.log(Level.INFO, "Error calling FireCloud", e);
        return ResponseEntity.status(e.getCode()).build();
    }
    response.setProfileList(responseList);
    return ResponseEntity.ok(response);
}
Also used : IdVerificationListResponse(org.pmiops.workbench.model.IdVerificationListResponse) User(org.pmiops.workbench.db.model.User) ArrayList(java.util.ArrayList) Profile(org.pmiops.workbench.model.Profile) ApiException(org.pmiops.workbench.firecloud.ApiException) AuthorityRequired(org.pmiops.workbench.annotations.AuthorityRequired)

Example 4 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class AuthDomainController method addUserToAuthDomain.

@Override
@AuthorityRequired({ Authority.MANAGE_GROUP })
public ResponseEntity<Void> addUserToAuthDomain(String groupName, AuthDomainRequest request) {
    User user = userDao.findUserByEmail(request.getEmail());
    DataAccessLevel previousAccess = user.getDataAccessLevel();
    try {
        fireCloudService.addUserToGroup(request.getEmail(), groupName);
    } catch (ApiException e) {
        ExceptionUtils.convertFirecloudException(e);
    }
    // TODO(blrubenstein): Parameterize this.
    user.setDataAccessLevel(DataAccessLevel.REGISTERED);
    user.setDisabled(false);
    userDao.save(user);
    userService.logAdminUserAction(user.getUserId(), "user access to  " + groupName + " domain", previousAccess, DataAccessLevel.REGISTERED);
    return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
Also used : User(org.pmiops.workbench.db.model.User) DataAccessLevel(org.pmiops.workbench.model.DataAccessLevel) ApiException(org.pmiops.workbench.firecloud.ApiException) AuthorityRequired(org.pmiops.workbench.annotations.AuthorityRequired)

Example 5 with ApiException

use of org.pmiops.workbench.firecloud.ApiException in project workbench by all-of-us.

the class ProfileControllerTest method testMe_successDevProjectConflict.

@Test
public void testMe_successDevProjectConflict() throws Exception {
    createUser();
    when(fireCloudService.isRequesterEnabledInFirecloud()).thenReturn(true);
    Profile profile = profileController.getMe().getBody();
    String projectName = BILLING_PROJECT_PREFIX + PRIMARY_EMAIL.hashCode();
    doThrow(new ApiException(HttpStatus.CONFLICT.value(), "conflict")).when(fireCloudService).createAllOfUsBillingProject(projectName);
    // When a conflict occurs in dev, log the exception but continue.
    assertProfile(profile, PRIMARY_EMAIL, CONTACT_EMAIL, FAMILY_NAME, GIVEN_NAME, DataAccessLevel.UNREGISTERED, TIMESTAMP, projectName, true);
    verify(fireCloudService).registerUser(CONTACT_EMAIL, GIVEN_NAME, FAMILY_NAME);
    verify(fireCloudService).createAllOfUsBillingProject(projectName);
    verify(fireCloudService).addUserToBillingProject(PRIMARY_EMAIL, projectName);
}
Also used : Profile(org.pmiops.workbench.model.Profile) ApiException(org.pmiops.workbench.firecloud.ApiException) DataJpaTest(org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest) Test(org.junit.Test)

Aggregations

ApiException (org.pmiops.workbench.firecloud.ApiException)15 User (org.pmiops.workbench.db.model.User)8 Test (org.junit.Test)6 ServerErrorException (org.pmiops.workbench.exceptions.ServerErrorException)5 AuthorityRequired (org.pmiops.workbench.annotations.AuthorityRequired)4 WorkbenchConfig (org.pmiops.workbench.config.WorkbenchConfig)4 Profile (org.pmiops.workbench.model.Profile)4 DataJpaTest (org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest)4 ArrayList (java.util.ArrayList)3 BadRequestException (org.pmiops.workbench.exceptions.BadRequestException)3 Userinfoplus (com.google.api.services.oauth2.model.Userinfoplus)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 Timestamp (java.sql.Timestamp)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Function (java.util.function.Function)2 Level (java.util.logging.Level)2 Logger (java.util.logging.Logger)2 Collectors (java.util.stream.Collectors)2 Provider (javax.inject.Provider)2