Search in sources :

Example 11 with FlightMap

use of bio.terra.stairway.FlightMap in project jade-data-repo by DataBiosphere.

the class IngestDriverStep method launchLoads.

private void launchLoads(FlightContext context, int launchCount, List<LoadFile> loadFiles, String profileId, UUID loadId, GoogleBucketResource bucketInfo) throws DatabaseOperationException, StairwayExecutionException, InterruptedException {
    Stairway stairway = context.getStairway();
    for (int i = 0; i < launchCount; i++) {
        LoadFile loadFile = loadFiles.get(i);
        String flightId = stairway.createFlightId();
        FileLoadModel fileLoadModel = new FileLoadModel().sourcePath(loadFile.getSourcePath()).targetPath(loadFile.getTargetPath()).mimeType(loadFile.getMimeType()).profileId(profileId).loadTag(loadTag).description(loadFile.getDescription());
        FlightMap inputParameters = new FlightMap();
        inputParameters.put(FileMapKeys.DATASET_ID, datasetId);
        inputParameters.put(FileMapKeys.REQUEST, fileLoadModel);
        inputParameters.put(FileMapKeys.BUCKET_INFO, bucketInfo);
        loadService.setLoadFileRunning(loadId, loadFile.getTargetPath(), flightId);
        // NOTE: this is the window where we have recorded a flight as RUNNING in the load_file
        // table, but it has not yet been launched. A failure in this window leaves "orphan"
        // loads that are marked running, but not actually started. We handle this
        // with the check for launch orphans at the beginning of the do() method.
        // We use submitToQueue to spread the file loaders across multiple instances of datarepo.
        stairway.submitToQueue(flightId, FileIngestWorkerFlight.class, inputParameters);
    }
}
Also used : Stairway(bio.terra.stairway.Stairway) LoadFile(bio.terra.service.load.LoadFile) FlightMap(bio.terra.stairway.FlightMap) FileLoadModel(bio.terra.model.FileLoadModel)

Example 12 with FlightMap

use of bio.terra.stairway.FlightMap in project jade-data-repo by DataBiosphere.

the class IngestFileDirectoryStep method doStep.

@Override
public StepResult doStep(FlightContext context) {
    FlightMap inputParameters = context.getInputParameters();
    FileLoadModel loadModel = inputParameters.get(JobMapKeys.REQUEST.getKeyName(), FileLoadModel.class);
    FlightMap workingMap = context.getWorkingMap();
    String fileId = workingMap.get(FileMapKeys.FILE_ID, String.class);
    workingMap.put(FileMapKeys.LOAD_COMPLETED, false);
    String datasetId = dataset.getId().toString();
    String targetPath = loadModel.getTargetPath();
    try {
        // The state logic goes like this:
        // 1. the directory entry doesn't exist. We need to create the directory entry for it.
        // 2. the directory entry exists. There are three cases:
        // a. If loadTags do not match, then we throw FileAlreadyExistsException.
        // b. directory entry loadTag matches our loadTag AND entry fileId matches our fileId:
        // means we are recovering and need to complete the file creation work.
        // c. directory entry loadTag matches our loadTag AND entry fileId does NOT match our fileId
        // means this is a re-run of a load job. We update the fileId in the working map. We don't
        // know if we are recovering or already finished. We try to retrieve the file object for
        // the entry fileId:
        // i. If that is successful, then we already loaded this file. We store "completed=true"
        // in the working map, so other steps do nothing.
        // ii. If that fails, then we are recovering: we leave completed unset (=false) in the working map.
        // 
        // Lookup the file - on a recovery, we may have already created it, but not
        // finished. Or it might already exist, created by someone else.
        FireStoreDirectoryEntry existingEntry = fileDao.lookupDirectoryEntryByPath(dataset, targetPath);
        if (existingEntry == null) {
            // Not there - create it
            FireStoreDirectoryEntry newEntry = new FireStoreDirectoryEntry().fileId(fileId).isFileRef(true).path(fireStoreUtils.getDirectoryPath(loadModel.getTargetPath())).name(fireStoreUtils.getName(loadModel.getTargetPath())).datasetId(datasetId).loadTag(loadModel.getLoadTag());
            fileDao.createDirectoryEntry(dataset, newEntry);
        } else {
            if (!StringUtils.equals(existingEntry.getLoadTag(), loadModel.getLoadTag())) {
                // (a) Exists and is not our file
                throw new FileAlreadyExistsException("Path already exists: " + targetPath);
            }
            // (b) or (c) Load tags match - check file ids
            if (!StringUtils.equals(existingEntry.getFileId(), fileId)) {
                // (c) We are in a re-run of a load job. Try to get the file entry.
                fileId = existingEntry.getFileId();
                workingMap.put(FileMapKeys.FILE_ID, fileId);
                FireStoreFile fileEntry = fileDao.lookupFile(dataset, fileId);
                if (fileEntry != null) {
                    // (c)(i) We successfully loaded this file already
                    workingMap.put(FileMapKeys.LOAD_COMPLETED, true);
                }
            // (c)(ii) We are recovering and should continue this load; leave load completed false/unset
            }
        }
    } catch (FileSystemAbortTransactionException rex) {
        return new StepResult(StepStatus.STEP_RESULT_FAILURE_RETRY, rex);
    }
    return StepResult.getStepResultSuccess();
}
Also used : FireStoreFile(bio.terra.service.filedata.google.firestore.FireStoreFile) FileAlreadyExistsException(bio.terra.service.filedata.exception.FileAlreadyExistsException) FlightMap(bio.terra.stairway.FlightMap) FileLoadModel(bio.terra.model.FileLoadModel) FileSystemAbortTransactionException(bio.terra.service.filedata.exception.FileSystemAbortTransactionException) StepResult(bio.terra.stairway.StepResult) FireStoreDirectoryEntry(bio.terra.service.filedata.google.firestore.FireStoreDirectoryEntry)

Example 13 with FlightMap

use of bio.terra.stairway.FlightMap in project jade-data-repo by DataBiosphere.

the class IngestFileIdStep method doStep.

@Override
public StepResult doStep(FlightContext context) {
    FlightMap workingMap = context.getWorkingMap();
    String fileId = UUID.randomUUID().toString();
    workingMap.put(FileMapKeys.FILE_ID, fileId);
    if (configService.testInsertFault(ConfigEnum.FILE_INGEST_LOCK_CONFLICT_STOP_FAULT)) {
        try {
            logger.info("FILE_INGEST_LOCK_CONFLICT_STOP_FAULT");
            while (!configService.testInsertFault(ConfigEnum.FILE_INGEST_LOCK_CONFLICT_CONTINUE_FAULT)) {
                logger.info("Sleeping for CONTINUE FAULT");
                TimeUnit.SECONDS.sleep(5);
            }
            logger.info("FILE_INGEST_LOCK_CONFLICT_CONTINUE_FAULT");
        } catch (InterruptedException intEx) {
            Thread.currentThread().interrupt();
            throw new DatasetLockException("Unexpected interrupt during file ingest lock fault", intEx);
        }
    }
    return StepResult.getStepResultSuccess();
}
Also used : DatasetLockException(bio.terra.service.dataset.exception.DatasetLockException) FlightMap(bio.terra.stairway.FlightMap)

Example 14 with FlightMap

use of bio.terra.stairway.FlightMap in project jade-data-repo by DataBiosphere.

the class IngestFilePrimaryDataLocationStep method doStep.

@Override
public StepResult doStep(FlightContext context) throws InterruptedException {
    FlightMap workingMap = context.getWorkingMap();
    Boolean loadComplete = workingMap.get(FileMapKeys.LOAD_COMPLETED, Boolean.class);
    if (loadComplete == null || !loadComplete) {
        try {
            GoogleBucketResource bucketForFile = locationService.getOrCreateBucketForFile(profileId, context.getFlightId());
            workingMap.put(FileMapKeys.BUCKET_INFO, bucketForFile);
        } catch (BucketLockException blEx) {
            return new StepResult(StepStatus.STEP_RESULT_FAILURE_RETRY, blEx);
        }
    }
    return StepResult.getStepResultSuccess();
}
Also used : GoogleBucketResource(bio.terra.service.resourcemanagement.google.GoogleBucketResource) FlightMap(bio.terra.stairway.FlightMap) StepResult(bio.terra.stairway.StepResult) BucketLockException(bio.terra.service.resourcemanagement.exception.BucketLockException)

Example 15 with FlightMap

use of bio.terra.stairway.FlightMap in project jade-data-repo by DataBiosphere.

the class IngestFilePrimaryDataStep method undoStep.

@Override
public StepResult undoStep(FlightContext context) {
    FlightMap workingMap = context.getWorkingMap();
    String fileId = workingMap.get(FileMapKeys.FILE_ID, String.class);
    GoogleBucketResource bucketResource = workingMap.get(FileMapKeys.BUCKET_INFO, GoogleBucketResource.class);
    gcsPdao.deleteFileById(dataset, fileId, bucketResource);
    return StepResult.getStepResultSuccess();
}
Also used : GoogleBucketResource(bio.terra.service.resourcemanagement.google.GoogleBucketResource) FlightMap(bio.terra.stairway.FlightMap)

Aggregations

FlightMap (bio.terra.stairway.FlightMap)147 StepResult (bio.terra.stairway.StepResult)38 UUID (java.util.UUID)29 FlightState (bio.terra.stairway.FlightState)20 DatabaseOperationException (bio.terra.stairway.exception.DatabaseOperationException)14 Test (org.junit.jupiter.api.Test)14 Dataset (bio.terra.service.dataset.Dataset)9 IOException (java.io.IOException)9 IamRole (bio.terra.service.iam.IamRole)8 AuthenticatedUserRequest (bio.terra.workspace.service.iam.AuthenticatedUserRequest)8 HashMap (java.util.HashMap)8 DuplicateFlightIdException (bio.terra.stairway.exception.DuplicateFlightIdException)7 CloningInstructions (bio.terra.workspace.service.resource.model.CloningInstructions)7 FlightDebugInfo (bio.terra.stairway.FlightDebugInfo)6 BaseConnectedTest (bio.terra.workspace.common.BaseConnectedTest)6 FileSystemAbortTransactionException (bio.terra.service.filedata.exception.FileSystemAbortTransactionException)5 Snapshot (bio.terra.service.snapshot.Snapshot)5 FlightNotFoundException (bio.terra.stairway.exception.FlightNotFoundException)5 StairwayExecutionException (bio.terra.stairway.exception.StairwayExecutionException)5 BaseUnitTest (bio.terra.workspace.common.BaseUnitTest)5