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;
}
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);
}
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");
}
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;
}
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);
}
Aggregations