placidenduwayo před 1 rokem
rodič
revize
140fbebeea

+ 7
- 1
src/main/java/fr/natan/akkastreamfileprocessingapi/controller/MovieController.java Zobrazit soubor

@@ -35,11 +35,17 @@ public class MovieController {
35 35
         return new ResponseEntity<>("is running", HttpStatus.OK);
36 36
     }
37 37
 
38
-    @RequestMapping(value = "/persons/{personID}", method = RequestMethod.GET)
38
+    @RequestMapping(value = "/persons/id/{personID}", method = RequestMethod.GET)
39 39
     private ResponseEntity<String> getPersonByID(@PathVariable(name = "personID") String nconst){
40 40
        akkaStreamFilesProcessing.getPersonById(nconst);
41 41
 
42 42
        return new ResponseEntity<>("is running", HttpStatus.OK);
43 43
 
44 44
     }
45
+
46
+    @RequestMapping(value = "/persons/name/{primaryName}", method = RequestMethod.GET)
47
+    private ResponseEntity<String> getPersonByName(@PathVariable(name = "primaryName") String primaryName){
48
+        akkaStreamFilesProcessing.getPersonByName(primaryName);
49
+        return new ResponseEntity<>("is running", HttpStatus.OK);
50
+    }
45 51
 }

+ 0
- 5
src/main/scala/fr/natan/akkastreamfileprocessingapi/jsonformat/ToJsonMapping.scala Zobrazit soubor

@@ -1,5 +0,0 @@
1
-package fr.natan.akkastreamfileprocessingapi.jsonformat
2
-
3
-case class ToJsonMapping() {
4
-
5
-}

+ 48
- 0
src/main/scala/fr/natan/akkastreamfileprocessingapi/models/Models.scala Zobrazit soubor

@@ -0,0 +1,48 @@
1
+package fr.natan.akkastreamfileprocessingapi.models
2
+
3
+object Models {
4
+
5
+  final case class Person(
6
+                           nconst: String,
7
+                           primaryName: String,
8
+                           birthYear: String,
9
+                           deathYear: String,
10
+                           primaryProfession: List[String],
11
+                           knownForTitles: List[String]
12
+                         ) {
13
+    override def toString: String = {
14
+      "Person[person-ID:" + nconst +
15
+        ", primary-name:" + primaryName +
16
+        ", birth-year:" + birthYear +
17
+        ", dearth year:" + deathYear +
18
+        ", primary profession:" + primaryProfession +
19
+        ", known for titles:" + knownForTitles +
20
+        "]"
21
+    }
22
+  }
23
+
24
+  final case class TvSeries(
25
+                             tconst: String,
26
+                             titleType: String,
27
+                             primaryTitle: String,
28
+                             originalTitle: String,
29
+                             isAdult: String,
30
+                             startYear: String,
31
+                             endYear: String,
32
+                             runtimeMinutes: String,
33
+                             genres: String
34
+                           ) {
35
+
36
+    override def toString: String = {
37
+      "TvSerie[tvSerieID : " + tconst +
38
+        ", title-type:" + titleType +
39
+        ", primary-title:" + primaryTitle + "" +
40
+        ", riginal-title:" + originalTitle +
41
+        ", is adult (no=0, yes=1):" + isAdult +
42
+        ", start year:" + startYear +
43
+        ", end year:" + endYear +
44
+        ", runtime minutes:" + runtimeMinutes +
45
+        ", genre:" + genres + "]"
46
+    }
47
+  }
48
+}

+ 30
- 0
src/main/scala/fr/natan/akkastreamfileprocessingapi/models/ModelsBuilder.scala Zobrazit soubor

@@ -0,0 +1,30 @@
1
+package fr.natan.akkastreamfileprocessingapi.models
2
+import Models.{Person, TvSeries}
3
+object ModelsBuilder {
4
+
5
+  def buildPersonModel(map: Map[String, String]): Person = {
6
+    Person(
7
+      map("nconst"),
8
+      map("primaryName"),
9
+      map("birthYear"),
10
+      map("deathYear"),
11
+      map("primaryProfession").split(",").toList,
12
+      map("knownForTitles").split(",").toList,
13
+    )
14
+  }
15
+
16
+  def buildTvSerieModel(map: Map[String, String]): TvSeries = {
17
+    val tvSerie: TvSeries = TvSeries(
18
+      map("tconst"),
19
+      map("titleType"),
20
+      map("primaryTitle"),
21
+      map("originalTitle"),
22
+      map("isAdult"),
23
+      map("startYear"),
24
+      map("endYear"),
25
+      map("runtimeMinutes"),
26
+      map("genres")
27
+    )
28
+    tvSerie
29
+  }
30
+}

+ 0
- 20
src/main/scala/fr/natan/akkastreamfileprocessingapi/models/Person.scala Zobrazit soubor

@@ -1,20 +0,0 @@
1
-package fr.natan.akkastreamfileprocessingapi.models
2
-
3
-final case class Person(
4
-                         nconst: String,
5
-                         primaryName: String,
6
-                         birthYear: String,
7
-                         deathYear: String,
8
-                         primaryProfession: List[String],
9
-                         knownForTitles: List[String]
10
-                       ){
11
-  override def toString: String = {
12
-    "Person[ person-ID:"+nconst+
13
-      ", primary-name:"+primaryName+
14
-    ", birth-year:"+birthYear+
15
-    ", dearth year:"+deathYear+
16
-    ", primary profession:"+primaryProfession+
17
-    ", known for titles:"+knownForTitles+
18
-    "]"
19
-  }
20
-}

+ 0
- 26
src/main/scala/fr/natan/akkastreamfileprocessingapi/models/TvSeries.scala Zobrazit soubor

@@ -1,26 +0,0 @@
1
-package fr.natan.akkastreamfileprocessingapi.models
2
-
3
-final case class TvSeries(
4
-                     tconst: String,
5
-                     titleType: String,
6
-                     primaryTitle: String,
7
-                    originalTitle: String,
8
-                     isAdult: String,
9
-                     startYear: String,
10
-                    endYear: String,
11
-                     runtimeMinutes: String,
12
-                     genres: String
13
-                   ) {
14
-
15
-  override def toString: String = {
16
-    "TvSerie[tvSerieID : " + tconst +
17
-      ", title-type:"+titleType+
18
-      ", primary-title:"+primaryTitle+"" +
19
-      ", riginal-title:"+originalTitle+
20
-      ", is adult (no=0, yes=1):"+isAdult+
21
-      ", start year:"+startYear+
22
-    ", end year:"+endYear+
23
-      ", runtime minutes:"+runtimeMinutes+
24
-      ", genre:"+genres+"]"
25
-  }
26
-}

+ 34
- 45
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamComponents.scala Zobrazit soubor

@@ -2,15 +2,13 @@ package fr.natan.akkastreamfileprocessingapi.service
2 2
 
3 3
 import akka.actor.ActorSystem
4 4
 import akka.stream.alpakka.csv.scaladsl.{CsvParsing, CsvToMap}
5
-import akka.stream.javadsl.Framing
6 5
 import akka.stream.scaladsl.{Compression, FileIO, Flow, Sink, Source}
7
-import akka.util.ByteString
8 6
 import akka.{Done, NotUsed}
9 7
 import com.typesafe.scalalogging.slf4j.Logger
10 8
 import fr.natan.akkastreamfileprocessingapi.businessexceptions.FileNotFoundException
11
-import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.separator
12
-import fr.natan.akkastreamfileprocessingapi.models.{Person, TvSeries}
9
+import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSeries}
13 10
 import fr.natan.akkastreamfileprocessingapi.valitator.Validators.fileExists
11
+import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.{buildPersonModel, buildTvSerieModel}
14 12
 
15 13
 import java.io.File
16 14
 import java.nio.file.Paths
@@ -20,81 +18,71 @@ object AkkaStreamComponents {
20 18
 
21 19
   implicit val actor: ActorSystem = ActorSystem("AkkaStreamActor")
22 20
 
23
-  private def convertToTvSerie(map: Map[String, String]): TvSeries = {
24
-    val tvSerie: TvSeries = TvSeries(
25
-      map("tconst"),
26
-      map("titleType"),
27
-      map("primaryTitle"),
28
-      map("originalTitle"),
29
-      map("isAdult"),
30
-      map("startYear"),
31
-      map("endYear"),
32
-      map("runtimeMinutes"),
33
-      map("genres")
34
-    )
35
-
36
-    tvSerie
37
-  }
38
-
39
-  private def convertToPerson(map: Map[String, String]): Person ={
40
-    Person(
41
-      map("nconst"),
42
-      map("primaryName"),
43
-      map("birthYear"),
44
-      map("deathYear"),
45
-      map("primaryProfession").split(",").toList,
46
-      map("knownForTitles").split(",").toList,
47
-    )
48
-  }
49
-
50
-  //flows
21
+  //flows building
51 22
 
23
+  //flow1
52 24
   def buildTvSerieFlow(): Flow[Map[String, String], TvSeries, NotUsed] = {
53 25
 
54 26
     val tvFlow: Flow[Map[String, String], TvSeries, NotUsed] =
55 27
       Flow[Map[String, String]]
56 28
         .map(row => {
57
-          convertToTvSerie(row)
29
+          buildTvSerieModel(row)
58 30
         })
59 31
     tvFlow
60 32
   }
61 33
 
34
+  //flow2
62 35
   def buildPersonFlow(): Flow[Map[String, String], Person, NotUsed] = {
63 36
     val personFlow: Flow[Map[String, String], Person, NotUsed] =
64 37
       Flow[Map[String, String]]
65 38
         .map((rowMap: Map[String, String]) => {
66
-          convertToPerson(rowMap)
39
+          buildPersonModel(rowMap)
67 40
         })
68 41
 
69 42
     personFlow
70 43
   }
71 44
 
45
+  //flow3
72 46
   def filterByMoviePrimaryTitleFlow(moviePrimaryTitle: String): Flow[Map[String, String], TvSeries, NotUsed] = {
73 47
     val filterFlow: Flow[Map[String, String], TvSeries, NotUsed] = Flow[Map[String, String]]
74 48
         .filter((rows: Map[String, String]) => {
75 49
           rows.getOrElse("primaryTitle","")==moviePrimaryTitle
76 50
         })
77 51
         .map(rowMap => {
78
-          convertToTvSerie(map = rowMap)
52
+          buildTvSerieModel(map = rowMap)
79 53
         })
80 54
 
81 55
     filterFlow
82 56
   }
83 57
 
84
-  def filterByPersonID(nconst: String): Flow[Map[String, String], Person, NotUsed]={
58
+  //flow4
59
+  def filterByPersonIdFlow(nconst: String): Flow[Map[String, String], Person, NotUsed]={
85 60
     val personFilter: Flow[Map[String, String], Person, NotUsed]=
86 61
       Flow[Map[String, String]]
87 62
         .filter((rowMap:Map[String, String])=>{
88 63
           rowMap.getOrElse("nconst","")==nconst
89 64
         })
90 65
         .map(rowMap=>{
91
-          convertToPerson(map = rowMap)
66
+          buildPersonModel(map = rowMap)
67
+        })
68
+
69
+    personFilter
70
+  }
71
+
72
+  def filterByPersonNameFlow(personName: String): Flow[Map[String, String], Person, NotUsed] ={
73
+    val personFilter: Flow[Map[String, String], Person, NotUsed] =
74
+      Flow[Map[String, String]]
75
+        .filter((rowMap: Map[String, String]) =>{
76
+          rowMap.getOrElse("primaryName","")==personName
77
+        })
78
+        .map((rowMap: Map[String, String])=>{
79
+          buildPersonModel(map = rowMap)
92 80
         })
93 81
 
94 82
     personFilter
95 83
   }
96 84
 
97
-  //source
85
+  //source building
98 86
   def buildSource(inputFile: File): Source[Map[String, String], NotUsed] = {
99 87
 
100 88
     var datasource: Source[Map[String, String], NotUsed] = null
@@ -126,7 +114,9 @@ object AkkaStreamComponents {
126 114
     source
127 115
   }
128 116
 
129
-  //sink
117
+  //sinks building
118
+
119
+  //sink1
130 120
   def buildTvSeriesSink(logger: Logger): Sink[TvSeries, Future[Done]] = {
131 121
     val tvSeriesSink : Sink[TvSeries, Future[Done]]= Sink.foreach[TvSeries](
132 122
       (movie: TvSeries) => {
@@ -136,15 +126,14 @@ object AkkaStreamComponents {
136 126
     tvSeriesSink
137 127
   }
138 128
 
139
-  def buildPersonsSink(logger: Logger): Sink[Person,Future[Done]] = {
140
-    val listPersonsSink: Sink[Person, Future[Done]]=
141
-      Sink.foreach[Person]((person: Person)=>{
142
-        logger.info(s"${person.toString}")
143
-      })
144
-
129
+  //sink2
130
+  def buildAllPersonsSink(logger: Logger): Sink[Person,Future[Seq[Person]]] = {
131
+    val listPersonsSink: Sink[Person, Future[Seq[Person]]]=
132
+      Sink.seq
145 133
     listPersonsSink
146 134
   }
147 135
 
136
+  //sink3
148 137
   def buildPersonSink(logger: Logger): Sink[Person, Future[Done]] = {
149 138
     Sink.foreach[Person](
150 139
       (person: Person) => logger.info(s"${person.toString}")

+ 1
- 4
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamFileProcessing.scala Zobrazit soubor

@@ -1,9 +1,5 @@
1 1
 package fr.natan.akkastreamfileprocessingapi.service
2 2
 
3
-import akka.Done
4
-
5
-import scala.concurrent.Future
6
-
7 3
 trait AkkaStreamFileProcessing {
8 4
 
9 5
   def getAllMovies()
@@ -12,4 +8,5 @@ trait AkkaStreamFileProcessing {
12 8
   def getAllPersons()
13 9
 
14 10
   def getPersonById(nconst: String)
11
+  def getPersonByName(primaryName: String)
15 12
 }

+ 23
- 23
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamFileProcessingImpl.scala Zobrazit soubor

@@ -5,16 +5,8 @@ import akka.stream.scaladsl.{Flow, Sink, Source}
5 5
 import akka.{Done, NotUsed}
6 6
 import com.typesafe.scalalogging.slf4j.Logger
7 7
 import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.{nameBasics, titleBasics}
8
-import fr.natan.akkastreamfileprocessingapi.models.{Person, TvSeries}
9
-import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{
10
-  buildAndValidateSource,
11
-  buildPersonFlow,
12
-  buildPersonSink,
13
-  buildPersonsSink,
14
-  buildSource, buildTvSerieFlow,
15
-  buildTvSeriesSink, filterByMoviePrimaryTitleFlow,
16
-  filterByPersonID
17
-}
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}
18 10
 import org.slf4j.LoggerFactory
19 11
 import org.springframework.stereotype.Component
20 12
 
@@ -33,7 +25,6 @@ class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
33 25
     val source: Source[Map[String, String], NotUsed] = buildAndValidateSource(inputFile = titleBasics)
34 26
     val sink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger)
35 27
 
36
-
37 28
     val startingTime: Long = System.currentTimeMillis()
38 29
 
39 30
     //graph sink->flow->sink
@@ -51,10 +42,10 @@ class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
51 42
 
52 43
   override def getMoviesByTitle(moviePrimaryTitle: String): Unit = {
53 44
 
54
-    /*val tvSeriesSource: Source[String, NotUsed] = buildAndValidateSource(inputFile = titleBasics)
45
+    val tvSeriesSource: Source[Map[String, String], NotUsed] = buildAndValidateSource(inputFile = titleBasics)
55 46
     val tvSeriesSink: Sink[TvSeries, Future[Done]] = buildTvSeriesSink(logger = logger)
56 47
 
57
-    val filterByMovieTitleFlow: Flow[String, TvSeries, NotUsed] =
48
+    val filterByMovieTitleFlow: Flow[Map[String, String], TvSeries, NotUsed] =
58 49
       filterByMoviePrimaryTitleFlow(moviePrimaryTitle = moviePrimaryTitle)
59 50
 
60 51
     val startTime: Long = System.currentTimeMillis()
@@ -64,14 +55,14 @@ class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
64 55
       .andThen {
65 56
         case Success(value) =>
66 57
           val elapsedTime: Long = (System.currentTimeMillis() - startTime) / 1000
67
-          logger.info(s"$value: successfully processing file, elapsed time $titleBasics: $elapsedTime sec")
58
+          logger.info(s"$value: successfully processing file, elapsed time: $elapsedTime sec")
68 59
         case Failure(error: Error) => logger.error(s"$error")
69
-      }*/
60
+      }
70 61
   }
71 62
 
72 63
   override def getAllPersons(): Unit = {
73 64
     val personSource: Source[Map[String, String], NotUsed] = buildSource(inputFile = nameBasics)
74
-    val personSink: Sink[Person, Future[Done]] = buildPersonsSink(logger = logger)
65
+    val personSink: Sink[Person, Future[Done]] = buildPersonSink(logger = logger)
75 66
 
76 67
     //graph
77 68
     val startTime: Long = System.currentTimeMillis()
@@ -81,29 +72,38 @@ class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
81 72
       .andThen {
82 73
         case Success(value) =>
83 74
           val elapsedTime: Long = (System.currentTimeMillis() - startTime) / 1000
84
-          logger.info(s"$value: successfully processing file $elapsedTime sec")
75
+          logger.info(s"$value: successfully processing, elapsed time: $elapsedTime sec")
85 76
         case Failure(error: Error) => logger.error(s"$error")
86 77
       }
87 78
   }
88 79
 
89 80
   override def getPersonById(nconst: String): Unit = {
90 81
     val source: Source[Map[String, String], NotUsed] = buildSource(inputFile = nameBasics)
91
-    val sink: Sink[Person, Future[Done]] = buildPersonSink(logger = logger)
92 82
 
93 83
     val startTime: Long = System.currentTimeMillis()
94 84
     source
95
-      .via(flow = filterByPersonID(nconst = nconst))
96
-      .runWith(sink = sink)
85
+      .via(flow = filterByPersonIdFlow(nconst = nconst))
86
+      .runWith(sink = buildPersonSink(logger = logger))
97 87
       .andThen {
98
-        case Success(value) => {
88
+        case Success(value) =>
99 89
           val elapsedTime: Long = (System.currentTimeMillis()-startTime)/1000
100 90
           logger.info(s"$value: Successfully processed, elapsed time: $elapsedTime")
101
-        }
102 91
         case Failure(exception) => logger.error(s"$exception: Fail")
103 92
       }
104 93
   }
105 94
 
106
-
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
+  }
107 107
 }
108 108
 
109 109
 

Powered by TurnKey Linux.