Browse Source

first commit

placidenduwayo 2 years ago
parent
commit
1c8c64627a

+ 13
- 14
src/main/java/fr/natan/akkastreamfileprocessingapi/controller/MovieController.java View File

17
         this.akkaStreamFilesProcessing = akkaStreamFilesProcessing;
17
         this.akkaStreamFilesProcessing = akkaStreamFilesProcessing;
18
     }
18
     }
19
 
19
 
20
-    @RequestMapping(value = "/movies", method = RequestMethod.GET)
21
-    private ResponseEntity<String> getAllMovies() {
22
-        akkaStreamFilesProcessing.getAllMovies();
23
-        return new ResponseEntity<>("is running", HttpStatus.OK);
24
-    }
25
-
26
-    @RequestMapping(value = "/movies/{movieTitle}", method = RequestMethod.GET)
27
-    private ResponseEntity<String> getMovieByTitle(@PathVariable(name ="movieTitle" ) String movieTitle){
28
-        akkaStreamFilesProcessing.getMoviesByTitle(movieTitle);
29
-        return new ResponseEntity<>("is running", HttpStatus.OK);
30
-    }
31
-
32
     @RequestMapping(value = "/persons", method = RequestMethod.GET)
20
     @RequestMapping(value = "/persons", method = RequestMethod.GET)
33
     private ResponseEntity<String> getallPersons(){
21
     private ResponseEntity<String> getallPersons(){
34
         akkaStreamFilesProcessing.getAllPersons();
22
         akkaStreamFilesProcessing.getAllPersons();
37
 
25
 
38
     @RequestMapping(value = "/persons/id/{personID}", method = RequestMethod.GET)
26
     @RequestMapping(value = "/persons/id/{personID}", method = RequestMethod.GET)
39
     private ResponseEntity<String> getPersonByID(@PathVariable(name = "personID") String nconst){
27
     private ResponseEntity<String> getPersonByID(@PathVariable(name = "personID") String nconst){
40
-       akkaStreamFilesProcessing.getPersonById(nconst);
41
 
28
 
42
-       return new ResponseEntity<>("is running", HttpStatus.OK);
29
+       return new ResponseEntity<>(akkaStreamFilesProcessing.getPersonById(nconst).toString(), HttpStatus.OK);
43
 
30
 
44
     }
31
     }
45
 
32
 
48
         akkaStreamFilesProcessing.getPersonByName(primaryName);
35
         akkaStreamFilesProcessing.getPersonByName(primaryName);
49
         return new ResponseEntity<>("is running", HttpStatus.OK);
36
         return new ResponseEntity<>("is running", HttpStatus.OK);
50
     }
37
     }
38
+
39
+    @RequestMapping(value = "/movies", method = RequestMethod.GET)
40
+    private ResponseEntity<String> getAllMovies() {
41
+        akkaStreamFilesProcessing.getAllTvSeries();
42
+        return new ResponseEntity<>("is running", HttpStatus.OK);
43
+    }
44
+
45
+    @RequestMapping(value = "/movies/{movieTitle}", method = RequestMethod.GET)
46
+    private ResponseEntity<String> getMovieByTitle(@PathVariable(name ="movieTitle" ) String movieTitle){
47
+        akkaStreamFilesProcessing.getByTvSeriePrimaryTitle(movieTitle);
48
+        return new ResponseEntity<>("is running", HttpStatus.OK);
49
+    }
51
 }
50
 }

+ 15
- 0
src/main/scala/fr/natan/akkastreamfileprocessingapi/models/Models.scala View File

19
         ", known for titles:" + knownForTitles +
19
         ", known for titles:" + knownForTitles +
20
         "]"
20
         "]"
21
     }
21
     }
22
+
23
+    def getNconst: String={
24
+      nconst
25
+    }
26
+    def getPrimaryName: String = {
27
+      primaryName
28
+    }
22
   }
29
   }
23
 
30
 
24
   final case class TvSeries(
31
   final case class TvSeries(
44
         ", runtime minutes:" + runtimeMinutes +
51
         ", runtime minutes:" + runtimeMinutes +
45
         ", genre:" + genres + "]"
52
         ", genre:" + genres + "]"
46
     }
53
     }
54
+
55
+   def getTconst: String= {
56
+     tconst
57
+   }
58
+    def getPrimaryTitle: String={
59
+      primaryTitle
60
+    }
47
   }
61
   }
62
+
48
 }
63
 }

+ 30
- 30
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamComponents.scala View File

21
   //flows building
21
   //flows building
22
 
22
 
23
   //flow1
23
   //flow1
24
-  def buildTvSerieFlow(): Flow[Map[String, String], TvSeries, NotUsed] = {
25
-
26
-    val tvFlow: Flow[Map[String, String], TvSeries, NotUsed] =
27
-      Flow[Map[String, String]]
28
-        .map(row => {
29
-          buildTvSerieModel(row)
30
-        })
31
-    tvFlow
32
-  }
33
-
34
-  //flow2
35
   def buildPersonFlow(): Flow[Map[String, String], Person, NotUsed] = {
24
   def buildPersonFlow(): Flow[Map[String, String], Person, NotUsed] = {
36
     val personFlow: Flow[Map[String, String], Person, NotUsed] =
25
     val personFlow: Flow[Map[String, String], Person, NotUsed] =
37
       Flow[Map[String, String]]
26
       Flow[Map[String, String]]
42
     personFlow
31
     personFlow
43
   }
32
   }
44
 
33
 
34
+  //flow2
35
+
36
+  def buildTvSerieFlow(): Flow[Map[String, String], TvSeries, NotUsed] = {
37
+
38
+    val tvFlow: Flow[Map[String, String], TvSeries, NotUsed] =
39
+      Flow[Map[String, String]]
40
+        .map(row => {
41
+          buildTvSerieModel(row)
42
+        })
43
+    tvFlow
44
+  }
45
+
45
   //flow3
46
   //flow3
46
-  def filterByMoviePrimaryTitleFlow(moviePrimaryTitle: String): Flow[Map[String, String], TvSeries, NotUsed] = {
47
+  def filterByTvSeriePrimaryTitleFlow(tvSeriePrimaryTitle: String): Flow[Map[String, String], TvSeries, NotUsed] = {
47
     val filterFlow: Flow[Map[String, String], TvSeries, NotUsed] = Flow[Map[String, String]]
48
     val filterFlow: Flow[Map[String, String], TvSeries, NotUsed] = Flow[Map[String, String]]
48
         .filter((rows: Map[String, String]) => {
49
         .filter((rows: Map[String, String]) => {
49
-          rows.getOrElse("primaryTitle","")==moviePrimaryTitle
50
+          rows.getOrElse(key = "primaryName", default = "")==tvSeriePrimaryTitle
50
         })
51
         })
51
         .map(rowMap => {
52
         .map(rowMap => {
52
-          buildTvSerieModel(map = rowMap)
53
+          val tvSerie: TvSeries = buildTvSerieModel(map = rowMap)
54
+          tvSerie
53
         })
55
         })
54
 
56
 
55
     filterFlow
57
     filterFlow
60
     val personFilter: Flow[Map[String, String], Person, NotUsed]=
62
     val personFilter: Flow[Map[String, String], Person, NotUsed]=
61
       Flow[Map[String, String]]
63
       Flow[Map[String, String]]
62
         .filter((rowMap:Map[String, String])=>{
64
         .filter((rowMap:Map[String, String])=>{
63
-          rowMap.getOrElse("nconst","")==nconst
65
+          rowMap.getOrElse(key="nconst",default="")==nconst
64
         })
66
         })
65
         .map(rowMap=>{
67
         .map(rowMap=>{
66
           buildPersonModel(map = rowMap)
68
           buildPersonModel(map = rowMap)
69
     personFilter
71
     personFilter
70
   }
72
   }
71
 
73
 
74
+  //flow5
72
   def filterByPersonNameFlow(personName: String): Flow[Map[String, String], Person, NotUsed] ={
75
   def filterByPersonNameFlow(personName: String): Flow[Map[String, String], Person, NotUsed] ={
73
     val personFilter: Flow[Map[String, String], Person, NotUsed] =
76
     val personFilter: Flow[Map[String, String], Person, NotUsed] =
74
       Flow[Map[String, String]]
77
       Flow[Map[String, String]]
75
         .filter((rowMap: Map[String, String]) =>{
78
         .filter((rowMap: Map[String, String]) =>{
76
-          rowMap.getOrElse("primaryName","")==personName
79
+          rowMap.getOrElse(key = "primaryName", default = "")==personName
77
         })
80
         })
78
         .map((rowMap: Map[String, String])=>{
81
         .map((rowMap: Map[String, String])=>{
79
           buildPersonModel(map = rowMap)
82
           buildPersonModel(map = rowMap)
83
   }
86
   }
84
 
87
 
85
   //source building
88
   //source building
86
-  def buildSource(inputFile: File): Source[Map[String, String], NotUsed] = {
87
 
89
 
88
-    var datasource: Source[Map[String, String], NotUsed] = null
90
+  def buildSource(inputFile: File): Source[Map[String, String], _] = {
89
 
91
 
92
+    var datasource: Source[Map[String, String], NotUsed] = null
90
     if (!fileExists(inputFile.getPath)) {
93
     if (!fileExists(inputFile.getPath)) {
91
       return null
94
       return null
92
     }
95
     }
105
     datasource
108
     datasource
106
   }
109
   }
107
 
110
 
108
-  def buildAndValidateSource(inputFile: File): Source[Map[String, String], NotUsed] = {
111
+  def buildAndValidateSource(inputFile: File): Source[Map[String, String], _] = {
109
 
112
 
110
-    val source: Source[Map[String, String], NotUsed] = buildSource(inputFile = inputFile)
113
+    val source: Source[Map[String, String], _] = buildSource(inputFile = inputFile)
111
     if (source == null) {
114
     if (source == null) {
112
       throw new FileNotFoundException(filename = inputFile.getPath)
115
       throw new FileNotFoundException(filename = inputFile.getPath)
113
     }
116
     }
115
   }
118
   }
116
 
119
 
117
   //sinks building
120
   //sinks building
118
-
119
   //sink1
121
   //sink1
120
   def buildTvSeriesSink(logger: Logger): Sink[TvSeries, Future[Done]] = {
122
   def buildTvSeriesSink(logger: Logger): Sink[TvSeries, Future[Done]] = {
121
     val tvSeriesSink : Sink[TvSeries, Future[Done]]= Sink.foreach[TvSeries](
123
     val tvSeriesSink : Sink[TvSeries, Future[Done]]= Sink.foreach[TvSeries](
122
-      (movie: TvSeries) => {
123
-        logger.info(s"${movie.toString}")
124
+      (tvSerie: TvSeries) => {
125
+        logger.info(s"${tvSerie.toString}")
124
       }
126
       }
125
     )
127
     )
126
     tvSeriesSink
128
     tvSeriesSink
127
   }
129
   }
128
 
130
 
129
   //sink2
131
   //sink2
130
-  def buildAllPersonsSink(logger: Logger): Sink[Person,Future[Seq[Person]]] = {
131
-    val listPersonsSink: Sink[Person, Future[Seq[Person]]]=
132
-      Sink.seq
132
+  def buildAllPersonsSink(logger: Logger): Sink[Person,Future[Done]] = {
133
+    val listPersonsSink: Sink[Person, Future[Done]]=
134
+      Sink.foreach[Person]((person: Person)=>logger.info(s"${person.toString}"))
133
     listPersonsSink
135
     listPersonsSink
134
   }
136
   }
135
 
137
 
136
   //sink3
138
   //sink3
137
-  def buildPersonSink(logger: Logger): Sink[Person, Future[Done]] = {
138
-    Sink.foreach[Person](
139
-      (person: Person) => logger.info(s"${person.toString}")
140
-    )
139
+  def buildPersonSink(): Sink[Person, Future[Person]] = {
140
+    Sink.head
141
   }
141
   }
142
 }
142
 }

+ 7
- 5
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamFileProcessing.scala View File

1
 package fr.natan.akkastreamfileprocessingapi.service
1
 package fr.natan.akkastreamfileprocessingapi.service
2
 
2
 
3
+import fr.natan.akkastreamfileprocessingapi.models.Models.Person
4
+
3
 trait AkkaStreamFileProcessing {
5
 trait AkkaStreamFileProcessing {
6
+  def getAllPersons(): Unit
4
 
7
 
5
-  def getAllMovies()
6
-  def getMoviesByTitle (movieTitle: String)
8
+  def getPersonById(nconst: String): Person
9
+  def getPersonByName(primaryName: String): Unit
7
 
10
 
8
-  def getAllPersons()
11
+  def getAllTvSeries(): Unit
9
 
12
 
10
-  def getPersonById(nconst: String)
11
-  def getPersonByName(primaryName: String)
13
+  def getByTvSeriePrimaryTitle(tvSerieTitle: String): Unit
12
 }
14
 }

+ 77
- 48
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamFileProcessingImpl.scala View File

6
 import com.typesafe.scalalogging.slf4j.Logger
6
 import com.typesafe.scalalogging.slf4j.Logger
7
 import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.{nameBasics, titleBasics}
7
 import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.{nameBasics, titleBasics}
8
 import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSeries}
8
 import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSeries}
9
-import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{buildAndValidateSource, buildPersonFlow, buildPersonSink, buildSource, buildTvSerieFlow, buildTvSeriesSink, filterByMoviePrimaryTitleFlow, filterByPersonIdFlow, filterByPersonNameFlow}
9
+import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.buildTvSerieModel
10
+import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{buildAllPersonsSink, buildAndValidateSource, buildPersonFlow, buildPersonSink, buildSource, buildTvSerieFlow, buildTvSeriesSink, filterByPersonIdFlow, filterByPersonNameFlow, filterByTvSeriePrimaryTitleFlow}
10
 import org.slf4j.LoggerFactory
11
 import org.slf4j.LoggerFactory
11
 import org.springframework.stereotype.Component
12
 import org.springframework.stereotype.Component
12
 
13
 
13
 import scala.concurrent.ExecutionContext.Implicits.global
14
 import scala.concurrent.ExecutionContext.Implicits.global
14
-import scala.concurrent.Future
15
+import scala.concurrent.duration.DurationInt
16
+import scala.concurrent.{Await, Future}
15
 import scala.util.{Failure, Success}
17
 import scala.util.{Failure, Success}
16
 
18
 
17
 @Component
19
 @Component
20
   implicit val actorSystem: ActorSystem = ActorSystem("AkkaStreamActor")
22
   implicit val actorSystem: ActorSystem = ActorSystem("AkkaStreamActor")
21
   implicit val logger: Logger = Logger(LoggerFactory.getLogger(this.getClass))
23
   implicit val logger: Logger = Logger(LoggerFactory.getLogger(this.getClass))
22
 
24
 
23
-  override def getAllMovies(): Unit = {
25
+  override def getAllPersons(): Unit = {
26
+    val personSource: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
27
+    val personSink: Sink[Person, Future[Done]] = buildAllPersonsSink(logger = logger)
28
+
29
+    //graph
30
+    val startTime: Long = System.currentTimeMillis()
31
+    val result: Future[Done] = personSource
32
+      .via(flow = buildPersonFlow())
33
+      .runWith(sink = personSink)
34
+      .andThen {
35
+        case Success(value) =>
36
+          val elapsedTime: Long = (System.currentTimeMillis() - startTime) / 1000
37
+          logger.info(s"$value: Successfully processed, elapsed time: $elapsedTime")
38
+        case Failure(exception) => logger.error(s"$exception: Fail")
39
+      }
40
+  }
41
+
42
+  override def getPersonById(nconst: String): Person = {
43
+    val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
44
+
45
+    val startTime: Long = System.currentTimeMillis()
46
+    val res = source
47
+      .via(flow = filterByPersonIdFlow(nconst = nconst))
48
+      .runWith(sink = buildPersonSink())
49
+     .andThen {
50
+        case Success(value) =>
51
+          val elapsedTime: Long = (System.currentTimeMillis()-startTime)/1000
52
+          logger.info(s"$value: Successfully processed, elapsed time: $elapsedTime")
53
+        case Failure(exception) => logger.error(s"$exception: Fail")
54
+      }
55
+
56
+    Await.result(res,1 minutes)
57
+    val person: Person = res.value.get.get
58
+    person
59
+  }
60
+
61
+  override def getPersonByName(primaryName: String): Unit = {
62
+    val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
63
+    source
64
+      .via(
65
+        flow = filterByPersonNameFlow(personName = primaryName)
66
+      )
67
+      .runWith(sink = buildPersonSink())
68
+      .andThen {
69
+        case Failure(exception) => logger.info(s"$exception")
70
+        case Success(value) => logger.info(s"$value: Successufully processing")
71
+      }
72
+  }
24
 
73
 
25
-    val source: Source[Map[String, String], NotUsed] = buildAndValidateSource(inputFile = titleBasics)
74
+  override def getAllTvSeries(): Unit = {
75
+
76
+    val source: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
26
     val sink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger)
77
     val sink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger)
27
 
78
 
28
     val startingTime: Long = System.currentTimeMillis()
79
     val startingTime: Long = System.currentTimeMillis()
40
 
91
 
41
   }
92
   }
42
 
93
 
43
-  override def getMoviesByTitle(moviePrimaryTitle: String): Unit = {
94
+  override def getByTvSeriePrimaryTitle(tvSeriePrimaryTitle: String): Unit = {
44
 
95
 
45
-    val tvSeriesSource: Source[Map[String, String], NotUsed] = buildAndValidateSource(inputFile = titleBasics)
96
+    val tvSeriesSource: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
46
     val tvSeriesSink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger)
97
     val tvSeriesSink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger)
47
 
98
 
48
     val filterByMovieTitleFlow: Flow[Map[String, String], TvSeries, NotUsed] =
99
     val filterByMovieTitleFlow: Flow[Map[String, String], TvSeries, NotUsed] =
49
-      filterByMoviePrimaryTitleFlow(moviePrimaryTitle = moviePrimaryTitle)
100
+      filterByTvSeriePrimaryTitleFlow(tvSeriePrimaryTitle = tvSeriePrimaryTitle)
50
 
101
 
51
     val startTime: Long = System.currentTimeMillis()
102
     val startTime: Long = System.currentTimeMillis()
52
     val listTvSeries: Future[Done] = tvSeriesSource
103
     val listTvSeries: Future[Done] = tvSeriesSource
58
           logger.info(s"$value: successfully processing file, elapsed time: $elapsedTime sec")
109
           logger.info(s"$value: successfully processing file, elapsed time: $elapsedTime sec")
59
         case Failure(error: Error) => logger.error(s"$error")
110
         case Failure(error: Error) => logger.error(s"$error")
60
       }
111
       }
61
-  }
62
 
112
 
63
-  override def getAllPersons(): Unit = {
64
-    val personSource: Source[Map[String, String], NotUsed] = buildSource(inputFile = nameBasics)
65
-    val personSink: Sink[Person, Future[Done]] = buildPersonSink(logger = logger)
66
-
67
-    //graph
68
-    val startTime: Long = System.currentTimeMillis()
69
-    personSource
70
-      .via(flow = buildPersonFlow())
71
-      .runWith(sink = personSink)
72
-      .andThen {
73
-        case Success(value) =>
74
-          val elapsedTime: Long = (System.currentTimeMillis() - startTime) / 1000
75
-          logger.info(s"$value: successfully processing, elapsed time: $elapsedTime sec")
76
-        case Failure(error: Error) => logger.error(s"$error")
77
-      }
113
+    getTvSerieIdByPrimaryTitle(primaryTitle = tvSeriePrimaryTitle)
78
   }
114
   }
79
 
115
 
80
-  override def getPersonById(nconst: String): Unit = {
81
-    val source: Source[Map[String, String], NotUsed] = buildSource(inputFile = nameBasics)
82
-
83
-    val startTime: Long = System.currentTimeMillis()
84
-    source
85
-      .via(flow = filterByPersonIdFlow(nconst = nconst))
86
-      .runWith(sink = buildPersonSink(logger = logger))
87
-      .andThen {
88
-        case Success(value) =>
89
-          val elapsedTime: Long = (System.currentTimeMillis()-startTime)/1000
90
-          logger.info(s"$value: Successfully processed, elapsed time: $elapsedTime")
91
-        case Failure(exception) => logger.error(s"$exception: Fail")
92
-      }
116
+  private def getTvSerieIdByPrimaryTitle(primaryTitle: String): String ={
117
+    val source: Source[Map[String, String],_]= buildSource(inputFile = titleBasics)
118
+
119
+    var tvSerie: TvSeries =null
120
+    val res : Future[Option[String]]= source
121
+      .filter((rowMap: Map[String, String]) =>{
122
+        rowMap.getOrElse(key = "primaryTitle","")==primaryTitle
123
+      })
124
+      .map((rowMap: Map[String, String])=>{
125
+        tvSerie = buildTvSerieModel(rowMap)
126
+        rowMap.get("tconst")
127
+      })
128
+      .runWith(Sink.head)
129
+
130
+   Await.result(res,1 minutes)
131
+    val tconst:String = res.value.get.get.get
132
+    tconst
93
   }
133
   }
94
 
134
 
95
-  override def getPersonByName(primaryName: String): Unit = {
96
-    val source: Source[Map[String, String], NotUsed] = buildSource(inputFile = nameBasics)
97
-    source
98
-      .via(
99
-        flow = filterByPersonNameFlow(personName = primaryName)
100
-      )
101
-      .runWith(sink = buildPersonSink(logger = logger))
102
-      .andThen {
103
-        case Failure(exception) => logger.info(s"$exception")
104
-        case Success(value) => logger.info(s"$value: Successufully processing")
105
-      }
106
-  }
135
+
107
 }
136
 }
108
 
137
 
109
 
138
 

Powered by TurnKey Linux.