package net.elodina.mesos.zipkin.storage import java.util.concurrent.CopyOnWriteArrayList import net.elodina.mesos.zipkin.Config import net.elodina.mesos.zipkin.components.{WebService, QueryService, Collector} import play.api.libs.json._ import play.api.libs.functional.syntax._ import scala.collection.mutable import scala.collection.JavaConversions._ case class Cluster(_collectors: List[Collector] = Nil, _webServices: List[WebService] = Nil, _queryServices: List[QueryService] = Nil) { private[zipkin] var frameworkId: Option[String] = None private val storage = Cluster.newStorage(Config.storage) private[zipkin] val collectors: mutable.Buffer[Collector] = new CopyOnWriteArrayList[Collector]() private[zipkin] val queryServices: mutable.Buffer[QueryService] = new CopyOnWriteArrayList[QueryService]() private[zipkin] val webServices: mutable.Buffer[WebService] = new CopyOnWriteArrayList[WebService]() collectors ++= _collectors queryServices ++= _queryServices webServices ++= _webServices def clear(): Unit = { collectors.clear() queryServices.clear() webServices.clear() } def save() = storage.save(this)(Cluster.writer) def load() { storage.load(Cluster.reader).foreach { cluster => this.frameworkId = cluster.frameworkId collectors ++= cluster.collectors webServices ++= cluster.webServices queryServices ++= cluster.queryServices } } def fetchAllComponents = { collectors ++ queryServices ++ webServices } def isReconciling:Boolean = { collectors.exists(_.isReconciling) || queryServices.exists(_.isReconciling) || webServices.exists(_.isReconciling) } } object Cluster { private def newStorage(storage: String): Storage[Cluster] = { storage.split(":", 2) match { case Array("file", fileName) => FileStorage(fileName) case Array("zk", zk) => ZkStorage(zk) case _ => throw new IllegalArgumentException(s"Unsupported storage: $storage") } } implicit val writer = new Writes[Cluster] { override def writes(o: Cluster): JsValue = { Json.obj( "frameworkId" -> o.frameworkId, "collectors" -> o.collectors.toList, "webServices" -> o.webServices.toList, "queryServices" -> o.queryServices.toList ) } } implicit val reader = ( (__ \ 'frameworkId).readNullable[String] and (__ \ 'collectors).read[List[Collector]] and (__ \ 'webServices).read[List[WebService]] and (__ \ 'queryServices).read[List[QueryService]] )((frameworkId, collectors, webServices, queryServices) => { val cluster = Cluster(collectors, webServices, queryServices) cluster.frameworkId = frameworkId cluster }) }