No Description

AkkaStreamFileProcessingImpl.scala 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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, buildTvSerieModel}
  9. import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{
  10. buildAllPersonsSink,
  11. buildAndValidateSource,
  12. buildPersonFlow,
  13. buildPersonSink,
  14. buildSource,
  15. buildTvSerieFlow,
  16. buildTvSeriesSink,
  17. filterByPersonIdFlow,
  18. filterByPersonNameFlow,
  19. filterByTvSeriePrimaryTitleFlow
  20. }
  21. import org.slf4j.LoggerFactory
  22. import org.springframework.stereotype.Component
  23. import scala.concurrent.ExecutionContext.Implicits.global
  24. import scala.concurrent.duration.DurationInt
  25. import scala.concurrent.{Await, Future}
  26. import scala.language.postfixOps
  27. import scala.util.{Failure, Success}
  28. @Component
  29. class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
  30. implicit val actorSystem: ActorSystem = ActorSystem("AkkaStreamActor")
  31. implicit val logger: Logger = Logger(LoggerFactory.getLogger(this.getClass))
  32. override def getAllPersons(): Unit = {
  33. val personSource: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
  34. val personSink: Sink[Person, Future[Done]] = buildAllPersonsSink(logger = logger)
  35. //graph
  36. val startTime: Long = System.currentTimeMillis()
  37. val result: Future[Done] = personSource
  38. .via(flow = buildPersonFlow())
  39. .runWith(sink = personSink)
  40. .andThen {
  41. case Success(value) =>
  42. val elapsedTime: Long = (System.currentTimeMillis() - startTime) / 1000
  43. logger.info(s"$value: Successfully processed, elapsed time: $elapsedTime")
  44. case Failure(exception) => logger.error(s"$exception: Fail")
  45. }
  46. }
  47. override def getPersonById(nconst: String): Person = {
  48. val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
  49. val startTime: Long = System.currentTimeMillis()
  50. val res = source
  51. .via(flow = filterByPersonIdFlow(nconst = nconst))
  52. .runWith(sink = buildPersonSink())
  53. .andThen {
  54. case Success(value) =>
  55. val elapsedTime: Long = (System.currentTimeMillis()-startTime)/1000
  56. logger.info(s"$value")
  57. logger.info(s"Successfully processed, elapsed time: $elapsedTime")
  58. case Failure(exception) => logger.error(s"$exception: Fail")
  59. }
  60. Await.result(res,1 minutes)
  61. val person: Person = res.value.get.get
  62. person
  63. }
  64. override def getPersonByName(primaryName: String): Unit = {
  65. val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
  66. source
  67. .via(
  68. flow = filterByPersonNameFlow(personName = primaryName)
  69. )
  70. .runWith(sink = buildPersonSink())
  71. .andThen {
  72. case Failure(exception) => logger.info(s"$exception")
  73. case Success(value) => logger.info(s"$value: Successufully processing")
  74. }
  75. }
  76. override def getAllTvSeries(): Unit = {
  77. val source: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
  78. val sink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger)
  79. val startingTime: Long = System.currentTimeMillis()
  80. //graph sink->flow->sink
  81. source
  82. .via(flow = buildTvSerieFlow())
  83. .runWith(sink = sink)
  84. .andThen {
  85. case Success(value) =>
  86. val elapsedTime: Long = (System.currentTimeMillis() - startingTime) / 1000
  87. logger.info(s"$value: successfully processing file, elapsed time $titleBasics: $elapsedTime sec")
  88. case Failure(error: Error) => logger.error(s"$error")
  89. }
  90. }
  91. override def getByTvSeriePrimaryTitle(tvSeriePrimaryTitle: String): Unit = {
  92. val tvSeriesSource: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
  93. val tvSeriesSink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger)
  94. val filterByMovieTitleFlow: Flow[Map[String, String], TvSeries, NotUsed] =
  95. filterByTvSeriePrimaryTitleFlow(tvSeriePrimaryTitle = tvSeriePrimaryTitle)
  96. val startTime: Long = System.currentTimeMillis()
  97. val listTvSeries: Future[Done] = tvSeriesSource
  98. .via(flow = filterByMovieTitleFlow)
  99. .runWith(sink = tvSeriesSink)
  100. .andThen {
  101. case Success(value) =>
  102. val elapsedTime: Long = (System.currentTimeMillis() - startTime) / 1000
  103. logger.info(s"$value: successfully processing file, elapsed time: $elapsedTime sec")
  104. case Failure(error: Error) => logger.error(s"$error")
  105. }
  106. getTvSerieIdByPrimaryTitle(primaryTitle = tvSeriePrimaryTitle)
  107. }
  108. private def getTvSerieIdByPrimaryTitle(primaryTitle: String): String = {
  109. val source: Source[Map[String, String], _] = buildSource(inputFile = titleBasics)
  110. var tvSerie: TvSeries = null
  111. val res: Future[Option[String]] = source
  112. .filter((rowMap: Map[String, String]) => {
  113. rowMap.getOrElse(key = "primaryTitle", "") == primaryTitle
  114. })
  115. .map((rowMap: Map[String, String]) => {
  116. tvSerie = buildTvSerieModel(rowMap)
  117. rowMap.get("tconst")
  118. })
  119. .runWith(Sink.head)
  120. Await.result(res, 1 minutes)
  121. val tconst: String = res.value.get.get.get
  122. logger.info(s"TvSerie ID: $tconst, $tvSerie")
  123. tconst
  124. }
  125. private def getListOfPersonsIDByTvSerieID(tconst: String): List[Option[String]]={
  126. val source: Source[Map[String, String], _] = buildSource(inputFile = titlePrincipalsBasics)
  127. val startTime : Long = System.currentTimeMillis()
  128. val res: Future[IndexedSeq[Option[String]]] = source
  129. .filter((rowMaps: Map[String, String])=>{
  130. rowMaps.getOrElse(key = "tconst", default = "")==tconst
  131. })
  132. .map((rowMap: Map[String, String])=>{
  133. rowMap.get(key = "nconst")
  134. })
  135. .runWith(Sink.collection)
  136. .andThen {
  137. case Success(value) =>
  138. logger.info(s"$value")
  139. val elapsedTime : Long = (System.currentTimeMillis() - startTime)/1000
  140. logger.info(s"success, elapsed time: $elapsedTime")
  141. case Failure(error: Error) => logger.error(s"$error")
  142. }
  143. Await.result(res, 3 minutes)
  144. val listPersonsID: List[Option[String]] = res.value.get.get.toList
  145. listPersonsID
  146. }
  147. private def getListOfPersonsForTvSerie(nconstList: List[Option[String]]): List[Person] = {
  148. val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
  149. val startTime: Long = System.currentTimeMillis()
  150. val res : Future[IndexedSeq[Person]]= source
  151. .filter((rowMap: Map[String, String])=>{
  152. nconstList.contains(rowMap.getOrElse(key = "nconst",default = ""))
  153. })
  154. .map((rowMap: Map[String, String])=>{
  155. val person: Person = buildPersonModel(rowMap)
  156. person
  157. })
  158. .runWith(Sink.collection)
  159. .andThen {
  160. case Failure(exception) => logger.error(s"$exception")
  161. case Success(value) =>
  162. val elapsedTime: Long = (System.currentTimeMillis()-startTime)/1000
  163. logger.info(s"$value")
  164. logger.info(s"END: Successfully, elapsed time: $elapsedTime")
  165. }
  166. Await.result(res, 4 minutes)
  167. val listPersons: List[Person] = res.value.get.get.toList
  168. listPersons
  169. }
  170. override def generalize(tvSeriePrimaryTitle: String): Unit={
  171. val tvSerieID: String = getTvSerieIdByPrimaryTitle(primaryTitle = tvSeriePrimaryTitle)
  172. val listPersonIDs: List[Option[String]] = getListOfPersonsIDByTvSerieID(tconst = tvSerieID)
  173. getListOfPersonsForTvSerie(nconstList = listPersonIDs)
  174. }
  175. }

Powered by TurnKey Linux.