Проблема с подключением Alpakka S3

Я пытаюсь использовать Alpakka S3 для подключения к экземпляру minio для хранения файлов, но у меня возникают проблемы, так как я обновил версию библиотеки с 1.1.2 до 2.0.0.

Вот простой сервисный класс всего с двумя методами, которые пытаются создать корзину. Я пробовал оба подхода, сначала загружая настройки alpakka из локального конфигурационного файла (в моем случае application.conf), а затем путем прямого создания настроек через S3Ext.

Оба метода терпят неудачу, и я не уверен в проблеме. По поводу ошибки, вроде не правильно подгружаются настройки, но я не знаю, что я тут не так делаю.

Что я использую:

  • игровой фреймворк 2.8.1
  • скала 2.13.2
  • акка-поток-alpakka-s3 2.0.0

Вот класс обслуживания:

package services

import akka.actor.ActorSystem
import akka.stream.alpakka.s3._
import akka.stream.alpakka.s3.scaladsl.S3
import akka.stream.scaladsl.Sink
import akka.stream.{Attributes, Materializer}
import javax.inject.{Inject, Singleton}
import software.amazon.awssdk.auth.credentials.{AwsBasicCredentials, AwsCredentials, AwsCredentialsProvider}
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.regions.providers.AwsRegionProvider

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

@Singleton
class AlpakkaS3PlaygroundService @Inject()(
    materializer: Materializer,
    system: ActorSystem,
) {

  def makeBucket(bucketName: String): Future[String] = {
    S3.makeBucket(bucketName)(materializer) map { _ =>
      "bucket created"
    }
  }

  def makeBucket2(bucketName: String): Future[String] = {

    val s3Host      = "http://localhost:9000"
    val s3AccessKey = "access_key"
    val s3SecretKey = "secret_key"
    val s3Region    = "eu-central-1"

    val credentialsProvider = new AwsCredentialsProvider {
      override def resolveCredentials(): AwsCredentials = AwsBasicCredentials.create(s3AccessKey, s3SecretKey)
    }

    val regionProvider = new AwsRegionProvider {
      override def getRegion: Region = Region.of(s3Region)
    }

    val settings: S3Settings = S3Ext(system).settings
      .withEndpointUrl(s3Host)
      .withBufferType(MemoryBufferType)
      .withCredentialsProvider(credentialsProvider)
      .withListBucketApiVersion(ApiVersion.ListBucketVersion2)
      .withS3RegionProvider(regionProvider)

    val attributes: Attributes = S3Attributes.settings(settings)

    S3.makeBucketSource(bucketName)
      .withAttributes(attributes)
      .runWith(Sink.head)(materializer) map { _ =>
      "bucket created"
    }
  }
}

Конфиг в application.conf выглядит так:

akka.stream.alpakka.s3 {
  aws {
    credentials {
      provider = static
      access-key-id = "access_key"
      secret-access-key = "secret_key"
    }
    region {
      provider = static
      default-region = "eu-central-1"
    }
  }
  endpoint-url = "http://localhost:9000"
}

Если используется первый метод службы (makeBucket(...)), я вижу эту ошибку:

SdkClientException: Unable to load region from any of the providers in the chain software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain@34cb16dc: 
[software.amazon.awssdk.regions.providers.SystemSettingsRegionProvider@804e08b: Unable to load region from system settings. Region must be specified either via environment variable (AWS_REGION) or  system property (aws.region)., software.amazon.awssdk.regions.providers.AwsProfileRegionProvider@4d5f4b4d: No region provided in profile: default, software.amazon.awssdk.regions.providers.InstanceProfileRegionProvider@557feb58: Unable to contact EC2 metadata service.]

Сообщение об ошибке довольно точное, и я знаю, что не так, но я просто не знаю, что делать, потому что я указал настройки, как указано в документации. Есть идеи?

Во втором методе службы (makeBucket2(...)) я пытаюсь явно задать настройку S3, но это тоже не работает. Ошибка выглядит следующим образом:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[S3Exception: 404 page not found
]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:335)
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:253)
    at play.core.server.AkkaHttpServer$$anonfun$2.applyOrElse(AkkaHttpServer.scala:424)
    at play.core.server.AkkaHttpServer$$anonfun$2.applyOrElse(AkkaHttpServer.scala:420)
    at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:453)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:92)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18)
    at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:94)
    at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:92)
    at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:47)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:47)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
Caused by: akka.stream.alpakka.s3.S3Exception: 404 page not found

Здесь похоже, что заданная настройка вообще не учитывается, так как служба вроде бы не найдена. На самом деле это подход, который я использовал в предыдущей версии своего программного обеспечения, где я использовал akka-stream-alpakka-s3 версии 1.1.2, и она работала, как и ожидалось.

Конечно, я хочу использовать Alpakka S3 не только для создания ведер, но ради этой демонстрации и для того, чтобы обозначить мою проблему, я упростил ее только на этом примере. Я думаю, если эта проблема будет решена, все остальные методы, предоставляемые alpakka, будут работать.

Я действительно несколько раз пересматривал документацию, но я все еще не могу решить эту проблему, поэтому я надеюсь, что кто-то здесь может мне помочь.


person schub    schedule 21.05.2020    source источник


Ответы (2)


По крайней мере, начиная с 2.0.0, путь конфигурации для Alpakka S3 теперь alpakka.s3, а не akka.stream.alpakka.s3.

alpakka.s3 {
  aws {
    credentials {
      provider = static
      access-key-id = "access_key"
      secret-access-key = "secret_key"
    }
    region {
      provider = static
      default-region = "eu-central-1"
    }
  }
  endpoint-url = "http://localhost:9000"
}
person Levi Ramsey    schedule 21.05.2020
comment
Изменение пути конфигурации решило проблему региона, но теперь я получаю ту же ошибку, что и для второго метода. S3Exception: 404 page not found. Но я уверен, что URL-адрес и учетные данные верны, поскольку они используются другими службами, и я также могу открыть пользовательский интерфейс minio в браузере. Почему-то URL-адрес конечной точки загружается неправильно. ??? - person schub; 21.05.2020

Мне помогли на форуме изгиба света здесь.

Проблема решилась установкой следующего параметра:

alpakka.s3.path-style-access = true

Поскольку в документации сказано, что это значение будет объявлено устаревшим, я не стал указывать его.

В своем исходном посте я описал два подхода к настройке параметров: один через application.conf, а другой программно через S3Ext. Первый работает, устанавливая значение, как показано выше, второй подход выглядит так:

val settings: S3Settings = S3Ext(system).settings
      .withEndpointUrl(s3Host)
      .withBufferType(MemoryBufferType)
      .withCredentialsProvider(credentialsProvider)
      .withListBucketApiVersion(ApiVersion.ListBucketVersion2)
      .withS3RegionProvider(regionProvider)
      .withPathStyleAccess(true)

Здесь последняя строка имеет решающее значение, хотя я получаю предупреждение об устаревании.

Но, в конце концов, это решило проблему.

person schub    schedule 22.05.2020