From b9d2c22066c63da5f730654a83d81ffc6a1aad3d Mon Sep 17 00:00:00 2001 From: Leonardo Menezes <mail@lmenezes.com> Date: Sat, 7 Oct 2017 17:50:33 +0200 Subject: [PATCH] optimised cluster changes api --- .../ClusterChangesController.scala | 31 ++++------------ app/services/changes/DataService.scala | 36 +++++++++++++++++++ .../ClusterChangesControllerSpec.scala | 20 +++++------ 3 files changed, 53 insertions(+), 34 deletions(-) create mode 100644 app/services/changes/DataService.scala diff --git a/app/controllers/ClusterChangesController.scala b/app/controllers/ClusterChangesController.scala index 8fc9e64..41cb4b6 100644 --- a/app/controllers/ClusterChangesController.scala +++ b/app/controllers/ClusterChangesController.scala @@ -3,36 +3,19 @@ package controllers import javax.inject.Inject import controllers.auth.AuthenticationModule -import elastic.{ElasticClient, Error} -import models.commons.{Indices, Nodes} +import elastic.ElasticClient import models.{CerebroResponse, Hosts} -import play.api.libs.json.Json +import services.changes.DataService import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future class ClusterChangesController @Inject()(val authentication: AuthenticationModule, val hosts: Hosts, - client: ElasticClient) extends BaseController { + client: ElasticClient, + data: DataService) extends BaseController { - def get = process { request => - Future.sequence(Seq( - client.getIndices(request.target), - client.getNodes(request.target), - client.main(request.target) - )).map { responses => - val failed = responses.find(_.isInstanceOf[Error]) - failed match { - case None => - val body = Json.obj( - "indices" -> Indices(responses(0).body), - "nodes" -> Nodes(responses(1).body), - "cluster_name" -> (responses(2).body \ "cluster_name").as[String] - ) - CerebroResponse(200, body) - case Some(f) => - CerebroResponse(f.status, f.body) - } - } + def get = process { + request => data.getData(request.target).map(CerebroResponse(200, _)) } + } diff --git a/app/services/changes/DataService.scala b/app/services/changes/DataService.scala new file mode 100644 index 0000000..97f22df --- /dev/null +++ b/app/services/changes/DataService.scala @@ -0,0 +1,36 @@ +package services.changes + +import com.google.inject.Inject +import elastic.{ElasticClient, Error} +import models.ElasticServer +import models.commons.{Indices, Nodes} +import play.api.libs.json.{JsValue, Json} +import services.exception.RequestFailedException + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future + +class DataService @Inject()(client: ElasticClient) { + + val apis = Seq( + "_cat/nodes?format=json&h=name", // Node names + "_cat/indices?format=json&h=index", // Index names + "_cat/health?h=cluster&format=json" // Cluster name + ) + + def getData(target: ElasticServer): Future[JsValue] = + Future.sequence(apis.map(client.executeRequest("GET", _, None, target))).map { responses => + responses.zipWithIndex.find(_._1.isInstanceOf[Error]) match { + case Some((response, idx)) => + throw RequestFailedException(apis(idx), response.status, response.body.toString()) + + case None => + Json.obj( + "nodes" -> Nodes(responses(0).body), + "indices" -> Indices(responses(1).body), + "cluster_name" -> (responses(2).body \\ "cluster").head + ) + } + } + +} diff --git a/test/controllers/ClusterChangesControllerSpec.scala b/test/controllers/ClusterChangesControllerSpec.scala index d7a9c7f..ae9d95a 100644 --- a/test/controllers/ClusterChangesControllerSpec.scala +++ b/test/controllers/ClusterChangesControllerSpec.scala @@ -1,7 +1,6 @@ package controllers -import controllers.AnalysisControllerSpec.application -import elastic.{ElasticResponse, Success} +import elastic.Success import models.ElasticServer import play.api.libs.json.Json import play.api.test.FakeRequest @@ -28,26 +27,27 @@ object ClusterChangesControllerSpec extends MockedServices { |} """.stripMargin ) - val mainResponse = Json.parse("""{"cluster_name": "elasticsearch"}""") + val healthResponse = Json.parse("""[{"cluster": "elasticsearch"}]""") val indicesResponse = Json.parse( """ |[ - | {"health":"green","status":"open","index":"index1","pri":"10","rep":"0","docs.count":"4330","docs.deleted":"10","store.size":"4.1mb","pri.store.size":"4.1mb"}, - | {"health":"green","status":"closed","index":"index2","pri":"10","rep":"0","docs.count":"1497203","docs.deleted":"5048","store.size":"860.9mb","pri.store.size":"860.9mb"} + | {"index":"index1"}, + | {"index":"index2"} |] """.stripMargin ) val nodesResponse = Json.parse( """ |[ - | {"host":"127.0.0.1","ip":"127.0.0.1","name":"Shriek"}, - | {"host":"127.0.0.1","ip":"127.0.0.1","name":"Jimaine Szardos"} + | {"name":"Shriek"}, + | {"name":"Jimaine Szardos"} |] """.stripMargin ) - client.main(ElasticServer("somehost", None)) returns Future.successful(Success(200, mainResponse)) - client.getNodes(ElasticServer("somehost", None)) returns Future.successful(Success(200, nodesResponse)) - client.getIndices(ElasticServer("somehost", None)) returns Future.successful(Success(200, indicesResponse)) + + client.executeRequest("GET", "_cat/health?h=cluster&format=json", None, ElasticServer("somehost", None)) returns Future.successful(Success(200, healthResponse)) + client.executeRequest("GET", "_cat/nodes?format=json&h=name", None, ElasticServer("somehost", None)) returns Future.successful(Success(200, nodesResponse)) + client.executeRequest("GET", "_cat/indices?format=json&h=index", None, ElasticServer("somehost", None)) returns Future.successful(Success(200, indicesResponse)) val response = route(application, FakeRequest(POST, "/cluster_changes").withBody(Json.obj("host" -> "somehost"))).get ensure(response, 200, expectedResponse) } -- GitLab