google-cloud-lib/src/main/java/com/streamsets/pipeline/stage/bigquery/lib/BigQueryDelegate.java
public TableResult runQuery(QueryJobConfiguration queryConfig, long timeout, long pageSize) throws
      StageException {
    checkArgument(timeout >= 1000, "Timeout must be at least one second.");
    Instant maxTime = Instant.now().plusMillis(timeout);

    // Create a job ID so that we can safely retry.
    JobId jobId = JobId.of(UUID.randomUUID().toString());
    JobInfo jobInfo = JobInfo.newBuilder(queryConfig).setJobId(jobId).build();
    Job queryJob = bigquery.create(jobInfo);

    // Check for errors
    if (queryJob == null) {
      LOG.error("Job no longer exists: {}", jobInfo);
      throw new RuntimeException("Job no longer exists: "+jobInfo);
    } else if (queryJob.getStatus().getError() != null) {
      BigQueryError error = queryJob.getStatus().getError();
      LOG.error("Query Job execution error: {}", error);
      throw new StageException(Errors.BIGQUERY_02, error);
    }

    //Should consider using .waitFor(RetryOption.totalTimeout())
    while(!queryJob.isDone()) {
      if (Instant.now(clock).isAfter(maxTime) || !ThreadUtil.sleep(100)) {
        if (bigquery.cancel(queryJob.getJobId())) {
          LOG.info("Job {} cancelled successfully.", queryJob.getJobId());
        } else {
          LOG.warn("Job {} not found", queryJob.getJobId());
        }
        throw new StageException(Errors.BIGQUERY_00);
      }
    }


    if (queryJob.getStatus().getError() != null) {
      String errorMsg = queryJob.getStatus().getError().toString();
      throw new StageException(Errors.BIGQUERY_02, errorMsg);
    }

    // Get the results.
    TableResult result = null;
    try {
      result = queryJob.getQueryResults(QueryResultsOption.pageSize(pageSize));
    } catch (InterruptedException e) {
      String errorMsg = e.getMessage();
      throw new StageException(Errors.BIGQUERY_02, errorMsg);
    }

    return result;
  }
public TableResult runQuery(QueryJobConfiguration queryConfig, long timeout, long pageSize) throws
      StageException {
    checkArgument(timeout >= 1000, "Timeout must be at least one second.");
    Instant maxTime = Instant.now().plusMillis(timeout);

    // Create a job ID so that we can safely retry.
    JobId jobId = JobId.of(UUID.randomUUID().toString());
    JobInfo jobInfo = JobInfo.newBuilder(queryConfig).setJobId(jobId).build();
    Job queryJob = bigquery.create(jobInfo);

    // Check for errors
    if (queryJob == null) {
      LOG.error("Job no longer exists: {}", jobInfo);
      throw new RuntimeException("Job no longer exists: "+jobInfo);
    } else if (queryJob.getStatus().getError() != null) {
      BigQueryError error = queryJob.getStatus().getError();
      LOG.error("Query Job execution error: {}", error);
      throw new StageException(Errors.BIGQUERY_02, error);
    }

    //Should consider using .waitFor(RetryOption.totalTimeout())
    while(!queryJob.isDone()) {
      if (Instant.now(clock).isAfter(maxTime) || !ThreadUtil.sleep(100)) {
        if (bigquery.cancel(queryJob.getJobId())) {
          LOG.info("Job {} cancelled successfully.", queryJob.getJobId());
        } else {
          LOG.warn("Job {} not found", queryJob.getJobId());
        }
        throw new StageException(Errors.BIGQUERY_00);
      }
    }


    if (queryJob.getStatus().getError() != null) {
      String errorMsg = queryJob.getStatus().getError().toString();
      throw new StageException(Errors.BIGQUERY_02, errorMsg);
    }

    // Get the results.
    TableResult result = null;
    try {
      result = queryJob.getQueryResults(QueryResultsOption.pageSize(pageSize));
    } catch (InterruptedException e) {
      String errorMsg = e.getMessage();
      throw new StageException(Errors.BIGQUERY_02, errorMsg);
    }

    return result;
  }
Executes a query request and returns the results. A timeout is required to avoid
waiting for an indeterminate amount of time. If the query fails to complete within the
timeout it is aborted.

@param queryConfig request describing the query to execute
@param timeout maximum amount of time to wait for job completion before attempting to cancel
@return result of the query.
@throws StageException if the query does not complete within the requested timeout or
there is an error executing the query.