package fr.natan.akkastreamfileprocessingapi.service import akka.actor.ActorSystem import akka.stream.scaladsl.{Flow, Sink, Source} import akka.{Done, NotUsed} import com.typesafe.scalalogging.slf4j.Logger import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.{nameBasics, titleBasics} import fr.natan.akkastreamfileprocessingapi.models.{Person, TvSeries} import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{ buildAndValidateSource, buildPersonFlow, buildPersonSink, buildPersonsSink, buildSource, buildTvSerieFlow, buildTvSeriesSink, filterByMoviePrimaryTitleFlow, filterByPersonID } import org.slf4j.LoggerFactory import org.springframework.stereotype.Component import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future import scala.util.{Failure, Success} @Component class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing { implicit val actorSystem: ActorSystem = ActorSystem("AkkaStreamActor") implicit val logger: Logger = Logger(LoggerFactory.getLogger(this.getClass)) override def getAllMovies(): Unit = { val source: Source[Map[String, String], NotUsed] = buildAndValidateSource(inputFile = titleBasics) val sink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger) val startingTime: Long = System.currentTimeMillis() //graph sink->flow->sink source .via(flow = buildTvSerieFlow()) .runWith(sink = sink) .andThen { case Success(value) => val elapsedTime: Long = (System.currentTimeMillis() - startingTime) / 1000 logger.info(s"$value: successfully processing file, elapsed time $titleBasics: $elapsedTime sec") case Failure(error: Error) => logger.error(s"$error") } } override def getMoviesByTitle(moviePrimaryTitle: String): Unit = { /*val tvSeriesSource: Source[String, NotUsed] = buildAndValidateSource(inputFile = titleBasics) val tvSeriesSink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger) val filterByMovieTitleFlow: Flow[String, TvSeries, NotUsed] = filterByMoviePrimaryTitleFlow(moviePrimaryTitle = moviePrimaryTitle) val startTime: Long = System.currentTimeMillis() val listTvSeries: Future[Done] = tvSeriesSource .via(flow = filterByMovieTitleFlow) .runWith(sink = tvSeriesSink) .andThen { case Success(value) => val elapsedTime: Long = (System.currentTimeMillis() - startTime) / 1000 logger.info(s"$value: successfully processing file, elapsed time $titleBasics: $elapsedTime sec") case Failure(error: Error) => logger.error(s"$error") }*/ } override def getAllPersons(): Unit = { val personSource: Source[Map[String, String], NotUsed] = buildSource(inputFile = nameBasics) val personSink: Sink[Person, Future[Done]] = buildPersonsSink(logger = logger) //graph val startTime: Long = System.currentTimeMillis() personSource .via(flow = buildPersonFlow()) .runWith(sink = personSink) .andThen { case Success(value) => val elapsedTime: Long = (System.currentTimeMillis() - startTime) / 1000 logger.info(s"$value: successfully processing file $elapsedTime sec") case Failure(error: Error) => logger.error(s"$error") } } override def getPersonById(nconst: String): Unit = { val source: Source[Map[String, String], NotUsed] = buildSource(inputFile = nameBasics) val sink: Sink[Person, Future[Done]] = buildPersonSink(logger = logger) val startTime: Long = System.currentTimeMillis() source .via(flow = filterByPersonID(nconst = nconst)) .runWith(sink = sink) .andThen { case Success(value) => { val elapsedTime: Long = (System.currentTimeMillis()-startTime)/1000 logger.info(s"$value: Successfully processed, elapsed time: $elapsedTime") } case Failure(exception) => logger.error(s"$exception: Fail") } } }