Нема описа

AkkaStreamFileProcessingImpl.scala 7.8KB

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

Powered by TurnKey Linux.