use of bio.terra.stairway.exception.DatabaseOperationException in project terra-workspace-manager by DataBiosphere.
the class LaunchCloneGcsBucketResourceFlightStep method doStep.
@Override
public StepResult doStep(FlightContext context) throws InterruptedException, RetryException {
validateRequiredEntries(context.getInputParameters(), JobMapKeys.AUTH_USER_INFO.getKeyName(), ControlledResourceKeys.DESTINATION_WORKSPACE_ID);
@Nullable final var location = context.getInputParameters().get(ControlledResourceKeys.LOCATION, String.class);
final var userRequest = context.getInputParameters().get(JobMapKeys.AUTH_USER_INFO.getKeyName(), AuthenticatedUserRequest.class);
final var destinationWorkspaceId = context.getInputParameters().get(ControlledResourceKeys.DESTINATION_WORKSPACE_ID, UUID.class);
// Gather input parameters for flight. See
// bio.terra.workspace.service.resource.controlled.ControlledResourceService#cloneGcsBucket.
final FlightMap subflightInputParameters = new FlightMap();
subflightInputParameters.put(ControlledResourceKeys.LOCATION, location);
subflightInputParameters.put(ControlledResourceKeys.DESTINATION_WORKSPACE_ID, destinationWorkspaceId);
subflightInputParameters.put(JobMapKeys.AUTH_USER_INFO.getKeyName(), userRequest);
subflightInputParameters.put(ResourceKeys.RESOURCE, resource);
subflightInputParameters.put(ControlledResourceKeys.CLONING_INSTRUCTIONS, resource.getCloningInstructions());
// submit flight
try {
context.getStairway().submit(subflightId, CloneControlledGcsBucketResourceFlight.class, subflightInputParameters);
} catch (DuplicateFlightIdException unused) {
return StepResult.getStepResultSuccess();
} catch (DatabaseOperationException | StairwayExecutionException e) {
return new StepResult(StepStatus.STEP_RESULT_FAILURE_RETRY, e);
}
return StepResult.getStepResultSuccess();
}
use of bio.terra.stairway.exception.DatabaseOperationException in project terra-workspace-manager by DataBiosphere.
the class LaunchCreateReferenceResourceFlightStep method doStep.
@Override
public StepResult doStep(FlightContext context) throws InterruptedException, RetryException {
if (CloningInstructions.COPY_REFERENCE != resource.getCloningInstructions()) {
// Nothing to do -- don't launch flight
return StepResult.getStepResultSuccess();
}
FlightUtils.validateRequiredEntries(context.getInputParameters(), ControlledResourceKeys.DESTINATION_WORKSPACE_ID, JobMapKeys.AUTH_USER_INFO.getKeyName());
final var destinationWorkspaceId = context.getInputParameters().get(ControlledResourceKeys.DESTINATION_WORKSPACE_ID, UUID.class);
final var userRequest = context.getInputParameters().get(JobMapKeys.AUTH_USER_INFO.getKeyName(), AuthenticatedUserRequest.class);
final String description = String.format("Clone of Referenced Resource %s", resource.getResourceId());
final ReferencedResource destinationResource = WorkspaceCloneUtils.buildDestinationReferencedResource(resource, destinationWorkspaceId, null, description);
// put the destination resource in the map, because it's not communicated
// from the flight as the response (and we need the workspace ID)
context.getWorkingMap().put(ControlledResourceKeys.DESTINATION_REFERENCED_RESOURCE, destinationResource);
final FlightMap subflightInputParameters = new FlightMap();
subflightInputParameters.put(ResourceKeys.RESOURCE, destinationResource);
subflightInputParameters.put(JobMapKeys.AUTH_USER_INFO.getKeyName(), userRequest);
subflightInputParameters.put(WorkspaceFlightMapKeys.ResourceKeys.RESOURCE_TYPE, resource.getResourceType().name());
try {
context.getStairway().submit(subflightId, CreateReferenceResourceFlight.class, subflightInputParameters);
} catch (DatabaseOperationException | StairwayExecutionException e) {
return new StepResult(StepStatus.STEP_RESULT_FAILURE_RETRY, e);
} catch (DuplicateFlightIdException unused) {
// already submitted the flight - treat as success
return StepResult.getStepResultSuccess();
}
FlightUtils.validateRequiredEntries(context.getWorkingMap(), ControlledResourceKeys.DESTINATION_REFERENCED_RESOURCE);
return StepResult.getStepResultSuccess();
}
use of bio.terra.stairway.exception.DatabaseOperationException in project terra-workspace-manager by DataBiosphere.
the class AwaitCloneAllResourcesFlightStep method doStep.
@Override
public StepResult doStep(FlightContext context) throws InterruptedException, RetryException {
validateRequiredEntries(context.getInputParameters(), ControlledResourceKeys.SOURCE_WORKSPACE_ID, JobMapKeys.REQUEST.getKeyName());
validateRequiredEntries(context.getWorkingMap(), ControlledResourceKeys.CLONE_ALL_RESOURCES_FLIGHT_ID);
final var cloneAllResourcesFlightId = context.getWorkingMap().get(ControlledResourceKeys.CLONE_ALL_RESOURCES_FLIGHT_ID, String.class);
final var destinationWorkspace = context.getInputParameters().get(JobMapKeys.REQUEST.getKeyName(), Workspace.class);
try {
// noinspection deprecation
final FlightState subflightState = context.getStairway().waitForFlight(cloneAllResourcesFlightId, FLIGHT_POLL_SECONDS, FLIGHT_POLL_CYCLES);
if (FlightStatus.SUCCESS != subflightState.getFlightStatus()) {
// no point in retrying the await step
return new StepResult(StepStatus.STEP_RESULT_FAILURE_FATAL, subflightState.getException().orElseGet(() -> new RuntimeException(String.format("Subflight had unexpected status %s. No exception for subflight found.", subflightState.getFlightStatus()))));
}
final FlightMap subflightResultMap = FlightUtils.getResultMapRequired(subflightState);
// Build the response object from the resource ID to details map. The map won't have been
// instantiated if there are no resources in the workspace, so just use an empty map in that
// case.
final var resourceIdToDetails = Optional.ofNullable(subflightResultMap.get(ControlledResourceKeys.RESOURCE_ID_TO_CLONE_RESULT, new TypeReference<Map<UUID, WsmResourceCloneDetails>>() {
})).orElse(Collections.emptyMap());
final var apiClonedWorkspace = new ApiClonedWorkspace();
apiClonedWorkspace.setDestinationWorkspaceId(destinationWorkspace.getWorkspaceId());
final var sourceWorkspaceId = context.getInputParameters().get(ControlledResourceKeys.SOURCE_WORKSPACE_ID, UUID.class);
apiClonedWorkspace.setSourceWorkspaceId(sourceWorkspaceId);
final List<ApiResourceCloneDetails> resources = resourceIdToDetails.values().stream().map(WsmResourceCloneDetails::toApiModel).collect(Collectors.toList());
apiClonedWorkspace.setResources(resources);
// Set overall response for workspace clone flights
FlightUtils.setResponse(context, apiClonedWorkspace, HttpStatus.OK);
} catch (DatabaseOperationException | FlightWaitTimedOutException e) {
// Retry for database issues or expired wait loop
return new StepResult(StepStatus.STEP_RESULT_FAILURE_RETRY, e);
}
return StepResult.getStepResultSuccess();
}
use of bio.terra.stairway.exception.DatabaseOperationException in project terra-workspace-manager by DataBiosphere.
the class AwaitCloneGcsBucketResourceFlightStep method doStep.
@Override
public StepResult doStep(FlightContext context) throws InterruptedException, RetryException {
// wait for the flight
try {
final FlightState subflightState = context.getStairway().waitForFlight(subflightId, FLIGHT_POLL_SECONDS, FLIGHT_POLL_CYCLES);
final FlightStatus subflightStatus = subflightState.getFlightStatus();
final WsmCloneResourceResult cloneResult = WorkspaceCloneUtils.flightStatusToCloneResult(subflightStatus, resource);
final var cloneDetails = new WsmResourceCloneDetails();
cloneDetails.setResult(cloneResult);
final FlightMap resultMap = FlightUtils.getResultMapRequired(subflightState);
final var clonedBucket = resultMap.get(JobMapKeys.RESPONSE.getKeyName(), ApiClonedControlledGcpGcsBucket.class);
cloneDetails.setStewardshipType(StewardshipType.CONTROLLED);
cloneDetails.setResourceType(WsmResourceType.CONTROLLED_GCP_GCS_BUCKET);
cloneDetails.setCloningInstructions(resource.getCloningInstructions());
cloneDetails.setSourceResourceId(resource.getResourceId());
cloneDetails.setDestinationResourceId(Optional.ofNullable(clonedBucket).map(ApiClonedControlledGcpGcsBucket::getBucket).map(ApiCreatedControlledGcpGcsBucket::getResourceId).orElse(null));
cloneDetails.setErrorMessage(FlightUtils.getFlightErrorMessage(subflightState));
cloneDetails.setName(resource.getName());
cloneDetails.setDescription(resource.getDescription());
// add to the map
final var resourceIdToResult = Optional.ofNullable(context.getWorkingMap().get(ControlledResourceKeys.RESOURCE_ID_TO_CLONE_RESULT, new TypeReference<Map<UUID, WsmResourceCloneDetails>>() {
})).orElseGet(HashMap::new);
resourceIdToResult.put(resource.getResourceId(), cloneDetails);
context.getWorkingMap().put(ControlledResourceKeys.RESOURCE_ID_TO_CLONE_RESULT, resourceIdToResult);
} catch (DatabaseOperationException | FlightWaitTimedOutException e) {
// Retry for database issues or expired wait loop
return new StepResult(StepStatus.STEP_RESULT_FAILURE_RETRY, e);
}
validateRequiredEntries(context.getWorkingMap(), ControlledResourceKeys.RESOURCE_ID_TO_CLONE_RESULT);
return StepResult.getStepResultSuccess();
}
use of bio.terra.stairway.exception.DatabaseOperationException in project terra-workspace-manager by DataBiosphere.
the class LaunchCreateGcpContextFlightStep method doStep.
@Override
public StepResult doStep(FlightContext context) throws InterruptedException, RetryException {
validateRequiredEntries(context.getInputParameters(), ControlledResourceKeys.SOURCE_WORKSPACE_ID, JobMapKeys.AUTH_USER_INFO.getKeyName(), JobMapKeys.REQUEST.getKeyName());
validateRequiredEntries(context.getWorkingMap(), ControlledResourceKeys.CREATE_CLOUD_CONTEXT_FLIGHT_ID);
final var userRequest = context.getInputParameters().get(JobMapKeys.AUTH_USER_INFO.getKeyName(), AuthenticatedUserRequest.class);
final var destinationWorkspace = context.getInputParameters().get(JobMapKeys.REQUEST.getKeyName(), Workspace.class);
final var cloudContextJobId = context.getWorkingMap().get(ControlledResourceKeys.CREATE_CLOUD_CONTEXT_FLIGHT_ID, String.class);
boolean flightAlreadyExists;
try {
context.getStairway().getFlightState(cloudContextJobId);
flightAlreadyExists = true;
} catch (FlightNotFoundException e) {
flightAlreadyExists = false;
} catch (DatabaseOperationException e) {
return new StepResult(StepStatus.STEP_RESULT_FAILURE_RETRY, e);
}
// if we already have a flight, don't launch another one
if (!flightAlreadyExists) {
workspaceService.createGcpCloudContext(destinationWorkspace.getWorkspaceId(), cloudContextJobId, userRequest);
}
return StepResult.getStepResultSuccess();
}
Aggregations