All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sksamuel.elastic4s.ElasticClient.scala Maven / Gradle / Ivy

There is a newer version: 6.0.0-rc1
Show newest version
package com.sksamuel.elastic4s

import java.net.InetSocketAddress

import org.elasticsearch.client.transport.TransportClient
import org.elasticsearch.client.{AdminClient, Client}
import org.elasticsearch.common.settings.Settings
import org.elasticsearch.common.transport.InetSocketTransportAddress
import org.elasticsearch.node.{Node, NodeBuilder}
import org.elasticsearch.plugins.Plugin

import scala.concurrent._
import scala.concurrent.duration._
import scala.language.implicitConversions
import scala.util.Try

/** @author Stephen Samuel */
class ElasticClient(val client: org.elasticsearch.client.Client,
                    node: Option[Node] = None) extends IterableSearch {

  def execute[T, R, Q](t: T)(implicit executable: Executable[T, R, Q]): Future[Q] = executable(client, t)

  def close(): Unit = {
    Try {
      client.close()
    }
    Try {
      node.foreach(_.close)
    }
  }

  def java: Client = client
  def admin: AdminClient = client.admin

  override def iterateSearch(query: SearchDefinition)(implicit timeout: Duration): Iterator[RichSearchResponse] = {
    IterableSearch(this).iterateSearch(query)
  }
}

object ElasticClient {

  /**
   * Creates an ElasticClient which wraps an existing Client.
   *
   * Note: If you use this method, then calling close on the client instance will not shutdown
   * any local node(s). Those must be managed by the caller of this method.
   *
   * @param client the client to wrap
   */
  def fromClient(client: Client): ElasticClient = new ElasticClient(client)

  /**
   * Creates an ElasticClient by requesting a client from a given Node.
   *
   * Note: This method will not manage the lifecycle of the node. Calling close on the client
   * will shutdown only the transport mechansim between the client and the node.
   *
   * @param node the node a client will connect to
   */
  def fromNode(node: Node): ElasticClient = new ElasticClient(node.client)

  @deprecated("use the transport method with an instance of ElasticsearchClientUri or uri format string", "2.0.0")
  def remote(host: String, port: Int): ElasticClient = transport(Settings.builder.build, ElasticsearchClientUri(host, port))

  @deprecated("use the transport method with an instance of ElasticsearchClientUri or uri format string", "2.0.0")
  def remote(settings: Settings, host: String, port: Int): ElasticClient = {
    transport(settings, ElasticsearchClientUri(host, port))
  }

  /**
   * Creates an ElasticClient connected to the elasticsearch instance(s) specified by the uri.
   * This method will use default settings.
   *
   * Note: The method name 'transport' refers to the fact that the client will connect to the instance(s)
   * using the transport client rather than becoming a full node itself and joining the cluster.
   * This is what most people think of when they talk about a client, like you would in mongo or mysql for example.
   * To create a local node, use the fromNode method.
   *
   * @param uri the instance(s) to connect to.
   */
  def transport(uri: ElasticsearchClientUri): ElasticClient = transport(Settings.builder.build, uri)

  @deprecated("use transport instead of remote", "2.0.0")
  def remote(uri: ElasticsearchClientUri): ElasticClient = transport(Settings.builder.build, uri)

  /**
   * Connects to elasticsearch instance(s) specified by the uri and setting the
   * given settings object on the client.
   *
   * Note: The method name 'transport' refers to the fact that the client will connect to the instance(s)
   * using the transport client rather than becoming a full node itself and joining the cluster.
   * This is what most people think of when they talk about a client, like you would in mongo or mysql for example.
   * To create a local node, use the fromNode method.
   *
   * @param settings the settings as applicable to the client.
   * @param uri the instance(s) to connect to.
   * @param plugins the plugins to add to the client.
   */
  def transport(settings: Settings, uri: ElasticsearchClientUri, plugins: Class[_ <: Plugin]*): ElasticClient = {
    val client = plugins
      .foldLeft(TransportClient.builder)((c, plugin) => c.addPlugin(plugin))
      .settings(settings)
      .build()
    for ( (host, port) <- uri.hosts ) {
      client.addTransportAddress(new InetSocketTransportAddress(new InetSocketAddress(host, port)))
    }
    fromClient(client)
  }

  @deprecated("use transport instead of remote", "2.0.0")
  def remote(settings: Settings, uri: ElasticsearchClientUri): ElasticClient = transport(settings, uri)

  /**
   * Creates a local data node. This is useful for embedded usage, or for unit tests.
   * Default settings will be applied.
   */
  def local: ElasticClient = local(Settings.settingsBuilder().build())

  /**
   * Creates a local data node. This is useful for embedded usage, or for unit tests.
   * @param settings the settings object to set on the node
   */
  def local(settings: Settings): ElasticClient = {
    val node = NodeBuilder.nodeBuilder().local(true).data(true).settings(settings).node()
    new ElasticClient(node.client, Some(node))
  }
}

object ElasticsearchClientUri {

  private val PREFIX = "elasticsearch://"

  implicit def stringtoUri(str: String): ElasticsearchClientUri = ElasticsearchClientUri(str)

  def apply(host: String, port: Int): ElasticsearchClientUri = apply(s"elasticsearch://$host:$port")

  def apply(str: String): ElasticsearchClientUri = {
    require(str != null && str.trim.nonEmpty, "Invalid uri, must be in format elasticsearch://host:port,host:port,...")
    val withoutPrefix = str.replace(PREFIX, "")
    val hosts = withoutPrefix.split(',').map { host =>
      val parts = host.split(':')
      if (parts.length == 2) {
        parts(0) -> parts(1).toInt
      } else {
        throw new IllegalArgumentException("Invalid uri, must be in format elasticsearch://host:port,host:port,...")
      }
    }
    ElasticsearchClientUri(str, hosts.toList)
  }
}

case class ElasticsearchClientUri(uri: String, hosts: List[(String, Int)])




© 2015 - 2025 Weber Informatics LLC | Privacy Policy