use of org.pmiops.workbench.db.model.Workspace.FirecloudWorkspaceId in project workbench by all-of-us.
the class WorkspacesController method createWorkspace.
@Override
public ResponseEntity<Workspace> createWorkspace(Workspace workspace) {
if (Strings.isNullOrEmpty(workspace.getNamespace())) {
throw new BadRequestException("missing required field 'namespace'");
} else if (Strings.isNullOrEmpty(workspace.getName())) {
throw new BadRequestException("missing required field 'name'");
} else if (workspace.getResearchPurpose() == null) {
throw new BadRequestException("missing required field 'researchPurpose'");
} else if (workspace.getDataAccessLevel() == null) {
throw new BadRequestException("missing required field 'dataAccessLevel'");
}
User user = userProvider.get();
org.pmiops.workbench.db.model.Workspace existingWorkspace = workspaceService.getByName(workspace.getNamespace(), workspace.getName());
if (existingWorkspace != null) {
throw new ConflictException(String.format("Workspace %s/%s already exists", workspace.getNamespace(), workspace.getName()));
}
// Note: please keep any initialization logic here in sync with CloneWorkspace().
FirecloudWorkspaceId workspaceId = generateFirecloudWorkspaceId(workspace.getNamespace(), workspace.getName());
FirecloudWorkspaceId fcWorkspaceId = workspaceId;
org.pmiops.workbench.firecloud.model.Workspace fcWorkspace = null;
for (int attemptValue = 0; attemptValue < MAX_FC_CREATION_ATTEMPT_VALUES; attemptValue++) {
try {
fcWorkspace = attemptFirecloudWorkspaceCreation(fcWorkspaceId);
break;
} catch (ConflictException e) {
if (attemptValue >= 5) {
throw e;
} else {
fcWorkspaceId = new FirecloudWorkspaceId(workspaceId.getWorkspaceNamespace(), workspaceId.getWorkspaceName() + Integer.toString(attemptValue));
}
}
}
Timestamp now = new Timestamp(clock.instant().toEpochMilli());
org.pmiops.workbench.db.model.Workspace dbWorkspace = new org.pmiops.workbench.db.model.Workspace();
dbWorkspace.setFirecloudName(fcWorkspaceId.getWorkspaceName());
dbWorkspace.setWorkspaceNamespace(fcWorkspaceId.getWorkspaceNamespace());
dbWorkspace.setCreator(user);
dbWorkspace.setCreationTime(now);
dbWorkspace.setLastModifiedTime(now);
dbWorkspace.setVersion(1);
setCdrVersionId(dbWorkspace, workspace.getCdrVersionId());
writeWorkspaceConfigFile(fcWorkspace, dbWorkspace.getCdrVersion());
org.pmiops.workbench.db.model.Workspace reqWorkspace = FROM_CLIENT_WORKSPACE.apply(workspace);
// TODO: enforce data access level authorization
dbWorkspace.setDataAccessLevel(reqWorkspace.getDataAccessLevel());
dbWorkspace.setName(reqWorkspace.getName());
dbWorkspace.setDescription(reqWorkspace.getDescription());
// Ignore incoming fields pertaining to review status; clients can only request a review.
setResearchPurposeDetails(dbWorkspace, workspace.getResearchPurpose());
if (reqWorkspace.getReviewRequested()) {
// Use a consistent timestamp.
dbWorkspace.setTimeRequested(now);
}
dbWorkspace.setReviewRequested(reqWorkspace.getReviewRequested());
org.pmiops.workbench.db.model.WorkspaceUserRole permissions = new org.pmiops.workbench.db.model.WorkspaceUserRole();
permissions.setRole(WorkspaceAccessLevel.OWNER);
permissions.setWorkspace(dbWorkspace);
permissions.setUser(user);
dbWorkspace.addWorkspaceUserRole(permissions);
dbWorkspace = workspaceService.getDao().save(dbWorkspace);
return ResponseEntity.ok(TO_SINGLE_CLIENT_WORKSPACE_FROM_FC_AND_DB.apply(dbWorkspace, fcWorkspace));
}
use of org.pmiops.workbench.db.model.Workspace.FirecloudWorkspaceId in project workbench by all-of-us.
the class WorkspacesController method cloneWorkspace.
@Override
public ResponseEntity<CloneWorkspaceResponse> cloneWorkspace(String workspaceNamespace, String workspaceId, CloneWorkspaceRequest body) {
Workspace workspace = body.getWorkspace();
if (Strings.isNullOrEmpty(workspace.getNamespace())) {
throw new BadRequestException("missing required field 'workspace.namespace'");
} else if (Strings.isNullOrEmpty(workspace.getName())) {
throw new BadRequestException("missing required field 'workspace.name'");
} else if (workspace.getResearchPurpose() == null) {
throw new BadRequestException("missing required field 'workspace.researchPurpose'");
}
User user = userProvider.get();
if (workspaceService.getByName(workspace.getNamespace(), workspace.getName()) != null) {
throw new ConflictException(String.format("Workspace %s/%s already exists", workspace.getNamespace(), workspace.getName()));
}
// Retrieving the workspace is done first, which acts as an access check.
String fromBucket = null;
try {
fromBucket = fireCloudService.getWorkspace(workspaceNamespace, workspaceId).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", workspaceNamespace, workspaceId));
}
log.log(Level.SEVERE, "Firecloud server error", e);
throw new ServerErrorException();
}
org.pmiops.workbench.db.model.Workspace fromWorkspace = workspaceService.getRequiredWithCohorts(workspaceNamespace, workspaceId);
if (fromWorkspace == null) {
throw new NotFoundException(String.format("Workspace %s/%s not found", workspaceNamespace, workspaceId));
}
FirecloudWorkspaceId fcWorkspaceId = generateFirecloudWorkspaceId(workspace.getNamespace(), workspace.getName());
fireCloudService.cloneWorkspace(workspaceNamespace, workspaceId, fcWorkspaceId.getWorkspaceNamespace(), fcWorkspaceId.getWorkspaceName());
org.pmiops.workbench.firecloud.model.Workspace toFcWorkspace = null;
try {
toFcWorkspace = fireCloudService.getWorkspace(fcWorkspaceId.getWorkspaceNamespace(), fcWorkspaceId.getWorkspaceName()).getWorkspace();
} catch (ApiException e) {
log.log(Level.SEVERE, "Firecloud error retrieving newly cloned workspace", e);
throw new ServerErrorException();
}
// feasibly copy within a single API request.
for (Blob b : cloudStorageService.getBlobList(fromBucket, NOTEBOOKS_WORKSPACE_DIRECTORY)) {
if (!NOTEBOOK_PATTERN.matcher(b.getName()).matches()) {
continue;
}
if (b.getSize() != null && b.getSize() / 1e6 > MAX_NOTEBOOK_SIZE_MB) {
throw new FailedPreconditionException(String.format("workspace %s/%s contains a notebook larger than %dMB: '%s'; cannot clone - please " + "remove this notebook, reduce its size, or contact the workspace owner", workspaceNamespace, workspaceId, MAX_NOTEBOOK_SIZE_MB, b.getName()));
}
cloudStorageService.copyBlob(b.getBlobId(), BlobId.of(toFcWorkspace.getBucketName(), b.getName()));
}
// The final step in the process is to clone the AoU representation of the
// workspace. The implication here is that we may generate orphaned
// Firecloud workspaces / buckets, but a user should not be able to see
// half-way cloned workspaces via AoU - so it will just appear as a
// transient failure.
org.pmiops.workbench.db.model.Workspace toWorkspace = FROM_CLIENT_WORKSPACE.apply(body.getWorkspace());
org.pmiops.workbench.db.model.Workspace dbWorkspace = new org.pmiops.workbench.db.model.Workspace();
Timestamp now = new Timestamp(clock.instant().toEpochMilli());
dbWorkspace.setFirecloudName(fcWorkspaceId.getWorkspaceName());
dbWorkspace.setWorkspaceNamespace(fcWorkspaceId.getWorkspaceNamespace());
dbWorkspace.setCreator(user);
dbWorkspace.setCreationTime(now);
dbWorkspace.setLastModifiedTime(now);
dbWorkspace.setVersion(1);
dbWorkspace.setName(toWorkspace.getName());
ResearchPurpose researchPurpose = body.getWorkspace().getResearchPurpose();
setResearchPurposeDetails(dbWorkspace, researchPurpose);
if (researchPurpose.getReviewRequested()) {
// Use a consistent timestamp.
dbWorkspace.setTimeRequested(now);
}
dbWorkspace.setReviewRequested(researchPurpose.getReviewRequested());
// Clone the previous description, by default.
if (Strings.isNullOrEmpty(toWorkspace.getDescription())) {
dbWorkspace.setDescription(fromWorkspace.getDescription());
} else {
dbWorkspace.setDescription(toWorkspace.getDescription());
}
dbWorkspace.setCdrVersion(fromWorkspace.getCdrVersion());
dbWorkspace.setDataAccessLevel(fromWorkspace.getDataAccessLevel());
writeWorkspaceConfigFile(toFcWorkspace, dbWorkspace.getCdrVersion());
org.pmiops.workbench.db.model.WorkspaceUserRole permissions = new org.pmiops.workbench.db.model.WorkspaceUserRole();
permissions.setRole(WorkspaceAccessLevel.OWNER);
permissions.setWorkspace(dbWorkspace);
permissions.setUser(user);
dbWorkspace.addWorkspaceUserRole(permissions);
dbWorkspace = workspaceService.saveAndCloneCohorts(fromWorkspace, dbWorkspace);
CloneWorkspaceResponse resp = new CloneWorkspaceResponse();
resp.setWorkspace(TO_SINGLE_CLIENT_WORKSPACE_FROM_FC_AND_DB.apply(dbWorkspace, toFcWorkspace));
return ResponseEntity.ok(resp);
}
use of org.pmiops.workbench.db.model.Workspace.FirecloudWorkspaceId in project workbench by all-of-us.
the class WorkspacesController method constructListWorkspaceFromDb.
// This does not populate the list of underserved research groups.
private static final Workspace constructListWorkspaceFromDb(org.pmiops.workbench.db.model.Workspace workspace, ResearchPurpose researchPurpose) {
FirecloudWorkspaceId workspaceId = workspace.getFirecloudWorkspaceId();
Workspace result = new Workspace().etag(Etags.fromVersion(workspace.getVersion())).lastModifiedTime(workspace.getLastModifiedTime().getTime()).creationTime(workspace.getCreationTime().getTime()).dataAccessLevel(workspace.getDataAccessLevel()).name(workspace.getName()).id(workspaceId.getWorkspaceName()).namespace(workspaceId.getWorkspaceNamespace()).description(workspace.getDescription()).researchPurpose(researchPurpose);
if (workspace.getCreator() != null) {
result.setCreator(workspace.getCreator().getEmail());
}
if (workspace.getCdrVersion() != null) {
result.setCdrVersionId(String.valueOf(workspace.getCdrVersion().getCdrVersionId()));
}
result.setUserRoles(workspace.getWorkspaceUserRoles().stream().map(TO_CLIENT_USER_ROLE).collect(Collectors.toList()));
return result;
}
Aggregations