use of bio.terra.workspace.model.CloneWorkspaceRequest in project terra-cli by DataBiosphere.
the class WorkspaceManagerService method cloneWorkspace.
/**
* Call the Workspace Manager POST "/api/workspaces/v1/{workspaceId}/clone" endpoint to clone a
* workspace.
*
* @param workspaceId - workspace ID to clone
* @param displayName - optional name of new cloned workspace
* @param description - optional description for new workspace
* @return object with information about the clone job success and destination workspace
*/
public CloneWorkspaceResult cloneWorkspace(UUID workspaceId, @Nullable String displayName, @Nullable String description) {
var request = new CloneWorkspaceRequest().spendProfile(Context.getServer().getWsmDefaultSpendProfile()).displayName(displayName).description(description).location(null);
WorkspaceApi workspaceApi = new WorkspaceApi(apiClient);
CloneWorkspaceResult initialResult = callWithRetries(() -> workspaceApi.cloneWorkspace(request, workspaceId), "Error cloning workspace");
logger.debug("clone workspace initial result: {}", initialResult);
// poll until the workspace clone completes.
// TODO PF-745: return immediately and give some interface for checking on the job status
// and retrieving the result.
CloneWorkspaceResult cloneWorkspaceResult = handleClientExceptions(() -> HttpUtils.pollWithRetries(() -> workspaceApi.getCloneWorkspaceResult(workspaceId, initialResult.getJobReport().getId()), (result) -> isDone(result.getJobReport()), WorkspaceManagerService::isRetryable, CLONE_WORKSPACE_MAXIMUM_RETRIES, CLONE_WORKSPACE_RETRY_INTERVAL), "Error in cloning workspace.");
logger.debug("clone workspace polling result: {}", cloneWorkspaceResult);
throwIfJobNotCompleted(cloneWorkspaceResult.getJobReport(), cloneWorkspaceResult.getErrorReport());
return cloneWorkspaceResult;
}
use of bio.terra.workspace.model.CloneWorkspaceRequest in project terra-workspace-manager by DataBiosphere.
the class CloneWorkspace method doUserJourney.
@Override
protected void doUserJourney(TestUserSpecification sourceOwnerUser, WorkspaceApi sourceOwnerWorkspaceApi) throws Exception {
// As reader user, clone the workspace
// Get a new workspace API for the reader
cloningUserWorkspaceApi = ClientTestUtils.getWorkspaceClient(cloningUser, server);
final CloneWorkspaceRequest cloneWorkspaceRequest = new CloneWorkspaceRequest().displayName("Cloned Workspace").description("A clone of workspace " + getWorkspaceId().toString()).spendProfile(// TODO- use a different one if available
getSpendProfileId()).location("us-central1");
CloneWorkspaceResult cloneResult = cloningUserWorkspaceApi.cloneWorkspace(cloneWorkspaceRequest, getWorkspaceId());
final String jobId = cloneResult.getJobReport().getId();
cloneResult = ClientTestUtils.pollWhileRunning(cloneResult, () -> cloningUserWorkspaceApi.getCloneWorkspaceResult(getWorkspaceId(), jobId), CloneWorkspaceResult::getJobReport, Duration.ofSeconds(10));
logger.info("Clone result: {}", cloneResult);
ClientTestUtils.assertJobSuccess("Clone Workspace", cloneResult.getJobReport(), cloneResult.getErrorReport());
assertNull(cloneResult.getErrorReport());
assertNotNull(cloneResult.getWorkspace());
assertThat(cloneResult.getWorkspace().getResources(), hasSize(EXPECTED_NUM_CLONED_RESOURCES));
assertEquals(getWorkspaceId(), cloneResult.getWorkspace().getSourceWorkspaceId());
destinationWorkspaceId = cloneResult.getWorkspace().getDestinationWorkspaceId();
assertNotNull(destinationWorkspaceId);
// Verify shared GCS bucket succeeds and is populated
final ResourceCloneDetails sharedBucketCloneDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> sharedSourceBucket.getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(sharedBucketCloneDetails.toString());
assertEquals(CloneResourceResult.SUCCEEDED, sharedBucketCloneDetails.getResult());
assertEquals(CloningInstructionsEnum.RESOURCE, sharedBucketCloneDetails.getCloningInstructions());
assertEquals(ResourceType.GCS_BUCKET, sharedBucketCloneDetails.getResourceType());
assertEquals(StewardshipType.CONTROLLED, sharedBucketCloneDetails.getStewardshipType());
assertNotNull(sharedBucketCloneDetails.getDestinationResourceId());
assertNull(sharedBucketCloneDetails.getErrorMessage());
assertEquals(sharedSourceBucket.getGcpBucket().getMetadata().getName(), sharedBucketCloneDetails.getName());
assertEquals(sharedSourceBucket.getGcpBucket().getMetadata().getDescription(), sharedBucketCloneDetails.getDescription());
// We need to get the destination bucket name and project ID
final WorkspaceDescription destinationWorkspace = cloningUserWorkspaceApi.getWorkspace(destinationWorkspaceId);
final String destinationProjectId = destinationWorkspace.getGcpContext().getProjectId();
final var clonedSharedBucket = cloningUserResourceApi.getBucket(destinationWorkspaceId, sharedBucketCloneDetails.getDestinationResourceId());
GcsBucketObjectUtils.retrieveBucketFile(clonedSharedBucket.getAttributes().getBucketName(), destinationProjectId, cloningUser);
// Verify clone of private bucket fails
final ResourceCloneDetails privateBucketCloneDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> privateSourceBucket.getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(privateBucketCloneDetails.toString());
assertEquals(CloneResourceResult.FAILED, privateBucketCloneDetails.getResult());
assertEquals(CloningInstructionsEnum.RESOURCE, privateBucketCloneDetails.getCloningInstructions());
assertEquals(ResourceType.GCS_BUCKET, privateBucketCloneDetails.getResourceType());
assertEquals(StewardshipType.CONTROLLED, privateBucketCloneDetails.getStewardshipType());
assertNull(privateBucketCloneDetails.getDestinationResourceId());
assertNotNull(privateBucketCloneDetails.getErrorMessage());
assertEquals(privateSourceBucket.getGcpBucket().getMetadata().getName(), privateBucketCloneDetails.getName());
assertEquals(privateSourceBucket.getGcpBucket().getMetadata().getDescription(), privateBucketCloneDetails.getDescription());
// Verify COPY_NOTHING bucket was skipped
final ResourceCloneDetails copyNothingBucketCloneDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> sharedCopyNothingSourceBucket.getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(copyNothingBucketCloneDetails.toString());
assertEquals(CloneResourceResult.SKIPPED, copyNothingBucketCloneDetails.getResult());
assertEquals(CloningInstructionsEnum.NOTHING, copyNothingBucketCloneDetails.getCloningInstructions());
assertEquals(ResourceType.GCS_BUCKET, copyNothingBucketCloneDetails.getResourceType());
assertEquals(StewardshipType.CONTROLLED, copyNothingBucketCloneDetails.getStewardshipType());
assertNull(copyNothingBucketCloneDetails.getDestinationResourceId());
assertNull(copyNothingBucketCloneDetails.getErrorMessage());
assertEquals(sharedCopyNothingSourceBucket.getGcpBucket().getMetadata().getName(), copyNothingBucketCloneDetails.getName());
assertEquals(sharedCopyNothingSourceBucket.getGcpBucket().getMetadata().getDescription(), copyNothingBucketCloneDetails.getDescription());
// verify COPY_DEFINITION bucket exists but is empty
final ResourceCloneDetails copyDefinitionBucketDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> copyDefinitionSourceBucket.getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(copyDefinitionBucketDetails.toString());
assertEquals(CloneResourceResult.SUCCEEDED, copyDefinitionBucketDetails.getResult());
assertEquals(CloningInstructionsEnum.DEFINITION, copyDefinitionBucketDetails.getCloningInstructions());
assertEquals(ResourceType.GCS_BUCKET, copyDefinitionBucketDetails.getResourceType());
assertEquals(StewardshipType.CONTROLLED, copyDefinitionBucketDetails.getStewardshipType());
assertNotNull(copyDefinitionBucketDetails.getDestinationResourceId());
final GcpGcsBucketResource clonedCopyDefinitionBucket = cloningUserResourceApi.getBucket(destinationWorkspaceId, copyDefinitionBucketDetails.getDestinationResourceId());
assertEmptyBucket(clonedCopyDefinitionBucket.getAttributes().getBucketName(), destinationProjectId);
assertEquals(copyDefinitionSourceBucket.getGcpBucket().getMetadata().getName(), copyDefinitionBucketDetails.getName());
assertEquals(copyDefinitionSourceBucket.getGcpBucket().getMetadata().getDescription(), copyDefinitionBucketDetails.getDescription());
// verify COPY_DEFINITION dataset exists but has no tables
final ResourceCloneDetails copyDefinitionDatasetDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> copyDefinitionDataset.getMetadata().getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(copyDefinitionDatasetDetails.toString());
assertEquals(CloneResourceResult.SUCCEEDED, copyDefinitionDatasetDetails.getResult());
assertEquals(CloningInstructionsEnum.DEFINITION, copyDefinitionDatasetDetails.getCloningInstructions());
assertEquals(ResourceType.BIG_QUERY_DATASET, copyDefinitionDatasetDetails.getResourceType());
assertEquals(StewardshipType.CONTROLLED, copyDefinitionDatasetDetails.getStewardshipType());
assertNotNull(copyDefinitionDatasetDetails.getDestinationResourceId());
assertNull(copyDefinitionDatasetDetails.getErrorMessage());
assertEquals(copyDefinitionDataset.getMetadata().getName(), copyDefinitionDatasetDetails.getName());
assertEquals(copyDefinitionDataset.getMetadata().getDescription(), copyDefinitionDatasetDetails.getDescription());
final BigQuery bigQueryClient = ClientTestUtils.getGcpBigQueryClient(cloningUser, destinationProjectId);
assertDatasetHasNoTables(destinationProjectId, bigQueryClient, copyDefinitionDatasetResourceName);
// verify clone resource dataset succeeded and has rows and tables
final ResourceCloneDetails copyResourceDatasetDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> copyResourceDataset.getMetadata().getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(copyResourceDatasetDetails.toString());
assertEquals(CloneResourceResult.SUCCEEDED, copyResourceDatasetDetails.getResult());
assertEquals(CloningInstructionsEnum.RESOURCE, copyResourceDatasetDetails.getCloningInstructions());
assertEquals(ResourceType.BIG_QUERY_DATASET, copyResourceDatasetDetails.getResourceType());
assertEquals(StewardshipType.CONTROLLED, copyResourceDatasetDetails.getStewardshipType());
assertNotNull(copyResourceDatasetDetails.getDestinationResourceId());
assertNull(copyResourceDatasetDetails.getErrorMessage());
// Use cloned result table to avoid Domain Restricted Sharing conflicts created by temporary
// result table IAM.
TableId resultTableId = TableId.of(destinationProjectId, copyResourceDatasetResourceName, BQ_RESULT_TABLE_NAME);
final QueryJobConfiguration employeeQueryJobConfiguration = QueryJobConfiguration.newBuilder("SELECT * FROM `" + destinationProjectId + "." + copyResourceDatasetResourceName + ".employee`;").setDestinationTable(resultTableId).setWriteDisposition(WriteDisposition.WRITE_TRUNCATE).build();
final TableResult employeeTableResult = bigQueryClient.query(employeeQueryJobConfiguration);
final long numEmployees = StreamSupport.stream(employeeTableResult.getValues().spliterator(), false).count();
assertThat(numEmployees, is(greaterThanOrEqualTo(2L)));
// verify private dataset clone failed
final ResourceCloneDetails privateDatasetDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> privateDataset.getMetadata().getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(privateDatasetDetails.toString());
assertEquals(CloneResourceResult.FAILED, privateDatasetDetails.getResult());
assertEquals(CloningInstructionsEnum.RESOURCE, privateDatasetDetails.getCloningInstructions());
assertEquals(ResourceType.BIG_QUERY_DATASET, privateDatasetDetails.getResourceType());
assertEquals(StewardshipType.CONTROLLED, privateDatasetDetails.getStewardshipType());
assertNull(privateDatasetDetails.getDestinationResourceId());
assertNotNull(privateDatasetDetails.getErrorMessage());
final ResourceCloneDetails bucketReferenceDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> sourceBucketReference.getMetadata().getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(bucketReferenceDetails.toString());
assertEquals(CloneResourceResult.SUCCEEDED, bucketReferenceDetails.getResult());
assertEquals(CloningInstructionsEnum.REFERENCE, bucketReferenceDetails.getCloningInstructions());
assertEquals(ResourceType.GCS_BUCKET, bucketReferenceDetails.getResourceType());
assertEquals(StewardshipType.REFERENCED, bucketReferenceDetails.getStewardshipType());
assertNotNull(bucketReferenceDetails.getDestinationResourceId());
assertNull(bucketReferenceDetails.getErrorMessage());
final ResourceCloneDetails bucketFileReferenceDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> sourceBucketFileReference.getMetadata().getResourceId().equals(r.getSourceResourceId())).findFirst());
logger.info(bucketFileReferenceDetails.toString());
assertEquals(CloneResourceResult.SUCCEEDED, bucketFileReferenceDetails.getResult());
assertEquals(CloningInstructionsEnum.REFERENCE, bucketFileReferenceDetails.getCloningInstructions());
assertEquals(ResourceType.GCS_OBJECT, bucketFileReferenceDetails.getResourceType());
assertEquals(StewardshipType.REFERENCED, bucketFileReferenceDetails.getStewardshipType());
assertNotNull(bucketFileReferenceDetails.getDestinationResourceId());
assertNull(bucketFileReferenceDetails.getErrorMessage());
final ResourceCloneDetails datasetReferenceDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> sourceDatasetReference.getMetadata().getResourceId().equals(r.getSourceResourceId())).findFirst());
assertEquals(CloneResourceResult.SKIPPED, datasetReferenceDetails.getResult());
assertEquals(CloningInstructionsEnum.NOTHING, datasetReferenceDetails.getCloningInstructions());
assertEquals(ResourceType.BIG_QUERY_DATASET, datasetReferenceDetails.getResourceType());
assertEquals(StewardshipType.REFERENCED, datasetReferenceDetails.getStewardshipType());
assertNull(datasetReferenceDetails.getDestinationResourceId());
assertNull(datasetReferenceDetails.getErrorMessage());
final ResourceCloneDetails dataTableReferenceDetails = getOrFail(cloneResult.getWorkspace().getResources().stream().filter(r -> sourceDataTableReference.getMetadata().getResourceId().equals(r.getSourceResourceId())).findFirst());
assertEquals(CloneResourceResult.SKIPPED, dataTableReferenceDetails.getResult());
assertEquals(CloningInstructionsEnum.NOTHING, dataTableReferenceDetails.getCloningInstructions());
assertEquals(ResourceType.BIG_QUERY_DATA_TABLE, dataTableReferenceDetails.getResourceType());
assertEquals(StewardshipType.REFERENCED, dataTableReferenceDetails.getStewardshipType());
assertNull(dataTableReferenceDetails.getDestinationResourceId());
assertNull(dataTableReferenceDetails.getErrorMessage());
}
Aggregations