Нет описания

AkkaStreamFileProcessingImpl.scala 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package fr.natan.akkastreamfileprocessingapi.service
  2. import akka.actor.ActorSystem
  3. import akka.stream.scaladsl.{Flow, Sink, Source}
  4. import akka.{Done, NotUsed}
  5. import com.typesafe.scalalogging.slf4j.Logger
  6. import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.{nameBasics, titleBasics, titlePrincipalsBasics}
  7. import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSeries}
  8. import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.buildPersonModel
  9. import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{
  10. buildAllPersonsSink, buildAllTvSeriesSink, buildAndValidateSource, buildPersonFlow, buildSource, buildTvSerieFlow,
  11. filterByPersonIdFlow, filterByPersonNameFlow, filterByTvSeriePrimaryTitleFlow
  12. }
  13. import org.slf4j.LoggerFactory
  14. import org.springframework.stereotype.Component
  15. import scala.concurrent.ExecutionContext.Implicits.global
  16. import scala.concurrent.Future
  17. import scala.language.postfixOps
  18. import scala.util.{Failure, Success}
  19. //noinspection SpellCheckingInspection
  20. @Component
  21. class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
  22. implicit val actorSystem: ActorSystem = ActorSystem("AkkaStreamActor")
  23. implicit val logger: Logger = Logger(LoggerFactory.getLogger(this.getClass))
  24. override def getPersonById(personID: String): Future[Person] = {
  25. val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
  26. val res: Future[Person] = source
  27. .via(flow = filterByPersonIdFlow(nconst = personID))
  28. .runWith(Sink.head)
  29. res.andThen {
  30. case Failure(exception) => logger.info(s"$exception")
  31. case Success(value) => logger.info(s"$value")
  32. }
  33. res
  34. }
  35. override def getPersonByName(primaryName: String): Future[IndexedSeq[Person]] = {
  36. val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
  37. val persons: Future[IndexedSeq[Person]] = source
  38. .via(flow = filterByPersonNameFlow(primaryName = primaryName))
  39. .runWith(Sink.collection)
  40. persons.onComplete({
  41. case Failure(exception) => logger.error(s"$exception")
  42. case Success(value: IndexedSeq[Person]) =>
  43. value.foreach((person: Person) => logger.info(s"$person"))
  44. logger.info("SUCCESS")
  45. })
  46. persons
  47. }
  48. override def getTvSerieByPrimaryTitle(tvSeriePrimaryTitle: String): Future[IndexedSeq[TvSeries]] = {
  49. val tvSeriesSource: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
  50. val filterByTvSerieTitle: Flow[Map[String, String], TvSeries, NotUsed] =
  51. filterByTvSeriePrimaryTitleFlow(tvSeriePrimaryTitle = tvSeriePrimaryTitle)
  52. val tvSries: Future[IndexedSeq[TvSeries]] = tvSeriesSource
  53. .via(flow = filterByTvSerieTitle)
  54. .runWith(Sink.collection)
  55. tvSries.onComplete({
  56. case Failure(exception) => logger.info(s"$exception")
  57. case Success(value: IndexedSeq[TvSeries]) =>
  58. value.foreach((tvSrie: TvSeries) => logger.info(s"$tvSrie"))
  59. logger.info("SUCCESS")
  60. })
  61. tvSries
  62. }
  63. private def getTvSerieIdByPrimaryTitle(primaryTitle: String): Future[Option[String]] = {
  64. val source: Source[Map[String, String], _] = buildSource(inputFile = titleBasics)
  65. val res: Future[Option[String]] = source
  66. .filter((rowMap: Map[String, String]) => {
  67. rowMap.getOrElse(key = "primaryTitle", "") == primaryTitle
  68. })
  69. .map((rowMap: Map[String, String]) => rowMap.get("tconst"))
  70. .runWith(Sink.head)
  71. res
  72. }
  73. private def getListOfPersonsIDByTvSerieID(tvSerieIdFuture: Future[Option[String]]): Future[IndexedSeq[Option[String]]] = {
  74. val source: Source[Map[String, String], _] = buildSource(inputFile = titlePrincipalsBasics)
  75. val res: Future[IndexedSeq[Option[String]]] = source
  76. .filter((rowMaps: Map[String, String]) => {
  77. rowMaps.getOrElse(key = "tconst", default = "") == tvSerieIdFuture.value.get.get.get
  78. })
  79. .map((rowMap: Map[String, String]) => {
  80. rowMap.get(key = "nconst")
  81. })
  82. .runWith(Sink.collection)
  83. res
  84. }
  85. private def getListOfPersonsForTvSerie(listPersonsIDsFuture: Future[IndexedSeq[Option[String]]]):
  86. Future[IndexedSeq[Person]] = {
  87. val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
  88. val res: Future[IndexedSeq[Person]] = source
  89. .filter((rowMaps: Map[String, String]) => {
  90. listPersonsIDsFuture.value.get.get.contains(rowMaps.get(key = "nconst"))
  91. })
  92. .map((rowMap: Map[String, String]) => {
  93. buildPersonModel(rowMap)
  94. })
  95. .runWith(Sink.collection)
  96. res
  97. }
  98. override def getTeamOfPersonsForTvSerie(tvSeriePrimaryTitle: String): Future[IndexedSeq[Person]] = {
  99. //futures chaining
  100. logger.info("STEP 1/3 START")
  101. val tvSerieIDFuture: Future[Option[String]] = getTvSerieIdByPrimaryTitle(primaryTitle = tvSeriePrimaryTitle)
  102. val finalFuture: Future[IndexedSeq[Person]] =
  103. tvSerieIDFuture.andThen({
  104. case Failure(exception) => logger.error(s"$exception")
  105. case Success(value: Option[String]) =>
  106. logger.info(s"TvSerie ID: $value")
  107. logger.info("STEP 1/3 END")
  108. })
  109. .flatMap({
  110. _ =>
  111. logger.info("STEP 2/3 START")
  112. val listPersonIDsFuture: Future[IndexedSeq[Option[String]]] = getListOfPersonsIDByTvSerieID(tvSerieIdFuture = tvSerieIDFuture)
  113. listPersonIDsFuture.andThen({
  114. case Failure(exception) => logger.error(s"$exception")
  115. case Success(value) =>
  116. value.foreach((personID: Option[String]) => logger.info(s"Person ID:$personID"))
  117. logger.info("STEP 2/3 END")
  118. })
  119. .flatMap({
  120. future =>
  121. logger.info("STEP 3/3 START")
  122. val personsTeamFuture: Future[IndexedSeq[Person]] = getListOfPersonsForTvSerie(listPersonsIDsFuture = listPersonIDsFuture)
  123. personsTeamFuture.andThen({
  124. case Failure(exception) => logger.error(s"$exception")
  125. case Success(value: IndexedSeq[Person]) =>
  126. value.foreach((person: Person) => logger.info(s"${person.toString}"))
  127. logger.info("STEP 3/3 END")
  128. })
  129. })
  130. })
  131. finalFuture
  132. }
  133. override def getAllPersons(): Unit = {
  134. val personSource: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
  135. //graph
  136. val startTime: Long = System.currentTimeMillis()
  137. val result: Future[Done] = personSource
  138. .via(flow = buildPersonFlow())
  139. .runWith(sink = buildAllPersonsSink(logger = logger))
  140. result.onComplete {
  141. case Failure(exception) => logger.error(s"$exception")
  142. case Success(value) =>
  143. logger.info(s"$value")
  144. val time: Long = (System.currentTimeMillis() - startTime) / 100
  145. logger.info(s"elapsed time: $time")
  146. }
  147. }
  148. override def getAllTvSeries(): Unit = {
  149. val source: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
  150. val sink: Sink[TvSeries, Future[Done]] = buildAllTvSeriesSink(logger = logger)
  151. val startingTime: Long = System.currentTimeMillis()
  152. //graph sink->flow->sink
  153. source
  154. .via(flow = buildTvSerieFlow())
  155. .runWith(sink = sink)
  156. .andThen {
  157. case Success(value) =>
  158. val elapsedTime: Long = (System.currentTimeMillis() - startingTime) / 1000
  159. logger.info(s"$value: successfully processing file, elapsed time $titleBasics: $elapsedTime sec")
  160. case Failure(error: Error) => logger.error(s"$error")
  161. }
  162. }
  163. }

Powered by TurnKey Linux.