使用Apache Fink的ECE ElasticSearch Sink进行身份验证(Scala代码)

时间:2019-05-25 23:33:03

标签: scala elasticsearch apache-flink flink-streaming

使用Flink文档中提供的示例时,编译器错误。 Flink文档提供了示例Scala代码,用于在与Elasticsearch https://ci.apache.org/projects/flink/flink-docs-stable/dev/connectors/elasticsearch.html进行对话时设置REST客户端工厂参数。 尝试这段代码时,我在IntelliJ中收到一个编译器错误,提示“无法解析符号restClientBuilder”。

我发现以下SO正是我的问题,除了它在Java中而且我在Scala中这样做。 Apache Flink (v1.6.0) authenticate Elasticsearch Sink (v6.4)

我尝试将上述SO中提供的解决方案代码粘贴粘贴到IntelliJ中,自动转换的代码也存在编译器错误。

      // provide a RestClientFactory for custom configuration on the internally created REST client
      // i only show the setMaxRetryTimeoutMillis for illustration purposes, the actual code will use HTTP cutom callback
      esSinkBuilder.setRestClientFactory(
        restClientBuilder -> {
          restClientBuilder.setMaxRetryTimeoutMillis(10)
        }
      )

然后我尝试了一下(由IntelliJ自动生成Java到Scala代码)

// provide a RestClientFactory for custom configuration on the internally created REST client// provide a RestClientFactory for custom configuration on the internally created REST client
      import org.apache.http.auth.AuthScope
      import org.apache.http.auth.UsernamePasswordCredentials
      import org.apache.http.client.CredentialsProvider
      import org.apache.http.impl.client.BasicCredentialsProvider
      import org.apache.http.impl.nio.client.HttpAsyncClientBuilder
      import org.elasticsearch.client.RestClientBuilder
      // provide a RestClientFactory for custom configuration on the internally created REST client// provide a RestClientFactory for custom configuration on the internally created REST client

      esSinkBuilder.setRestClientFactory((restClientBuilder) => {
        def foo(restClientBuilder) = restClientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
          override def customizeHttpClient(httpClientBuilder: HttpAsyncClientBuilder): HttpAsyncClientBuilder = { // elasticsearch username and password
            val credentialsProvider = new BasicCredentialsProvider
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(es_user, es_password))
            httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
          }
        })

        foo(restClientBuilder)
      })

原始代码段会产生错误“无法解析RestClientFactory”,然后Java到Scala会显示其他错误。

所以基本上我需要找到Apache Flink (v1.6.0) authenticate Elasticsearch Sink (v6.4)

中描述的解决方案的Scala版本

更新1 :在IntelliJ的帮助下,我取得了一些进展。以下代码可以编译并运行,但是还有另一个问题。

esSinkBuilder.setRestClientFactory(
          new RestClientFactory {
            override def configureRestClientBuilder(restClientBuilder: RestClientBuilder): Unit = {
              restClientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                override def customizeHttpClient(httpClientBuilder: HttpAsyncClientBuilder): HttpAsyncClientBuilder = {
                  // elasticsearch username and password
                  val credentialsProvider = new BasicCredentialsProvider
                  credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(es_user, es_password))
                  httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
                  httpClientBuilder.setSSLContext(trustfulSslContext)
                }
              })
            }
          }

问题是我不确定我是否应该做一个新的RestClientFactory对象。发生的事情是该应用程序连接到了Elasticsearch集群,但随后发现SSL CERT无效,因此我不得不放入trustfullSslContext(如此处https://gist.github.com/iRevive/4a3c7cb96374da5da80d4538f3da17cb所述),这使我摆脱了SSL问题,但现在ES REST客户端执行ping测试,但ping失败,它会引发异常并关闭应用程序。我怀疑由于SSL错误而导致ping操作失败,也许它没有将我安装的trustfulSslContext作为新的RestClientFactory的一部分使用,这使我怀疑我不应该做新的事情,应该有一种简单的方法来更新现有的RestclientFactory对象,并且基本上这都是由于我缺乏Scala知识而发生的。

1 个答案:

答案 0 :(得分:0)

很高兴报告此问题已解决。我在 Update 1 中发布的代码是正确的。对ECE的ping无法工作有两个原因:

  1. 证书需要包括完整的链,包括根CA,中间CA和ECE的证书。这有助于摆脱整个trustfulSslContext的内容。

  2. ECE坐在ha代理后面,并且代理将HTTP请求中的主机名映射到ECE中的实际部署集群名称。此映射逻辑未考虑Java REST高级客户端使用org.apache.httphost类,即使端口号是443,该类也将主机名创建为hostname:port_number。因为它由于443而找不到映射因此,ECE返回404错误而不是200 ok(找到此错误的唯一方法是在ha-proxy上查看未加密的数据包)。一旦固定了ha-proxy中的映射逻辑,就可以找到映射,并且ping现在可以成功。