Использовать TransferManager для загрузки каталога на s3 в Java не удалось без исключения - PullRequest
0 голосов
/ 13 декабря 2018

Я использую TransferManager для загрузки каталога (включая большое количество файлов от 10k до 100k) на s3, и я обнаружил, что иногда загрузка может быть неудачной или зависает без каких-либо исключений или обработчика успеха.Журнал просто показывает, что он начал загружаться на s3, но он никогда не показывает, что он закончился или не прошел.

Я показываю свой код ниже, надеюсь, кто-то может помочь мне выяснить, что происходит не так.

@PostMapping
public ResponseEntity upload(
    @RequestPart("file") @Valid
    MultipartFile file) throws IOException {
  try {
    File dest = File.createTempFile(UUID.randomUUID().toString(), "zip");
    if (!dest.getParentFile().exists()) {
      Files.createDirectories(dest.getParentFile().toPath());
    }
    file.transferTo(dest);
    CompletableFuture.supplyAsync(() -> {
      try {
        long size = fileUploadService
            .upload(new FileInputStream(dest),uploadDescriptor.getTargetPath());
        if (size <= 0) {
          log.fail();
        } else {
          log.success();
        }
      } catch (FileNotFoundException e) {
        log.fail();
        log.error(e.getMessage());
        e.printStackTrace();
      }
      return dest.delete();
    }, executor);
  } catch (IOException e) {
    log.error(e.getMessage());
    e.printStackTrace();
  }

  return ResponseEntity.accepted().build();
}

А вот это FileUploadService:

public class FileUploadService {

  private StorageService storageService;

  @Autowired
  public FileUploadService(StorageService storageService) {
    this.storageService = storageService;
  }

  public long upload(InputStream inputStream, String path) {
    try {
      Path tempDirectory = Files.createTempDirectory(UUID.randomUUID().toString());
      unzip(inputStream, tempDirectory);
      long size = FileUtils.sizeOfDirectory(tempDirectory.toFile());
      boolean isSuccess = storageService.storeDir(tempDirectory.toFile(), path);
      FileSystemUtils.deleteRecursively(tempDirectory);
      return isSuccess ? size : -1;
    } catch (IOException e) {
      e.printStackTrace();
      log.error("failed to update to {}", path);
      log.error(e.getMessage());
      return -1;
    }
  }
}

Вот это StorageService:

@Slf4j
public class StorageService {

  private static final String SUFFIX = "/";
  private S3Configuration configuration;
  private final AmazonS3 s3Client;

  @Autowired
  public S3StorageService(S3Configuration configuration) {
    this.configuration = configuration;
    BasicAWSCredentials awsCreds = new BasicAWSCredentials(
        configuration.getAccessKey(), configuration.getAccessSecret());
    s3Client = AmazonS3ClientBuilder.standard()
        .withRegion(configuration.getRegion())
        .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
        .build();
  }

  @Override
  public boolean storeDir(File file, String fullPath) {
    log.info("start upload from {} to {}", file.toString(), fullPath);
    TransferManager manager = TransferManagerBuilder.standard().withS3Client(s3Client).build();
    try {
      MultipleFileUpload xfer = manager.uploadDirectory(configuration.getBucketName(),
                                                        fullPath, file, true);
      xfer.waitForCompletion();
      log.info("finish upload from {} to {}", file.toString(), fullPath);
      return true;
    } catch (AmazonServiceException | InterruptedException e) {
      e.printStackTrace();
      log.error("failed to update from {} to {}", file.toString(), fullPath);
      log.error(e.getMessage());
      return false;
    } finally {
      manager.shutdownNow(false);
    }
  }
}

1 Ответ

0 голосов
/ 14 декабря 2018

Почему бы вам не попробовать "waitForException"?Или, еще лучше, отслеживать ход выполнения, чтобы вы могли видеть, как далеко он продвигается, и проверять наличие ошибок / завершение в конце, а когда он завершается, проверять состояние на наличие ошибок и т. Д.

...