Commit e48ca0b6 authored by Leonardo Menezes's avatar Leonardo Menezes
Browse files

created nodes api

parent c70642b9
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
package controllers

import javax.inject.Inject

import controllers.auth.AuthenticationModule
import elastic.{ElasticClient, Error}
import models.nodes.Nodes
import models.{CerebroResponse, Hosts}

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

class NodesController @Inject()(val authentication: AuthenticationModule,
                                val hosts: Hosts,
                                client: ElasticClient) extends BaseController {

  def index = process { request =>
    Future.sequence(
      Seq(
        client.nodes(Seq("jvm", "os"), request.target),
        client.nodesStats(Seq("jvm", "fs", "os", "process"), request.target),
        client.catMaster(request.target)
      )
    ).map { responses =>
      val failed = responses.find(_.isInstanceOf[Error])
      failed match {
        case Some(f) => CerebroResponse(f.status, f.body)
        case None =>
          val nodes = Nodes(responses(0).body, responses(1).body, responses(2).body)
          CerebroResponse(200, nodes)
      }
    }
  }

}
+2 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ class HTTPElasticClient @Inject()(client: WSClient) extends ElasticClient {
  }

  def nodesStats(stats: Seq[String], target: ElasticServer) = {
    val path = s"/_nodes/stats/${stats.mkString(",")}"
    val path = s"/_nodes/stats/${stats.mkString(",")}?human=true"
    execute(s"${target.host}$path", "GET", None, target.authentication)
  }

@@ -52,7 +52,7 @@ class HTTPElasticClient @Inject()(client: WSClient) extends ElasticClient {
  }

  def nodes(flags: Seq[String], target: ElasticServer) = {
    val path = s"/_nodes/_all/${flags.mkString(",")}"
    val path = s"/_nodes/_all/${flags.mkString(",")}?human=true"
    execute(s"${target.host}$path", "GET", None, target.authentication)
  }

+72 −0
Original line number Diff line number Diff line
package models.nodes

import models.commons.NodeRoles
import play.api.libs.json._

object Node {

  def apply(id: String, currentMaster: Boolean, info: JsValue, stats: JsValue): JsValue =
    Json.obj(
      "id" -> JsString(id),
      "current_master" -> JsBoolean(currentMaster),
      "name" -> (stats \ "name").as[JsValue],
      "heap" -> heap(stats),
      "disk" -> disk(stats),
      "cpu" -> cpu(stats),
      "uptime" -> (stats \ "jvm" \ "uptime_in_millis").as[JsValue],
      "jvm" -> (info \ "jvm" \ "version").as[JsValue],
      "version" -> (info \ "version").as[JsValue]
    ) ++ roles(info)

  private def roles(info: JsValue): JsObject = {
    val roles = NodeRoles(info)
    Json.obj(
      "master" -> JsBoolean(roles.master),
      "client" -> JsBoolean(roles.client),
      "ingest" -> JsBoolean(roles.ingest),
      "data" -> JsBoolean(roles.data)
    )
  }

  private def cpu(stats: JsValue): JsValue = {
    val load = (stats \ "os" \ "cpu" \ "load_average" \ "1m").asOpt[JsValue].getOrElse(// 5.X
      (stats \ "os" \ "load_average").asOpt[JsValue].getOrElse(JsNull) // FIXME: 2.X
    )
    val osCpu = (stats \ "os" \ "cpu" \ "percent").asOpt[JsValue].getOrElse(// 5.X
      (stats \ "os" \ "cpu_percent").asOpt[JsValue].getOrElse(JsNull) // FIXME 2.X
    )
    Json.obj(
      "process" -> (stats \ "process" \ "cpu" \ "percent").as[JsValue],
      "os" -> osCpu,
      "load" -> load
    )
  }

  private def disk(stats: JsValue): JsValue = {
    val total = (stats \ "fs" \ "total" \ "total_in_bytes").asOpt[Long]
    val available = (stats \ "fs" \ "total" \ "available_in_bytes").asOpt[Long]
    (total, available) match {
      case (Some(t), Some(a)) =>
        val percent = Math.round((1 - (a.toFloat / t.toFloat)) * 100)
        Json.obj(
          "total" -> JsNumber(t),
          "available" -> JsNumber(a),
          "percent" -> JsNumber(percent)
        )
      case _ =>
        Json.obj(
          "total" -> JsNull,
          "available" -> JsNull,
          "percent" -> JsNull
        )
    }
  }

  private def heap(stats: JsValue): JsValue =
    Json.obj(
      "max" -> (stats \ "jvm" \ "mem" \ "heap_max").as[JsValue],
      "used" -> (stats \ "jvm" \ "mem" \ "heap_used").as[JsValue],
      "percent" -> (stats \ "jvm" \ "mem" \ "heap_used_percent").as[JsValue]
    )

}
+19 −0
Original line number Diff line number Diff line
package models.nodes

import play.api.libs.json.{JsArray, JsObject, JsValue}

object Nodes {

  def apply(info: JsValue, stats: JsValue, master: JsValue): JsValue = {
    val masterId = (master \\ "id").head.as[String]
    JsArray(
      (info \ "nodes").as[JsObject].keys.map { nodeId =>
        val nodeInfo = (info \ "nodes" \ nodeId).as[JsValue]
        val nodeStats = (stats \ "nodes" \ nodeId).as[JsValue]
        val currentMaster = masterId.equals(nodeId)
        Node(nodeId, currentMaster, nodeInfo, nodeStats).as[JsValue]
      }.toSeq
    )
  }

}
+3 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ POST /overview/delete_indices controllers.ClusterOvervie
POST        /overview/get_shard_stats                 controllers.ClusterOverviewController.getShardStats
POST        /overview/relocate_shard                  controllers.ClusterOverviewController.relocateShard

# Nodes module
POST        /nodes                                    controllers.NodesController.index

# Navbar module
POST        /navbar                                   controllers.NavbarController.index