瀏覽代碼

first commit

placidenduwayo 1 年之前
父節點
當前提交
2c06acafc5

+ 3
- 2
src/main/java/fr/natan/akkastreamfileprocessingapi/controller/MovieController.java 查看文件

@@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
8 8
 import org.springframework.web.bind.annotation.RequestMethod;
9 9
 import org.springframework.web.bind.annotation.RestController;
10 10
 
11
+@SuppressWarnings("SpellCheckingInspection")
11 12
 @RestController
12 13
 public class MovieController {
13 14
 
@@ -18,7 +19,7 @@ public class MovieController {
18 19
     }
19 20
 
20 21
     @RequestMapping(value = "/persons", method = RequestMethod.GET)
21
-    private ResponseEntity<String> getallPersons(){
22
+    private ResponseEntity<String> getAllPersons(){
22 23
         akkaStreamFilesProcessing.getAllPersons();
23 24
         return new ResponseEntity<>("is running", HttpStatus.OK);
24 25
     }
@@ -49,7 +50,7 @@ public class MovieController {
49 50
     }
50 51
 
51 52
     @RequestMapping(value = "/tvseries/title/{tvSerieTitle}", method = RequestMethod.GET)
52
-    private ResponseEntity<String> getListOfPersonsIDByTvSerieID(@PathVariable(name = "tvSerieTitle") String tvSerieTitle){
53
+    private ResponseEntity<String> getListOfPersonsByTvSerieitle(@PathVariable(name = "tvSerieTitle") String tvSerieTitle){
53 54
       akkaStreamFilesProcessing.getPersonsTeamForTvSerie(tvSerieTitle);
54 55
        return new ResponseEntity<>("is running", HttpStatus.OK);
55 56
     }

+ 1
- 1
src/main/resources/application.yml 查看文件

@@ -1,5 +1,5 @@
1 1
 server:
2
-  port: 8090
2
+  port: 8091
3 3
   servlet:
4 4
     context-path: /path
5 5
 spring:

+ 13
- 32
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamComponents.scala 查看文件

@@ -12,16 +12,15 @@ import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.{buildPersonMod
12 12
 
13 13
 import java.io.File
14 14
 import java.nio.file.Paths
15
-import java.util
16 15
 import scala.concurrent.Future
17 16
 
17
+//noinspection SpellCheckingInspection
18 18
 object AkkaStreamComponents {
19 19
 
20 20
   implicit val actor: ActorSystem = ActorSystem("AkkaStreamActor")
21 21
 
22 22
   //flows building
23 23
 
24
-  //flow1
25 24
   def buildPersonFlow(): Flow[Map[String, String], Person, NotUsed] = {
26 25
     val personFlow: Flow[Map[String, String], Person, NotUsed] =
27 26
       Flow[Map[String, String]]
@@ -32,19 +31,6 @@ object AkkaStreamComponents {
32 31
     personFlow
33 32
   }
34 33
 
35
-  //flow2
36
-
37
-  def buildTvSerieFlow(): Flow[Map[String, String], TvSeries, NotUsed] = {
38
-
39
-    val tvFlow: Flow[Map[String, String], TvSeries, NotUsed] =
40
-      Flow[Map[String, String]]
41
-        .map(row => {
42
-          buildTvSerieModel(row)
43
-        })
44
-    tvFlow
45
-  }
46
-
47
-  //flow3
48 34
   def filterByTvSeriePrimaryTitleFlow(tvSeriePrimaryTitle: String): Flow[Map[String, String], TvSeries, NotUsed] = {
49 35
     val filterFlow: Flow[Map[String, String], TvSeries, NotUsed] = Flow[Map[String, String]]
50 36
         .filter((rows: Map[String, String]) => {
@@ -58,7 +44,6 @@ object AkkaStreamComponents {
58 44
     filterFlow
59 45
   }
60 46
 
61
-  //flow4
62 47
   def filterByPersonIdFlow(nconst: String): Flow[Map[String, String], Person, NotUsed]={
63 48
     val personFilter: Flow[Map[String, String], Person, NotUsed]=
64 49
       Flow[Map[String, String]]
@@ -72,12 +57,11 @@ object AkkaStreamComponents {
72 57
     personFilter
73 58
   }
74 59
 
75
-  //flow5
76
-  def filterByPersonNameFlow(personName: String): Flow[Map[String, String], Person, NotUsed] ={
60
+  def filterByPersonNameFlow(primaryName: String): Flow[Map[String, String], Person, NotUsed] ={
77 61
     val personFilter: Flow[Map[String, String], Person, NotUsed] =
78 62
       Flow[Map[String, String]]
79 63
         .filter((rowMap: Map[String, String]) =>{
80
-          rowMap.getOrElse(key = "primaryName", default = "")==personName
64
+          rowMap.getOrElse(key = "primaryName", default = "")==primaryName
81 65
         })
82 66
         .map((rowMap: Map[String, String])=>{
83 67
           buildPersonModel(personMap = rowMap)
@@ -86,6 +70,15 @@ object AkkaStreamComponents {
86 70
     personFilter
87 71
   }
88 72
 
73
+  def buildTvSerieFlow(): Flow[Map[String, String], TvSeries, NotUsed] = {
74
+
75
+    val tvFlow: Flow[Map[String, String], TvSeries, NotUsed] =
76
+      Flow[Map[String, String]]
77
+        .map((rowMap: Map[String, String]) => {
78
+          buildTvSerieModel(tvSerieMap = rowMap)
79
+        })
80
+    tvFlow
81
+  }
89 82
   //source building
90 83
 
91 84
   def buildSource(inputFile: File): Source[Map[String, String], NotUsed] = {
@@ -103,7 +96,7 @@ object AkkaStreamComponents {
103 96
       }
104 97
       )
105 98
       .via(Compression.gunzip())
106
-      .via(CsvParsing.lineScanner(CsvParsing.Tab))
99
+      .via(CsvParsing.lineScanner(CsvParsing.Tab, CsvParsing.DoubleQuote, CsvParsing.DoubleQuote))
107 100
       .via(CsvToMap.toMapAsStrings())
108 101
 
109 102
     datasource
@@ -119,27 +112,15 @@ object AkkaStreamComponents {
119 112
   }
120 113
 
121 114
   //sinks building
122
-  //sink1
123
-  def buildTvSeriesSink(logger: Logger): Sink[TvSeries, Future[Done]] = {
124
-    val tvSeriesSink : Sink[TvSeries, Future[Done]]= Sink
125
-      .foreach((tvSerie: TvSeries)=> logger.info(s"${tvSerie.toString}"))
126
-    tvSeriesSink
127
-  }
128 115
 
129 116
   def buildAllTvSeriesSink(logger: Logger): Sink[TvSeries, Future[Done]] = {
130 117
     val tvSeriesSink: Sink[TvSeries, Future[Done]] = Sink
131 118
       .foreach((tvSerie: TvSeries)=>logger.info(s"${tvSerie.toString}"))
132 119
     tvSeriesSink
133 120
   }
134
-  //sink2
135 121
   def buildAllPersonsSink(logger: Logger): Sink[Person,Future[Done]] = {
136 122
     val listPersonsSink: Sink[Person, Future[Done]]=
137 123
       Sink.foreach((person: Person)=>logger.info(s"${person.toString}"))
138 124
     listPersonsSink
139 125
   }
140
-
141
-  //sink3
142
-  def buildPersonSink(): Sink[Person, Future[Person]] = {
143
-    Sink.head
144
-  }
145 126
 }

+ 2
- 2
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamFileProcessing.scala 查看文件

@@ -1,15 +1,15 @@
1 1
 package fr.natan.akkastreamfileprocessingapi.service
2 2
 
3
-import akka.stream.scaladsl.Source
4 3
 import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSeries}
5 4
 
6 5
 import scala.concurrent.Future
7 6
 
7
+//noinspection SpellCheckingInspection
8 8
 trait AkkaStreamFileProcessing {
9 9
   def getAllPersons(): Unit
10 10
 
11 11
   def getPersonById(nconst: String): Future[Person]
12
-  def getPersonByName(primaryName: String): Unit
12
+  def getPersonByName(primaryName: String): Future[IndexedSeq[Person]]
13 13
 
14 14
   def getAllTvSeries(): Unit
15 15
 

+ 50
- 62
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/AkkaStreamFileProcessingImpl.scala 查看文件

@@ -6,24 +6,26 @@ import akka.{Done, NotUsed}
6 6
 import com.typesafe.scalalogging.slf4j.Logger
7 7
 import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.{nameBasics, titleBasics, titlePrincipalsBasics}
8 8
 import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSeries}
9
-import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.{buildPersonModel, buildTvSerieModel}
10
-import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{buildAllPersonsSink, buildAllTvSeriesSink, buildAndValidateSource, buildPersonFlow, buildPersonSink, buildSource, buildTvSerieFlow, buildTvSeriesSink, filterByPersonIdFlow, filterByPersonNameFlow, filterByTvSeriePrimaryTitleFlow}
9
+import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.buildPersonModel
10
+import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{
11
+  buildAllPersonsSink, buildAllTvSeriesSink, buildAndValidateSource, buildPersonFlow,
12
+  buildSource, buildTvSerieFlow, filterByPersonIdFlow, filterByPersonNameFlow, filterByTvSeriePrimaryTitleFlow}
11 13
 import org.slf4j.LoggerFactory
12 14
 import org.springframework.stereotype.Component
13 15
 
14 16
 import scala.concurrent.ExecutionContext.Implicits.global
15
-import scala.concurrent.duration.DurationInt
16
-import scala.concurrent.{Await, Future}
17
+import scala.concurrent.Future
17 18
 import scala.language.postfixOps
18 19
 import scala.util.{Failure, Success}
19 20
 
21
+//noinspection SpellCheckingInspection
20 22
 @Component
21 23
 class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
22 24
 
23 25
   implicit val actorSystem: ActorSystem = ActorSystem("AkkaStreamActor")
24 26
   implicit val logger: Logger = Logger(LoggerFactory.getLogger(this.getClass))
25 27
 
26
-  override def getAllPersons() = {
28
+  override def getAllPersons(): Unit = {
27 29
     val personSource: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
28 30
     //graph
29 31
     val startTime: Long = System.currentTimeMillis()
@@ -35,7 +37,7 @@ class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
35 37
       case Failure(exception) => logger.error(s"$exception")
36 38
       case Success(value) =>
37 39
         logger.info(s"$value")
38
-        val time: Long =(System.currentTimeMillis()-startTime)/100
40
+        val time: Long = (System.currentTimeMillis() - startTime) / 100
39 41
         logger.info(s"elapsed time: $time")
40 42
     }
41 43
   }
@@ -43,30 +45,26 @@ class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
43 45
   override def getPersonById(nconst: String): Future[Person] = {
44 46
     val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
45 47
 
46
-    val startTime: Long = System.currentTimeMillis()
48
+
47 49
     val res = source
48 50
       .via(flow = filterByPersonIdFlow(nconst = nconst))
49
-      .runWith(sink = buildPersonSink())
51
+      .runWith(Sink.head)
50 52
 
51 53
     res.andThen {
52
-      case Failure(exception) => logger.info(s"error!!!!!!!!!!!!!$exception")
54
+      case Failure(exception) => logger.info(s"$exception")
53 55
       case Success(value) => logger.info(s"$value")
54 56
     }
55 57
 
56 58
     res
57 59
   }
58 60
 
59
-  override def getPersonByName(primaryName: String): Unit = {
61
+  override def getPersonByName(primaryName: String): Future[IndexedSeq[Person]] = {
60 62
     val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
61
-    source
62
-      .via(
63
-        flow = filterByPersonNameFlow(personName = primaryName)
64
-      )
65
-      .runWith(sink = buildPersonSink())
66
-      .andThen {
67
-        case Failure(exception) => logger.info(s"$exception")
68
-        case Success(value) => logger.info(s"$value: Successufully processing")
69
-      }
63
+    val persons: Future[IndexedSeq[Person]] = source
64
+      .via(flow = filterByPersonNameFlow(primaryName = primaryName))
65
+      .runWith(Sink.collection)
66
+
67
+    persons
70 68
   }
71 69
 
72 70
   override def getAllTvSeries(): Unit = {
@@ -107,90 +105,80 @@ class AkkaStreamFileProcessingImpl extends AkkaStreamFileProcessing {
107 105
 
108 106
   }
109 107
 
110
-  private def getTvSerieIdByPrimaryTitle(primaryTitle: String): String = {
108
+  private def getTvSerieIdByPrimaryTitle(primaryTitle: String): Future[Option[String]] = {
111 109
     val source: Source[Map[String, String], _] = buildSource(inputFile = titleBasics)
112 110
 
113
-    var tvSerie: TvSeries = null
114 111
     val res: Future[Option[String]] = source
115 112
       .filter((rowMap: Map[String, String]) => {
116 113
         rowMap.getOrElse(key = "primaryTitle", "") == primaryTitle
117 114
       })
118 115
       .map((rowMap: Map[String, String]) => {
119
-        tvSerie = buildTvSerieModel(rowMap)
120 116
         rowMap.get("tconst")
121 117
       })
122 118
       .runWith(Sink.head)
123 119
 
124
-    Await.result(res, 1 minutes)
125
-    val tconst: String = res.value.get.get.get
126
-    logger.info(s"TvSerie ID: $tconst, $tvSerie")
127
-    tconst
120
+    res
121
+
128 122
   }
129 123
 
130
-  private def getListOfPersonsIDByTvSerieID(tconst: String): List[Option[String]]={
124
+  private def getListOfPersonsIDByTvSerieID(tvSerieID: Future[Option[String]]): Future[IndexedSeq[Option[String]]]={
131 125
     val source: Source[Map[String, String], _] = buildSource(inputFile = titlePrincipalsBasics)
132 126
 
133
-    val startTime : Long = System.currentTimeMillis()
134 127
     val res: Future[IndexedSeq[Option[String]]] = source
135 128
       .filter((rowMaps: Map[String, String])=>{
136
-        rowMaps.getOrElse(key = "tconst", default = "")==tconst
129
+        rowMaps.getOrElse(key = "tconst", default = "")==tvSerieID.value.get.get.get
137 130
       })
138 131
       .map((rowMap: Map[String, String])=>{
139 132
         rowMap.get(key = "nconst")
140 133
       })
141 134
       .runWith(Sink.collection)
142
-      .andThen {
143
-        case Success(value) =>
144
-          logger.info(s"$value")
145
-          val elapsedTime : Long = (System.currentTimeMillis() - startTime)/1000
146
-          logger.info(s"success, elapsed time: $elapsedTime")
147
-
148
-        case Failure(error: Error) => logger.error(s"$error")
149
-      }
150
-
151
-    Await.result(res, 3 minutes)
152
-    val listPersonsID: List[Option[String]] = res.value.get.get.toList
153 135
 
154
-    listPersonsID
136
+    res
155 137
 
156 138
   }
157 139
 
158
-  private def getListOfPersonsForTvSerie(nconstList: List[Option[String]]): List[Person] = {
140
+  private def getListOfPersonsForTvSerie(listPersonsIDs: Future[IndexedSeq[Option[String]]]): Future[IndexedSeq[Person]] = {
159 141
     val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
160 142
 
161
-    val startTime: Long = System.currentTimeMillis()
162
-
163 143
     val res : Future[IndexedSeq[Person]]=
164 144
       source
165 145
         .filter((rowMaps: Map[String, String])=>{
166
-          nconstList.contains(rowMaps.get(key = "nconst"))
146
+          listPersonsIDs.value.get.get.contains(rowMaps.get(key = "nconst"))
167 147
         })
168 148
       .map((rowMap: Map[String, String])=>{
169 149
        buildPersonModel(rowMap)
170 150
       })
171 151
       .runWith(Sink.collection)
172
-      .andThen {
173
-        case Failure(exception) => logger.error(s"$exception")
174
-        case Success(value) =>
175
-          val elapsedTime: Long = (System.currentTimeMillis()-startTime)/1000
176
-          logger.info(s"END: Successfully, elapsed time: $elapsedTime")
177
-      }
178
-
179
-    Await.result(res, 4 minutes)
180
-    val listPersons: List[Person] = res.value.get.get.toList
181
-
182
-    listPersons
183 152
 
153
+    res
184 154
   }
185 155
   override def getPersonsTeamForTvSerie(tvSeriePrimaryTitle: String):Unit={
186 156
 
187
-    val tvSerieID: String = getTvSerieIdByPrimaryTitle(primaryTitle = tvSeriePrimaryTitle)
188
-    val listPersonIDs: List[Option[String]] = getListOfPersonsIDByTvSerieID(tconst = tvSerieID)
189
-    val personsTeam: List[Person] = getListOfPersonsForTvSerie(nconstList = listPersonIDs)
157
+    logger.info("STEP 1/3")
158
+    val tvSerieID = getTvSerieIdByPrimaryTitle(primaryTitle = tvSeriePrimaryTitle)
159
+    tvSerieID.onComplete({
160
+      case Failure(exception) => logger.error(s"$exception")
161
+      case Success(value: Option[String]) =>
162
+        logger.info(s"TvSerie ID: $value")
163
+        logger.info("END STEP 1/3")
164
+    })
165
+    logger.info("STEP 2/3")
166
+    val listPersonIDs = getListOfPersonsIDByTvSerieID(tvSerieID = tvSerieID)
167
+    listPersonIDs.onComplete({
168
+      case Failure(exception) => logger.error(s"$exception")
169
+      case Success(value) =>
170
+        value.toList.foreach((personID: Option[String])=>logger.info(s"Person ID:$personID"))
171
+        logger.info("END STEP 2/3")
172
+    })
190 173
 
191
-    logger.info(s"Team size:${personsTeam.size}")
192
-    personsTeam.foreach((person: Person)=>{
193
-      logger.info(s"${person.toString}")
174
+    logger.info("STEP 3/3")
175
+    val personsTeam= getListOfPersonsForTvSerie(listPersonsIDs = listPersonIDs)
176
+    personsTeam.onComplete({
177
+      case Failure(exception) => logger.error(s"$exception")
178
+      case Success(value) =>
179
+        logger.info(s"${value.toList}")
180
+        value.toList.foreach((person:Person)=>logger.info(s"${person.toString}"))
181
+        logger.info("END STEP 3/3")
194 182
     })
195 183
 
196 184
   }

+ 8
- 0
src/main/scala/fr/natan/akkastreamfileprocessingapi/service/CompleteFuture.scala 查看文件

@@ -0,0 +1,8 @@
1
+package fr.natan.akkastreamfileprocessingapi.service
2
+
3
+import org.springframework.stereotype.Component
4
+
5
+@Component
6
+class CompleteFuture {
7
+
8
+}

Powered by TurnKey Linux.