Search in sources :

Example 1 with ErrorDetail

use of org.datatransferproject.types.transfer.errors.ErrorDetail in project data-transfer-project by google.

the class LocalJobStore method addErrorsToJob.

@Override
public void addErrorsToJob(UUID jobId, Collection<ErrorDetail> errors) throws IOException {
    // This is a no-op currently as nothing in DTP reads the errors currently.
    if (errors != null && !errors.isEmpty()) {
        for (ErrorDetail error : errors) {
            String errorString = OBJECT_MAPPER.writeValueAsString(error);
            monitor.info(() -> "Added error: " + errorString);
        }
    }
}
Also used : ErrorDetail(org.datatransferproject.types.transfer.errors.ErrorDetail)

Example 2 with ErrorDetail

use of org.datatransferproject.types.transfer.errors.ErrorDetail in project data-transfer-project by google.

the class GoogleCloudIdempotentImportExecutor method getErrorDetailsForJob.

private Map<String, ErrorDetail> getErrorDetailsForJob(UUID jobId) {
    Map<String, ErrorDetail> datastoreKnownErrors = new HashMap<>();
    Query<Entity> query = Query.newEntityQueryBuilder().setKind(IDEMPONTENT_ERRORS_KIND).setFilter(CompositeFilter.and(PropertyFilter.eq(JOB_ID_FIELD, String.valueOf(jobId)))).build();
    QueryResults<Entity> results = datastore.run(query);
    while (results.hasNext()) {
        Entity result = results.next();
        try {
            ErrorDetail error = objectMapper.readerFor(ErrorDetail.class).readValue(result.getString(ERROR_FIELD));
            datastoreKnownErrors.put(result.getString(IDEMPOTENT_ID_FIELD), error);
        } catch (IOException e) {
            monitor.severe(() -> jobIdPrefix + "Unable to parse ErrorDetail: " + e);
            throw new IllegalStateException(e);
        }
    }
    return datastoreKnownErrors;
}
Also used : ErrorDetail(org.datatransferproject.types.transfer.errors.ErrorDetail) HashMap(java.util.HashMap) IOException(java.io.IOException)

Example 3 with ErrorDetail

use of org.datatransferproject.types.transfer.errors.ErrorDetail in project data-transfer-project by google.

the class CallableImporter method call.

@Override
public ImportResult call() throws Exception {
    boolean success = false;
    Stopwatch stopwatch = Stopwatch.createStarted();
    try {
        idempotentImportExecutor.resetRecentErrors();
        ImportResult result = importerProvider.get().importItem(jobId, idempotentImportExecutor, authData, data);
        Collection<ErrorDetail> errors = idempotentImportExecutor.getRecentErrors();
        success = result.getType() == ImportResult.ResultType.OK && errors.isEmpty();
        if (!success) {
            throw new IOException("Problem with importer, forcing a retry, " + "first error: " + (errors.iterator().hasNext() ? errors.iterator().next().exception() : "none"));
        }
        result = result.copyWithCounts(data.getCounts());
        return result;
    } finally {
        metricRecorder.importPageAttemptFinished(JobMetadata.getDataType(), JobMetadata.getImportService(), success, stopwatch.elapsed());
    }
}
Also used : ErrorDetail(org.datatransferproject.types.transfer.errors.ErrorDetail) ImportResult(org.datatransferproject.spi.transfer.provider.ImportResult) Stopwatch(com.google.common.base.Stopwatch) IOException(java.io.IOException)

Example 4 with ErrorDetail

use of org.datatransferproject.types.transfer.errors.ErrorDetail in project data-transfer-project by google.

the class JobProcessor method processJob.

/**
 * Process our job, whose metadata is available via {@link JobMetadata}.
 */
void processJob() {
    boolean success = false;
    UUID jobId = JobMetadata.getJobId();
    monitor.debug(() -> format("Begin processing jobId: %s", jobId), EventCode.WORKER_JOB_STARTED);
    Collection<ErrorDetail> errors = null;
    try {
        markJobStarted(jobId);
        hooks.jobStarted(jobId);
        PortabilityJob job = store.findJob(jobId);
        JobAuthorization jobAuthorization = job.jobAuthorization();
        monitor.debug(() -> format("Starting copy job, id: %s, source: %s, destination: %s", jobId, job.exportService(), job.importService()));
        String scheme = jobAuthorization.encryptionScheme();
        AuthDataDecryptService decryptService = getAuthDecryptService(scheme);
        if (decryptService == null) {
            monitor.severe(() -> format("No auth decrypter found for scheme %s while processing job: %s", scheme, jobId));
            return;
        }
        String encrypted = jobAuthorization.encryptedAuthData();
        byte[] encodedPrivateKey = JobMetadata.getPrivateKey();
        AuthDataPair pair = decryptService.decrypt(encrypted, encodedPrivateKey);
        AuthData exportAuthData = objectMapper.readValue(pair.getExportAuthData(), AuthData.class);
        AuthData importAuthData = objectMapper.readValue(pair.getImportAuthData(), AuthData.class);
        String exportInfoStr = job.exportInformation();
        Optional<ExportInformation> exportInfo = Optional.empty();
        if (!Strings.isNullOrEmpty(exportInfoStr)) {
            exportInfo = Optional.of(objectMapper.readValue(exportInfoStr, ExportInformation.class));
        }
        // Copy the data
        dtpInternalMetricRecorder.startedJob(JobMetadata.getDataType(), JobMetadata.getExportService(), JobMetadata.getImportService());
        JobMetadata.getStopWatch().start();
        errors = copier.copy(exportAuthData, importAuthData, jobId, exportInfo);
        final int numErrors = errors.size();
        monitor.debug(() -> format("Finished copy for jobId: %s with %d error(s).", jobId, numErrors));
        success = errors.isEmpty();
    } catch (CopyExceptionWithFailureReason e) {
        String failureReason = e.getFailureReason();
        if (failureReason.contains(FailureReasons.DESTINATION_FULL.toString())) {
            monitor.info(() -> "The remaining storage in the user's account is not enough to perform this operation.", e);
        } else if (failureReason.contains(FailureReasons.INVALID_TOKEN.toString()) || failureReason.contains(FailureReasons.SESSION_INVALIDATED.toString()) || failureReason.contains(FailureReasons.UNCONFIRMED_USER.toString()) || failureReason.contains(FailureReasons.USER_CHECKPOINTED.toString())) {
            monitor.info(() -> "Got token error", e);
        } else {
            monitor.severe(() -> format("Error with failure code '%s' while processing jobId: %s", failureReason, jobId), e, EventCode.WORKER_JOB_ERRORED);
        }
        addFailureReasonToJob(jobId, failureReason);
    } catch (IOException | CopyException | RuntimeException e) {
        monitor.severe(() -> "Error processing jobId: " + jobId, e, EventCode.WORKER_JOB_ERRORED);
    } finally {
        monitor.debug(() -> "Finished processing jobId: " + jobId, EventCode.WORKER_JOB_FINISHED);
        addErrorsAndMarkJobFinished(jobId, success, errors);
        hooks.jobFinished(jobId, success);
        dtpInternalMetricRecorder.finishedJob(JobMetadata.getDataType(), JobMetadata.getExportService(), JobMetadata.getImportService(), success, JobMetadata.getStopWatch().elapsed());
        monitor.flushLogs();
        JobMetadata.reset();
    }
}
Also used : JobAuthorization(org.datatransferproject.spi.cloud.types.JobAuthorization) CopyException(org.datatransferproject.spi.transfer.types.CopyException) AuthData(org.datatransferproject.types.transfer.auth.AuthData) CopyExceptionWithFailureReason(org.datatransferproject.spi.transfer.types.CopyExceptionWithFailureReason) AuthDataDecryptService(org.datatransferproject.spi.transfer.security.AuthDataDecryptService) IOException(java.io.IOException) ErrorDetail(org.datatransferproject.types.transfer.errors.ErrorDetail) PortabilityJob(org.datatransferproject.spi.cloud.types.PortabilityJob) ExportInformation(org.datatransferproject.types.common.ExportInformation) UUID(java.util.UUID) AuthDataPair(org.datatransferproject.types.transfer.auth.AuthDataPair)

Example 5 with ErrorDetail

use of org.datatransferproject.types.transfer.errors.ErrorDetail in project data-transfer-project by google.

the class GooglePhotosImporterTest method importTwoPhotosWithFailure.

@Test
public void importTwoPhotosWithFailure() throws Exception {
    PhotoModel photoModel1 = new PhotoModel(PHOTO_TITLE, IMG_URI, PHOTO_DESCRIPTION, JPEG_MEDIA_TYPE, "oldPhotoID1", OLD_ALBUM_ID, false);
    PhotoModel photoModel2 = new PhotoModel(PHOTO_TITLE, IMG_URI, PHOTO_DESCRIPTION, JPEG_MEDIA_TYPE, "oldPhotoID2", OLD_ALBUM_ID, false);
    Mockito.when(googlePhotosInterface.uploadPhotoContent(any())).thenReturn("token1", "token2");
    BatchMediaItemResponse batchMediaItemResponse = new BatchMediaItemResponse(new NewMediaItemResult[] { buildMediaItemResult("token1", Code.OK_VALUE), buildMediaItemResult("token2", Code.UNAUTHENTICATED_VALUE) });
    Mockito.when(googlePhotosInterface.createPhotos(any(NewMediaItemUpload.class))).thenReturn(batchMediaItemResponse);
    long length = googlePhotosImporter.importPhotoBatch(UUID.randomUUID(), Mockito.mock(TokensAndUrlAuthData.class), Lists.newArrayList(photoModel1, photoModel2), executor, NEW_ALBUM_ID);
    // Only one photo of 32L imported
    assertEquals(32L, length);
    assertTrue(executor.isKeyCached(String.format("%s-%s", OLD_ALBUM_ID, "oldPhotoID1")));
    String failedDataId = String.format("%s-%s", OLD_ALBUM_ID, "oldPhotoID2");
    assertFalse(executor.isKeyCached(failedDataId));
    ErrorDetail errorDetail = executor.getErrors().iterator().next();
    assertEquals(failedDataId, errorDetail.id());
    assertThat(errorDetail.exception(), CoreMatchers.containsString("Media item could not be created."));
}
Also used : ErrorDetail(org.datatransferproject.types.transfer.errors.ErrorDetail) BatchMediaItemResponse(org.datatransferproject.datatransfer.google.mediaModels.BatchMediaItemResponse) PhotoModel(org.datatransferproject.types.common.models.photos.PhotoModel) TokensAndUrlAuthData(org.datatransferproject.types.transfer.auth.TokensAndUrlAuthData) NewMediaItemUpload(org.datatransferproject.datatransfer.google.mediaModels.NewMediaItemUpload) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Test(org.junit.Test)

Aggregations

ErrorDetail (org.datatransferproject.types.transfer.errors.ErrorDetail)7 IOException (java.io.IOException)3 Test (org.junit.Test)2 Entity (com.google.cloud.datastore.Entity)1 Key (com.google.cloud.datastore.Key)1 Stopwatch (com.google.common.base.Stopwatch)1 PhotosLibraryClient (com.google.photos.library.v1.PhotosLibraryClient)1 BatchCreateMediaItemsResponse (com.google.photos.library.v1.proto.BatchCreateMediaItemsResponse)1 NewMediaItemResult (com.google.photos.library.v1.proto.NewMediaItemResult)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 UUID (java.util.UUID)1 Monitor (org.datatransferproject.api.launcher.Monitor)1 BatchMediaItemResponse (org.datatransferproject.datatransfer.google.mediaModels.BatchMediaItemResponse)1 NewMediaItemUpload (org.datatransferproject.datatransfer.google.mediaModels.NewMediaItemUpload)1 JobAuthorization (org.datatransferproject.spi.cloud.types.JobAuthorization)1 PortabilityJob (org.datatransferproject.spi.cloud.types.PortabilityJob)1 InMemoryIdempotentImportExecutor (org.datatransferproject.spi.transfer.idempotentexecutor.InMemoryIdempotentImportExecutor)1 ImportResult (org.datatransferproject.spi.transfer.provider.ImportResult)1 AuthDataDecryptService (org.datatransferproject.spi.transfer.security.AuthDataDecryptService)1