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

codacy.events.EventRouter.scala Maven / Gradle / Ivy

The newest version!
package codacy.events

import codacy.events.internal.{EventLogger, Handlers, PathHolders}
import io.circe.Json
import shapeless.{CNil, Coproduct}

import scala.concurrent.Future

trait EventRouter {

  def usedTopics: List[String]
  def removeTopics: RemoveTopics
  def handleEvent(path: String, event: => Json): Future[Unit]
}

object EventRouter {

  def apply[Events <: Coproduct: Handlers](implicit logger: EventLogger = internal.defaultEventLogger): EventRouter = {
    new Impl[Events, CNil]
  }

  def removing[Events <: Coproduct: Handlers, Removes <: Coproduct: PathHolders](implicit
      logger: EventLogger,
      disjunction: Disjunction[Events, Removes]
  ): EventRouter = {
    new Impl[Events, Removes]
  }

  private type Handler = PartialFunction[(String, Json), Future[Unit]]

  final private class Impl[Events <: Coproduct, Removes <: Coproduct](implicit
      logger: EventLogger,
      handlers: Handlers[Events],
      removes: PathHolders[Removes]
  ) extends EventRouter {

    override lazy val (usedTopics, _) = handlers.handlers.unzip
    override lazy val removeTopics = RemoveTopics(removes.paths)

    override def handleEvent(path: String, event: => Json): Future[Unit] =
      router(path, event)

    private lazy val fallbackHandler: Handler = { case (path, _) =>
      logger.warn(s"no handler defined for ${path}, discarding event")
      Future.successful(())
    }

    private lazy val router: Handler = handlers.handlers
      .map {
        case (path, f) => ({ case (`path`, json) => f(path, json) }: Handler)
      }
      .reverse
      .fold(fallbackHandler)((pf, cur) => cur.orElse(pf))
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy