Bez popisu

AkkaStreamComponents.scala 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package fr.natan.akkastreamfileprocessingapi.service
  2. import akka.actor.ActorSystem
  3. import akka.stream.alpakka.csv.scaladsl.{CsvParsing, CsvToMap}
  4. import akka.stream.javadsl.Framing
  5. import akka.stream.scaladsl.{Compression, FileIO, Flow, Sink, Source}
  6. import akka.util.ByteString
  7. import akka.{Done, NotUsed}
  8. import com.typesafe.scalalogging.slf4j.Logger
  9. import fr.natan.akkastreamfileprocessingapi.businessexceptions.FileNotFoundException
  10. import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.separator
  11. import fr.natan.akkastreamfileprocessingapi.models.{Person, TvSeries}
  12. import fr.natan.akkastreamfileprocessingapi.valitator.Validators.fileExists
  13. import java.io.File
  14. import java.nio.file.Paths
  15. import scala.concurrent.Future
  16. object AkkaStreamComponents {
  17. implicit val actor: ActorSystem = ActorSystem("AkkaStreamActor")
  18. private def convertToTvSerie(map: Map[String, String]): TvSeries = {
  19. val tvSerie: TvSeries = TvSeries(
  20. map("tconst"),
  21. map("titleType"),
  22. map("primaryTitle"),
  23. map("originalTitle"),
  24. map("isAdult"),
  25. map("startYear"),
  26. map("endYear"),
  27. map("runtimeMinutes"),
  28. map("genres")
  29. )
  30. tvSerie
  31. }
  32. private def convertToPerson(map: Map[String, String]): Person ={
  33. Person(
  34. map("nconst"),
  35. map("primaryName"),
  36. map("birthYear"),
  37. map("deathYear"),
  38. map("primaryProfession").split(",").toList,
  39. map("knownForTitles").split(",").toList,
  40. )
  41. }
  42. //flows
  43. def buildTvSerieFlow(): Flow[Map[String, String], TvSeries, NotUsed] = {
  44. val tvFlow: Flow[Map[String, String], TvSeries, NotUsed] =
  45. Flow[Map[String, String]]
  46. .map(row => {
  47. convertToTvSerie(row)
  48. })
  49. tvFlow
  50. }
  51. def buildPersonFlow(): Flow[Map[String, String], Person, NotUsed] = {
  52. val personFlow: Flow[Map[String, String], Person, NotUsed] =
  53. Flow[Map[String, String]]
  54. .map((rowMap: Map[String, String]) => {
  55. convertToPerson(rowMap)
  56. })
  57. personFlow
  58. }
  59. def filterByMoviePrimaryTitleFlow(moviePrimaryTitle: String): Flow[Map[String, String], TvSeries, NotUsed] = {
  60. val filterFlow: Flow[Map[String, String], TvSeries, NotUsed] = Flow[Map[String, String]]
  61. .filter((rows: Map[String, String]) => {
  62. rows.getOrElse("primaryTitle","")==moviePrimaryTitle
  63. })
  64. .map(rowMap => {
  65. convertToTvSerie(map = rowMap)
  66. })
  67. filterFlow
  68. }
  69. def filterByPersonID(nconst: String): Flow[Map[String, String], Person, NotUsed]={
  70. val personFilter: Flow[Map[String, String], Person, NotUsed]=
  71. Flow[Map[String, String]]
  72. .filter((rowMap:Map[String, String])=>{
  73. rowMap.getOrElse("nconst","")==nconst
  74. })
  75. .map(rowMap=>{
  76. convertToPerson(map = rowMap)
  77. })
  78. personFilter
  79. }
  80. //source
  81. def buildSource(inputFile: File): Source[Map[String, String], NotUsed] = {
  82. var datasource: Source[Map[String, String], NotUsed] = null
  83. if (!fileExists(inputFile.getPath)) {
  84. return null
  85. }
  86. datasource = Source
  87. .single(inputFile)
  88. .flatMapConcat((filename: File) => {
  89. FileIO.fromPath(
  90. Paths.get(filename.getPath)
  91. )
  92. }
  93. )
  94. .via(Compression.gunzip())
  95. .via(CsvParsing.lineScanner(CsvParsing.Tab, CsvParsing.DoubleQuote))
  96. .via(CsvToMap.toMapAsStrings())
  97. datasource
  98. }
  99. def buildAndValidateSource(inputFile: File): Source[Map[String, String], NotUsed] = {
  100. val source: Source[Map[String, String], NotUsed] = buildSource(inputFile = inputFile)
  101. if (source == null) {
  102. throw new FileNotFoundException(filename = inputFile.getPath)
  103. }
  104. source
  105. }
  106. //sink
  107. def buildTvSeriesSink(logger: Logger): Sink[TvSeries, Future[Done]] = {
  108. val tvSeriesSink : Sink[TvSeries, Future[Done]]= Sink.foreach[TvSeries](
  109. (movie: TvSeries) => {
  110. logger.info(s"${movie.toString}")
  111. }
  112. )
  113. tvSeriesSink
  114. }
  115. def buildPersonsSink(logger: Logger): Sink[Person,Future[Done]] = {
  116. val listPersonsSink: Sink[Person, Future[Done]]=
  117. Sink.foreach[Person]((person: Person)=>{
  118. logger.info(s"${person.toString}")
  119. })
  120. listPersonsSink
  121. }
  122. def buildPersonSink(logger: Logger): Sink[Person, Future[Done]] = {
  123. Sink.foreach[Person](
  124. (person: Person) => logger.info(s"${person.toString}")
  125. )
  126. }
  127. }

Powered by TurnKey Linux.