private ItemImportResult<String> importSinglePhoto(
      PhotoModel photo,
      UUID jobId,
      IdempotentImportExecutor idempotentImportExecutor,
      KoofrClient koofrClient)
      throws IOException, InvalidTokenException, DestinationMemoryFullException {
    monitor.debug(() -> String.format("Import single photo %s", photo.getTitle()));
    Long size = null;
    try {
      InputStreamWrapper inputStreamWrapper =
          connectionProvider.getInputStreamForItem(jobId, photo);
      ItemImportResult<String> response;

      try (InputStream inputStream = inputStreamWrapper.getStream()) {
        final byte[] bytes = IOUtils.toByteArray(inputStream);

        Date dateCreated = getDateCreated(photo, bytes);

        String title = buildPhotoTitle(jobId, photo.getTitle(), dateCreated);
        String description = KoofrClient.trimDescription(photo.getDescription());

        String parentPath = idempotentImportExecutor.getCachedValue(photo.getAlbumId());
        String fullPath = parentPath + "/" + title;

        if (koofrClient.fileExists(fullPath)) {
          monitor.debug(() -> String.format("Photo already exists %s", photo.getTitle()));

          return ItemImportResult.success(fullPath);
        }

        final ByteArrayInputStream inMemoryInputStream = new ByteArrayInputStream(bytes);

        try {
          long inputStreamBytes = inputStreamWrapper.getBytes();
          String stringResult =
              koofrClient.uploadFile(
                  parentPath,
                  title,
                  inMemoryInputStream,
                  photo.getMediaType(),
                  dateCreated,
                  description);
          if (stringResult != null && !stringResult.isEmpty()) {
            response = ItemImportResult.success(stringResult, inputStreamBytes);
          } else {
            response =
                ItemImportResult.success(
                    String.format(SKIPPED_FILE_RESULT_FORMAT, photo.getDataId()));
          }
          size = inputStreamBytes;
        } catch (KoofrClientIOException exception) {
          if (exception.getCode() == 404) {
            monitor.info(
                () ->
                    String.format(
                        "Can't find album during importSingleItem for id: %s", photo.getDataId()),
                exception);
            response =
                ItemImportResult.success(
                    String.format(SKIPPED_FILE_RESULT_FORMAT, photo.getDataId()));
          } else {
            return ItemImportResult.error(exception, size);
          }
        }

        try {
          if (photo.isInTempStore()) {
            jobStore.removeData(jobId, photo.getFetchableUrl());
          }
        } catch (Exception e) {
          // Swallow the exception caused by Remove data so that existing flows continue
          monitor.info(
              () ->
                  format(
                      "Exception swallowed while removing data for jobId %s, localPath %s",
                      jobId, photo.getFetchableUrl()),
              e);
        }
      }

      return response;
    } catch (KoofrClientIOException exception) {
      return ItemImportResult.error(exception, size);
    }
  }
Imports albums and photos to Koofr.
extensions/data-transfer/portability-data-transfer-koofr/src/main/java/org/datatransferproject/transfer/koofr/photos/KoofrPhotosImporter.java