akka-http elasticsearch {"error":"no handler found for uri [https://localhost:9200/myindex/_bulk] and method [POST]"}

huangapple go评论86阅读模式
英文:

akka-http elasticsearch {"error":"no handler found for uri [https://localhost:9200/myindex/_bulk] and method [POST]"}

问题

你遇到的问题可能是由于缺少正确的请求处理程序或URI路径导致的。请检查以下几点:

  1. 确保 Elasticsearch 8.7.0 正在运行,而且能够通过 https://localhost:9200 访问。

  2. 确保你的 Elasticsearch 8.7.0 支持 _bulk 操作。有时,Elasticsearch 的配置可能需要启用 _bulk 操作,否则默认情况下可能不支持。

  3. 检查你的 Akka HTTP 请求是否正确。确保 URI 路径是正确的,并且请求的方法是 POST

如果以上检查都没有问题,仍然遇到问题,那么可能需要更详细的 Elasticsearch 和 Akka HTTP 配置信息,以便更好地帮助你解决问题。

英文:

So, I am using elasticsearch 8.7.0.
I create index 'my index':

  1. curl --insecure --user "elastic:password" -X PUT "https://localhost:9200/myindex"

I can add JSON documents manually to elasticsearch 8.7.0 using curl

  1. curl --insecure --user "elastic:password" -X POST "https://localhost:9200/myindex/_bulk" -H 'Content-Type: application/json' -d'{"some": "json"}'

but when I try to do it programmatically with akka-http in Scala 3 using the code below:

  1. @main
  2. def main(args: String*): Unit = {
  3. val records = Seq(
  4. """{ "index":{ "_index" : "myindex", "_id" : "1" } }
  5. |{"title":"title1"}""".stripMargin,
  6. """{ "index":{ "_index" : "myindex", "_id" : "2" } }
  7. |{"title":"title2"}""".stripMargin,
  8. """{ "index":{ "_index" : "myindex", "_id" : "3" } }
  9. |{"title":"title3"}""".stripMargin,
  10. """{ "index":{ "_index" : "myindex", "_id" : "4" } }
  11. |{"title":"title4"}""".stripMargin)
  12. implicit val system: ActorSystem = ActorSystem("elastic")
  13. implicit val ec: ExecutionContextExecutor = system.dispatcher
  14. val trustfulSslContext: SSLContext = {
  15. // https://github.com/raboof/akka-http-connect-without-checking-cert/blob/0ca55a06afb83b587f592dd97358970502f7b834/Main.scala
  16. object NoCheckX509TrustManager extends X509TrustManager {
  17. override def checkClientTrusted(chain: Array[X509Certificate], authType: String): Unit = ()
  18. override def checkServerTrusted(chain: Array[X509Certificate], authType: String): Unit = ()
  19. override def getAcceptedIssuers: Array[X509Certificate] = Array[X509Certificate]()
  20. }
  21. val context: SSLContext = SSLContext.getInstance("TLS")
  22. context.init(Array[KeyManager](), Array(NoCheckX509TrustManager), new SecureRandom())
  23. context
  24. }
  25. Source
  26. .fromIterator[String]( () => records.iterator )
  27. .grouped(2)
  28. .map(_.mkString("\n"))
  29. .map { payload =>
  30. val entity = HttpEntity(ContentTypes.`application/json`, payload)
  31. val request = HttpRequest(
  32. HttpMethods.POST,
  33. uri = Uri("https://localhost:9200/myindex/_bulk"),
  34. headers = Seq(headers.Authorization(BasicHttpCredentials("elastic", "password"))),
  35. entity = entity
  36. )
  37. println(s"request: $request")
  38. request
  39. }
  40. .via(Http().outgoingConnectionHttps(host = "localhost", port = 9200, connectionContext = ConnectionContext.httpsClient(trustfulSslContext)))
  41. .map(response => {
  42. println(s"response: ${response.entity.toStrict(1 second).map(_.data.utf8String)}")
  43. response
  44. })
  45. .toMat(Sink.ignore)(Keep.none)
  46. .run()
  47. }

I get the following output

  1. request: HttpRequest(HttpMethod(POST),https://localhost:9200/myindex/_bulk,List(Authorization),HttpEntity.Strict(application/json,137 bytes total),HttpProtocol(HTTP/1.1))
  2. response: FulfilledFuture({"error":"no handler found for uri [https://localhost:9200/myindex/_bulk] and method [POST]"})
  3. request: HttpRequest(HttpMethod(POST),https://localhost:9200/myindex/_bulk,List(Authorization),HttpEntity.Strict(application/json,137 bytes total),HttpProtocol(HTTP/1.1))
  4. response: FulfilledFuture({"error":"no handler found for uri [https://localhost:9200/myindex/_bulk] and method [POST]"})

What am I missing?

答案1

得分: 0

明显地,URI 只能包含路径部分,而不是完整的 URL。

Uri("https://localhost:9200/myindex/_bulk") 替换为 Uri("/myindex/_bulk") 可以解决这个问题。

此外,负载必须以 \n 结尾,所以我还不得不将 .map(_.mkString("\n")) 替换为 .map(_.mkString("", "\n", "\n")) 以使其正常工作。

英文:

Apparently, the URI can only contain the path, not the full URL.

Replacing Uri("https://localhost:9200/myindex/_bulk") by Uri("/myindex/_bulk") in the HttpRequest fixes the problem.

Additionally, the payload must end by \n so, I also had to replace .map(_.mkString("\n")) by .map(_.mkString("", "\n", "\n")) to get it to work.

huangapple
  • 本文由 发表于 2023年5月15日 05:19:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76249733.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定