Browse Source

first commit

placidenduwayo 1 year ago
parent
commit
1baaaae3a0

+ 4
- 4
pom.xml View File

66
             <version>2.1.2</version>
66
             <version>2.1.2</version>
67
         </dependency>
67
         </dependency>
68
 
68
 
69
-        <!-- https://mvnrepository.com/artifact/io.spray/spray-json -->
69
+        <!-- https://mvnrepository.com/artifact/com.typesafe.play/play-json -->
70
         <dependency>
70
         <dependency>
71
-            <groupId>io.spray</groupId>
72
-            <artifactId>spray-json_2.12</artifactId>
73
-            <version>1.3.6</version>
71
+            <groupId>com.typesafe.play</groupId>
72
+            <artifactId>play-json_2.12</artifactId>
73
+            <version>2.10.0-RC7</version>
74
         </dependency>
74
         </dependency>
75
 
75
 
76
 
76
 

+ 33
- 17
src/main/java/fr/natan/akkastreamfileprocessingapi/controller/MovieController.java View File

5
 import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamFileProcessing;
5
 import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamFileProcessing;
6
 import org.springframework.http.HttpStatus;
6
 import org.springframework.http.HttpStatus;
7
 import org.springframework.http.ResponseEntity;
7
 import org.springframework.http.ResponseEntity;
8
-import org.springframework.scheduling.annotation.Async;
9
 import org.springframework.web.bind.annotation.PathVariable;
8
 import org.springframework.web.bind.annotation.PathVariable;
10
 import org.springframework.web.bind.annotation.RequestMapping;
9
 import org.springframework.web.bind.annotation.RequestMapping;
11
 import org.springframework.web.bind.annotation.RequestMethod;
10
 import org.springframework.web.bind.annotation.RequestMethod;
12
 import org.springframework.web.bind.annotation.RestController;
11
 import org.springframework.web.bind.annotation.RestController;
12
+import play.api.libs.json.JsValue;
13
+import play.api.libs.json.Json;
13
 import scala.collection.IndexedSeq;
14
 import scala.collection.IndexedSeq;
15
+import scala.collection.immutable.List;
14
 import scala.concurrent.Future;
16
 import scala.concurrent.Future;
15
 
17
 
16
 import java.util.concurrent.CompletableFuture;
18
 import java.util.concurrent.CompletableFuture;
22
 public class MovieController {
24
 public class MovieController {
23
 
25
 
24
     private final AkkaStreamFileProcessing akkaStreamFilesProcessing;
26
     private final AkkaStreamFileProcessing akkaStreamFilesProcessing;
25
-
27
+    private final CompletableFutureResult completableFutureResult;
26
     public MovieController(AkkaStreamFileProcessing akkaStreamFilesProcessing) {
28
     public MovieController(AkkaStreamFileProcessing akkaStreamFilesProcessing) {
27
         this.akkaStreamFilesProcessing = akkaStreamFilesProcessing;
29
         this.akkaStreamFilesProcessing = akkaStreamFilesProcessing;
30
+        completableFutureResult = new CompletableFutureResult();
28
     }
31
     }
29
 
32
 
30
     @RequestMapping(value = "/persons/id/{personID}", method = RequestMethod.GET)
33
     @RequestMapping(value = "/persons/id/{personID}", method = RequestMethod.GET)
31
     private ResponseEntity<String> getPersonByID(@PathVariable(name = "personID") String personID) throws ExecutionException, InterruptedException {
34
     private ResponseEntity<String> getPersonByID(@PathVariable(name = "personID") String personID) throws ExecutionException, InterruptedException {
32
         Future<Models.Person> personFuture = akkaStreamFilesProcessing.getPersonById(personID);
35
         Future<Models.Person> personFuture = akkaStreamFilesProcessing.getPersonById(personID);
33
-        CompletableFuture<Models.Person> completableFutureResult =
34
-                new CompletableFutureResult().buildcompletableFuture(personFuture);
35
-
36
-        return new ResponseEntity<>(completableFutureResult.get().toString(), HttpStatus.OK);
36
+        CompletableFuture<Models.Person> personCompletableFuture = this.completableFutureResult.buildcompletableFuture(personFuture);
37
+        Models.Person person = personCompletableFuture.get();
38
+        JsValue personJs = Json.toJson(person, person.personFormat());
39
+        return new ResponseEntity<>(personJs.toString(), HttpStatus.OK);
37
     }
40
     }
38
 
41
 
39
     @RequestMapping(value = "/persons/name/{primaryName}", method = RequestMethod.GET)
42
     @RequestMapping(value = "/persons/name/{primaryName}", method = RequestMethod.GET)
40
-    private ResponseEntity<IndexedSeq<String>> getPersonByName(@PathVariable(name = "primaryName") String primaryName) throws ExecutionException, InterruptedException {
41
-        Future<IndexedSeq<Models.Person>> personsFuture = akkaStreamFilesProcessing.getPersonByName(primaryName);
42
-        CompletableFuture completableFutureResult =new
43
-                CompletableFutureResult().buildCompletableFuture2(personsFuture);
44
-        IndexedSeq<String> list = (IndexedSeq<String>) completableFutureResult.get();
45
-        return new ResponseEntity<>(list, HttpStatus.OK);
43
+    private ResponseEntity<String> getPersonByName(@PathVariable(name = "primaryName") String primaryName)
44
+            throws ExecutionException, InterruptedException {
45
+
46
+        Future<Models.Person> personFuture = akkaStreamFilesProcessing.getPersonByName(primaryName);
47
+        CompletableFuture completableFutureResult = this.completableFutureResult.buildcompletableFuture(personFuture);
48
+       Models.Person person = (Models.Person) completableFutureResult.get();
49
+       JsValue personJs = Json.toJson(person, person.personFormat());
50
+        return new ResponseEntity<>(personJs.toString(), HttpStatus.OK);
46
     }
51
     }
47
 
52
 
48
-    @RequestMapping(value = "/tvseries/{tvseriePrimaryTitle}", method = RequestMethod.GET)
49
-    private Future<IndexedSeq<Models.TvSeries>> getTvserieByPrimaryTitle(@PathVariable(name = "tvseriePrimaryTitle") String tvseriePrimaryTitle) {
50
-        return akkaStreamFilesProcessing.getTvSerieByPrimaryTitle(tvseriePrimaryTitle);
53
+    @RequestMapping(value = "/tvseries/id/{tvSerieId}", method = RequestMethod.GET)
54
+    private ResponseEntity<String> getTvSerieByID(@PathVariable(name = "tvSerieId") String tvSerieID) throws ExecutionException, InterruptedException {
55
+        Future<Models.TvSerie> tvSerieFuture = akkaStreamFilesProcessing.getTvSerieById(tvSerieID);
56
+        CompletableFuture<Models.TvSerie> tvSerieCompletableFuture = this.completableFutureResult.buildcompletableFuture(tvSerieFuture);
57
+        Models.TvSerie tvSerie = tvSerieCompletableFuture.get();
58
+        JsValue tvSerieJs = Json.toJson(tvSerie, tvSerie.tvSerieFormat());
59
+
60
+        return new ResponseEntity<>(tvSerieJs.toString(), HttpStatus.OK);
61
+    }
62
+
63
+    @RequestMapping(value = "/tvseries/title/{tvseriePrimaryTitle}", method = RequestMethod.GET)
64
+    private ResponseEntity<List<Models.TvSerie>> getTvserieByPrimaryTitle(@PathVariable(name = "tvseriePrimaryTitle") String tvseriePrimaryTitle) {
65
+       List<Models.TvSerie> listFuture = akkaStreamFilesProcessing.getTvSerieByPrimaryTitle(tvseriePrimaryTitle);
66
+
67
+       return new ResponseEntity<>(listFuture, HttpStatus.OK);
51
     }
68
     }
52
 
69
 
53
-    @RequestMapping(value = "/tvseries/title/{tvSerieTitle}", method = RequestMethod.GET)
54
-    @Async
70
+    @RequestMapping(value = "/persons/tvseries/title/{tvSerieTitle}", method = RequestMethod.GET)
55
     private Future<IndexedSeq<Models.Person>> getPersonsForTvSerie(@PathVariable(name = "tvSerieTitle") String tvSerieTitle) {
71
     private Future<IndexedSeq<Models.Person>> getPersonsForTvSerie(@PathVariable(name = "tvSerieTitle") String tvSerieTitle) {
56
         return akkaStreamFilesProcessing.getTeamOfPersonsForTvSerie(tvSerieTitle);
72
         return akkaStreamFilesProcessing.getTeamOfPersonsForTvSerie(tvSerieTitle);
57
     }
73
     }

+ 4
- 13
src/main/java/fr/natan/akkastreamfileprocessingapi/futurecompleteness/CompletableFutureResult.java View File

1
 package fr.natan.akkastreamfileprocessingapi.futurecompleteness;
1
 package fr.natan.akkastreamfileprocessingapi.futurecompleteness;
2
 
2
 
3
-import scala.collection.IndexedSeq;
4
 import scala.concurrent.Future;
3
 import scala.concurrent.Future;
5
 
4
 
5
+import java.util.Random;
6
 import java.util.concurrent.CompletableFuture;
6
 import java.util.concurrent.CompletableFuture;
7
 import java.util.concurrent.Executors;
7
 import java.util.concurrent.Executors;
8
 
8
 
11
 
11
 
12
     public CompletableFuture<T> buildcompletableFuture(Future<T> future){
12
     public CompletableFuture<T> buildcompletableFuture(Future<T> future){
13
         CompletableFuture<T> completableFuture = new CompletableFuture<>();
13
         CompletableFuture<T> completableFuture = new CompletableFuture<>();
14
-        Executors.newCachedThreadPool().submit(()->{
15
-            Thread.sleep(500);
14
+        Executors.newSingleThreadExecutor().submit(()->{
15
+            Thread.sleep(new Random().nextInt(500-200)+200);
16
             return completableFuture.complete(future.value().get().get());
16
             return completableFuture.complete(future.value().get().get());
17
         });
17
         });
18
-        return completableFuture;
19
-    }
20
 
18
 
21
-    public CompletableFuture<IndexedSeq<T>> buildCompletableFuture2(Future<IndexedSeq<T>> futures){
22
-        CompletableFuture<IndexedSeq<T>> completableFuture = new CompletableFuture<>();
23
-        Executors.newCachedThreadPool().submit(
24
-                ()->{
25
-                    Thread.sleep(500);
26
-                    return completableFuture.complete(futures.value().get().get().seq());
27
-                }
28
-        );
29
         return completableFuture;
19
         return completableFuture;
30
     }
20
     }
21
+
31
 }
22
 }

+ 41
- 31
src/main/scala/fr/natan/akkastreamfileprocessingapi/models/Models.scala View File

1
 package fr.natan.akkastreamfileprocessingapi.models
1
 package fr.natan.akkastreamfileprocessingapi.models
2
 
2
 
3
+import play.api.libs.json.{JsValue, Json, Writes}
4
+
3
 object Models {
5
 object Models {
4
 
6
 
5
-  final case class Person(nconst: String, primaryName: String, birthYear: String, deathYear: String,
6
-                          primaryProfession: List[String], knownForTitles: List[String]) {
7
-    override def toString: String = {
8
-      "Person[person-ID:" + nconst +
9
-        ", primary-name:" + primaryName +
10
-        ", birth-year:" + birthYear +
11
-        ", dearth-year:" + deathYear +
12
-        ", primary-profession:" + primaryProfession +
13
-        ", known-for-titles" + knownForTitles +
14
-        "]"
15
-    }
7
+  final case class Person(
8
+                           personID: String,
9
+                           primaryName: String,
10
+                           birthYear: String,
11
+                           deathYear: String,
12
+                           primaryProfession: List[String],
13
+                           knownForTitles: List[String]
14
+                         ) {
16
 
15
 
16
+    implicit val personFormat = new Writes[Person] {
17
+      override def writes(person: Person): JsValue = Json.obj(
18
+        "person id" -> person.personID,
19
+        "primary name" -> person.primaryName,
20
+        "birth year" -> person.birthYear,
21
+        "death year" -> person.deathYear,
22
+        "primary profession" -> person.primaryProfession,
23
+        "known for titles" -> person.knownForTitles
24
+      )
25
+    }
17
   }
26
   }
18
 
27
 
19
-  final case class TvSeries(
20
-                             tconst: String,
21
-                             titleType: String,
22
-                             primaryTitle: String,
23
-                             originalTitle: String,
24
-                             startYear: String,
25
-                             endYear: String,
26
-                             runtimeMinutes: String,
27
-                             genres: String
28
-                           ) {
28
+  final case class TvSerie(
29
+                            tvSerieID: String,
30
+                            titleType: String,
31
+                            primaryTitle: String,
32
+                            originalTitle: String,
33
+                            startYear: String,
34
+                            endYear: String,
35
+                            runtimeMinutes: String,
36
+                            genres: List[String]
37
+                          ) {
29
 
38
 
30
-    override def toString: String = {
31
-      "TvSerie[tvSerieID : " + tconst +
32
-        ", title-type:" + titleType +
33
-        ", primary-title:" + primaryTitle + "" +
34
-        ", riginal-title:" + originalTitle +
35
-        ", start year:" + startYear +
36
-        ", end year:" + endYear +
37
-        ", runtime minutes:" + runtimeMinutes +
38
-        ", genres:" + genres + "]"
39
+    implicit val tvSerieFormat = new Writes[TvSerie] {
40
+      override def writes(tvSerie: TvSerie): JsValue = Json.obj(
41
+        "tv serie id" -> tvSerie.tvSerieID,
42
+        "tv serie type" -> tvSerie.titleType,
43
+        "primary title" -> tvSerie.primaryTitle,
44
+        "original title" -> tvSerie.originalTitle,
45
+        "start year" -> tvSerie.startYear,
46
+        "end year" -> tvSerie.endYear,
47
+        "runtime minutes" -> tvSerie.runtimeMinutes,
48
+        "genres" -> tvSerie.genres
49
+      )
39
     }
50
     }
40
   }
51
   }
41
-
42
 }
52
 }

+ 4
- 4
src/main/scala/fr/natan/akkastreamfileprocessingapi/models/ModelsBuilder.scala View File

1
 package fr.natan.akkastreamfileprocessingapi.models
1
 package fr.natan.akkastreamfileprocessingapi.models
2
-import Models.{Person, TvSeries}
2
+import Models.{Person, TvSerie}
3
 object ModelsBuilder {
3
 object ModelsBuilder {
4
 
4
 
5
   def buildPersonModel(personMap: Map[String, String]): Person = {
5
   def buildPersonModel(personMap: Map[String, String]): Person = {
13
     )
13
     )
14
   }
14
   }
15
 
15
 
16
-  def buildTvSerieModel(tvSerieMap: Map[String, String]): TvSeries = {
17
-    val tvSerie: TvSeries = TvSeries(
16
+  def buildTvSerieModel(tvSerieMap: Map[String, String]): TvSerie = {
17
+    val tvSerie: TvSerie = TvSerie(
18
       tvSerieMap("tconst"),
18
       tvSerieMap("tconst"),
19
       tvSerieMap("titleType"),
19
       tvSerieMap("titleType"),
20
       tvSerieMap("primaryTitle"),
20
       tvSerieMap("primaryTitle"),
22
       tvSerieMap("startYear"),
22
       tvSerieMap("startYear"),
23
       tvSerieMap("endYear"),
23
       tvSerieMap("endYear"),
24
       tvSerieMap("runtimeMinutes"),
24
       tvSerieMap("runtimeMinutes"),
25
-      tvSerieMap("genres")
25
+      tvSerieMap("genres").split(",").toList
26
     )
26
     )
27
     tvSerie
27
     tvSerie
28
   }
28
   }

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

6
 import akka.{Done, NotUsed}
6
 import akka.{Done, NotUsed}
7
 import com.typesafe.scalalogging.slf4j.Logger
7
 import com.typesafe.scalalogging.slf4j.Logger
8
 import fr.natan.akkastreamfileprocessingapi.businessexceptions.FileNotFoundException
8
 import fr.natan.akkastreamfileprocessingapi.businessexceptions.FileNotFoundException
9
-import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSeries}
9
+import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSerie}
10
 import fr.natan.akkastreamfileprocessingapi.valitator.Validators.fileExists
10
 import fr.natan.akkastreamfileprocessingapi.valitator.Validators.fileExists
11
 import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.{buildPersonModel, buildTvSerieModel}
11
 import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.{buildPersonModel, buildTvSerieModel}
12
 
12
 
20
   implicit val actor: ActorSystem = ActorSystem("AkkaStreamActor")
20
   implicit val actor: ActorSystem = ActorSystem("AkkaStreamActor")
21
 
21
 
22
   //flows building
22
   //flows building
23
-
24
   def buildPersonFlow(): Flow[Map[String, String], Person, NotUsed] = {
23
   def buildPersonFlow(): Flow[Map[String, String], Person, NotUsed] = {
25
     val personFlow: Flow[Map[String, String], Person, NotUsed] =
24
     val personFlow: Flow[Map[String, String], Person, NotUsed] =
26
       Flow[Map[String, String]]
25
       Flow[Map[String, String]]
31
     personFlow
30
     personFlow
32
   }
31
   }
33
 
32
 
34
-  def filterByTvSeriePrimaryTitleFlow(tvSeriePrimaryTitle: String): Flow[Map[String, String], TvSeries, NotUsed] = {
35
-    val filterFlow: Flow[Map[String, String], TvSeries, NotUsed] = Flow[Map[String, String]]
36
-        .filter((rows: Map[String, String]) => {
37
-          rows.getOrElse(key = "primaryTitle", default = "")==tvSeriePrimaryTitle
38
-        })
39
-        .map(rowMap => {
40
-          val tvSerie: TvSeries = buildTvSerieModel(tvSerieMap = rowMap)
41
-          tvSerie
42
-        })
43
-
44
-    filterFlow
45
-  }
46
-
47
-  def filterByPersonIdFlow(nconst: String): Flow[Map[String, String], Person, NotUsed]={
48
-    val personFilter: Flow[Map[String, String], Person, NotUsed]=
33
+  def filterPersonByIdFlow(personID: String): Flow[Map[String, String], Person, NotUsed]={
34
+    val personFlowFilter: Flow[Map[String, String], Person, NotUsed]=
49
       Flow[Map[String, String]]
35
       Flow[Map[String, String]]
50
         .filter((rowMap:Map[String, String])=>{
36
         .filter((rowMap:Map[String, String])=>{
51
-          rowMap.getOrElse(key="nconst",default="")==nconst
37
+          rowMap.getOrElse(key="nconst",default="")==personID
52
         })
38
         })
53
         .map(rowMap=>{
39
         .map(rowMap=>{
54
           buildPersonModel(personMap = rowMap)
40
           buildPersonModel(personMap = rowMap)
55
         })
41
         })
56
 
42
 
57
-    personFilter
43
+    personFlowFilter
58
   }
44
   }
59
 
45
 
60
-  def filterByPersonNameFlow(primaryName: String): Flow[Map[String, String], Person, NotUsed] ={
61
-    val personFilter: Flow[Map[String, String], Person, NotUsed] =
46
+  def filterPersonByNameFlow(primaryName: String): Flow[Map[String, String], Person, NotUsed] ={
47
+    val personFlowFilter: Flow[Map[String, String], Person, NotUsed] =
62
       Flow[Map[String, String]]
48
       Flow[Map[String, String]]
63
         .filter((rowMap: Map[String, String]) =>{
49
         .filter((rowMap: Map[String, String]) =>{
64
           rowMap.getOrElse(key = "primaryName", default = "")==primaryName
50
           rowMap.getOrElse(key = "primaryName", default = "")==primaryName
67
           buildPersonModel(personMap = rowMap)
53
           buildPersonModel(personMap = rowMap)
68
         })
54
         })
69
 
55
 
70
-    personFilter
56
+    personFlowFilter
71
   }
57
   }
72
 
58
 
73
-  def buildTvSerieFlow(): Flow[Map[String, String], TvSeries, NotUsed] = {
59
+  def buildTvSerieFlow(): Flow[Map[String, String], TvSerie, NotUsed] = {
74
 
60
 
75
-    val tvFlow: Flow[Map[String, String], TvSeries, NotUsed] =
61
+    val tvSerieFlow: Flow[Map[String, String], TvSerie, NotUsed] =
76
       Flow[Map[String, String]]
62
       Flow[Map[String, String]]
77
         .map((rowMap: Map[String, String]) => {
63
         .map((rowMap: Map[String, String]) => {
78
           buildTvSerieModel(tvSerieMap = rowMap)
64
           buildTvSerieModel(tvSerieMap = rowMap)
79
         })
65
         })
80
-    tvFlow
66
+    tvSerieFlow
81
   }
67
   }
68
+
69
+  def filterTvSerieByIdFlow(tvSerieID: String): Flow[Map[String, String], TvSerie, NotUsed] = {
70
+    val tvSerieFlowFilter : Flow[Map[String, String], TvSerie, NotUsed] =
71
+      Flow[Map[String, String]]
72
+        .filter((rowMap: Map[String, String])=>rowMap.getOrElse(key = "tconst", default = "")==tvSerieID)
73
+        .map((rowMap: Map[String, String])=>{
74
+          buildTvSerieModel(tvSerieMap = rowMap)
75
+        })
76
+
77
+    tvSerieFlowFilter
78
+  }
79
+  def filterTvSerieByPrimaryTitleFlow(tvSeriePrimaryTitle: String): Flow[Map[String, String], TvSerie, NotUsed] = {
80
+    val filterFlowFilter: Flow[Map[String, String], TvSerie, NotUsed] = Flow[Map[String, String]]
81
+      .filter((rows: Map[String, String]) => {
82
+        rows.getOrElse(key = "primaryTitle", default = "") == tvSeriePrimaryTitle
83
+      })
84
+      .map(rowMap => {
85
+        val tvSerie: TvSerie = buildTvSerieModel(tvSerieMap = rowMap)
86
+        tvSerie
87
+      })
88
+
89
+    filterFlowFilter
90
+  }
91
+
82
   //source building
92
   //source building
83
 
93
 
84
   def buildSource(inputFile: File): Source[Map[String, String], NotUsed] = {
94
   def buildSource(inputFile: File): Source[Map[String, String], NotUsed] = {
113
 
123
 
114
   //sinks building
124
   //sinks building
115
 
125
 
116
-  def buildAllTvSeriesSink(logger: Logger): Sink[TvSeries, Future[Done]] = {
117
-    val tvSeriesSink: Sink[TvSeries, Future[Done]] = Sink
118
-      .foreach((tvSerie: TvSeries)=>logger.info(s"${tvSerie.toString}"))
126
+  def buildAllTvSeriesSink(logger: Logger): Sink[TvSerie, Future[Done]] = {
127
+    val tvSeriesSink: Sink[TvSerie, Future[Done]] = Sink
128
+      .foreach((tvSerie: TvSerie)=>logger.info(s"${tvSerie.toString}"))
119
     tvSeriesSink
129
     tvSeriesSink
120
   }
130
   }
121
   def buildAllPersonsSink(logger: Logger): Sink[Person,Future[Done]] = {
131
   def buildAllPersonsSink(logger: Logger): Sink[Person,Future[Done]] = {

+ 4
- 3
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, TvSeries}
3
+import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSerie}
4
 
4
 
5
 import scala.concurrent.Future
5
 import scala.concurrent.Future
6
 
6
 
7
 //noinspection SpellCheckingInspection,AccessorLikeMethodIsUnit
7
 //noinspection SpellCheckingInspection,AccessorLikeMethodIsUnit
8
 trait AkkaStreamFileProcessing {
8
 trait AkkaStreamFileProcessing {
9
   def getPersonById(personID: String): Future[Person]
9
   def getPersonById(personID: String): Future[Person]
10
-  def getPersonByName(primaryName: String): Future[IndexedSeq[Person]]
10
+  def getPersonByName(primaryName: String): Future[Person]
11
 
11
 
12
-  def getTvSerieByPrimaryTitle(tvSerieTitle: String):Future[IndexedSeq[TvSeries]]
12
+  def getTvSerieById(tvSerieID: String): Future[TvSerie]
13
+  def getTvSerieByPrimaryTitle(tvSerieTitle: String):List[TvSerie]
13
 
14
 
14
   def getTeamOfPersonsForTvSerie(tvSeriePrimaryTitle: String): Future[IndexedSeq[Person]]
15
   def getTeamOfPersonsForTvSerie(tvSeriePrimaryTitle: String): Future[IndexedSeq[Person]]
15
   def getAllTvSeries(): Unit
16
   def getAllTvSeries(): Unit

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

1
 package fr.natan.akkastreamfileprocessingapi.service
1
 package fr.natan.akkastreamfileprocessingapi.service
2
 
2
 
3
+import akka.Done
3
 import akka.actor.ActorSystem
4
 import akka.actor.ActorSystem
4
-import akka.stream.scaladsl.{Flow, Sink, Source}
5
-import akka.{Done, NotUsed}
5
+import akka.stream.scaladsl.{Sink, Source}
6
 import com.typesafe.scalalogging.slf4j.Logger
6
 import com.typesafe.scalalogging.slf4j.Logger
7
 import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.{nameBasics, titleBasics, titlePrincipalsBasics}
7
 import fr.natan.akkastreamfileprocessingapi.datasource.Datasource.{nameBasics, titleBasics, titlePrincipalsBasics}
8
-import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSeries}
8
+import fr.natan.akkastreamfileprocessingapi.models.Models.{Person, TvSerie}
9
 import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.buildPersonModel
9
 import fr.natan.akkastreamfileprocessingapi.models.ModelsBuilder.buildPersonModel
10
-import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{
11
-  buildAllPersonsSink, buildAllTvSeriesSink, buildAndValidateSource, buildPersonFlow, buildSource, buildTvSerieFlow,
12
-  filterByPersonIdFlow, filterByPersonNameFlow, filterByTvSeriePrimaryTitleFlow
13
-}
10
+import fr.natan.akkastreamfileprocessingapi.service.AkkaStreamComponents.{buildAllPersonsSink, buildAllTvSeriesSink, buildAndValidateSource, buildPersonFlow, buildSource, buildTvSerieFlow, filterPersonByIdFlow, filterPersonByNameFlow, filterTvSerieByIdFlow, filterTvSerieByPrimaryTitleFlow}
14
 import org.slf4j.LoggerFactory
11
 import org.slf4j.LoggerFactory
15
 import org.springframework.stereotype.Component
12
 import org.springframework.stereotype.Component
16
 
13
 
17
 import scala.concurrent.ExecutionContext.Implicits.global
14
 import scala.concurrent.ExecutionContext.Implicits.global
18
-import scala.concurrent.Future
15
+import scala.concurrent.duration.DurationInt
16
+import scala.concurrent.{Await, Future}
19
 import scala.language.postfixOps
17
 import scala.language.postfixOps
20
 import scala.util.{Failure, Success}
18
 import scala.util.{Failure, Success}
21
 
19
 
29
   override def getPersonById(personID: String): Future[Person] = {
27
   override def getPersonById(personID: String): Future[Person] = {
30
     val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
28
     val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
31
     val res: Future[Person] = source
29
     val res: Future[Person] = source
32
-      .via(flow = filterByPersonIdFlow(nconst = personID))
30
+      .via(flow = filterPersonByIdFlow(personID = personID))
33
       .runWith(Sink.head)
31
       .runWith(Sink.head)
34
 
32
 
35
-    res.andThen {
33
+    res.onComplete({
36
       case Failure(exception) => logger.info(s"$exception")
34
       case Failure(exception) => logger.info(s"$exception")
37
-      case Success(value) => logger.info(s"$value")
38
-    }
35
+      case Success(value:Person) => logger.info(s"$value")
36
+    })
39
 
37
 
40
     res
38
     res
41
   }
39
   }
42
 
40
 
43
-  override def getPersonByName(primaryName: String): Future[IndexedSeq[Person]] = {
41
+  override def getPersonByName(primaryName: String): Future[Person] = {
44
     val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
42
     val source: Source[Map[String, String], _] = buildSource(inputFile = nameBasics)
45
-    val persons: Future[IndexedSeq[Person]] = source
46
-      .via(flow = filterByPersonNameFlow(primaryName = primaryName))
47
-      .runWith(Sink.collection)
43
+    val persons: Future[Person] = source
44
+      .via(flow = filterPersonByNameFlow(primaryName = primaryName))
45
+      .runWith(Sink.head)
48
 
46
 
49
     persons.onComplete({
47
     persons.onComplete({
50
       case Failure(exception) => logger.error(s"$exception")
48
       case Failure(exception) => logger.error(s"$exception")
51
-      case Success(value: IndexedSeq[Person]) =>
52
-        value.foreach((person: Person) => logger.info(s"$person"))
49
+      case Success(value: Person) => logger.info(s"$value")
53
         logger.info("SUCCESS")
50
         logger.info("SUCCESS")
54
     })
51
     })
55
 
52
 
56
     persons
53
     persons
57
   }
54
   }
58
 
55
 
59
-  override def getTvSerieByPrimaryTitle(tvSeriePrimaryTitle: String): Future[IndexedSeq[TvSeries]] = {
56
+  override def getTvSerieById(tvSerieID: String): Future[TvSerie] = {
57
+    val source: Source[Map[String, String], _] = buildSource(inputFile = titleBasics)
58
+    val res: Future[TvSerie] = source
59
+      .via(flow = filterTvSerieByIdFlow(tvSerieID = tvSerieID))
60
+      .runWith(Sink.head)
60
 
61
 
61
-    val tvSeriesSource: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
62
+    res.onComplete({
63
+      case Failure(exception) => logger.info(s"$exception")
64
+      case Success(value: TvSerie) => logger.info(s"$value")
65
+    })
66
+    res
67
+  }
68
+  override def getTvSerieByPrimaryTitle(tvSeriePrimaryTitle: String): List[TvSerie] = {
62
 
69
 
63
-    val filterByTvSerieTitle: Flow[Map[String, String], TvSeries, NotUsed] =
64
-      filterByTvSeriePrimaryTitleFlow(tvSeriePrimaryTitle = tvSeriePrimaryTitle)
70
+    val tvSeriesSource: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
65
 
71
 
66
-    val tvSries: Future[IndexedSeq[TvSeries]] = tvSeriesSource
67
-      .via(flow = filterByTvSerieTitle)
72
+    val tvSries: Future[List[TvSerie]] = tvSeriesSource
73
+      .via(flow = filterTvSerieByPrimaryTitleFlow(tvSeriePrimaryTitle = tvSeriePrimaryTitle))
68
       .runWith(Sink.collection)
74
       .runWith(Sink.collection)
69
 
75
 
70
     tvSries.onComplete({
76
     tvSries.onComplete({
71
       case Failure(exception) => logger.info(s"$exception")
77
       case Failure(exception) => logger.info(s"$exception")
72
-      case Success(value: IndexedSeq[TvSeries]) =>
73
-        value.foreach((tvSrie: TvSeries) => logger.info(s"$tvSrie"))
78
+      case Success(value: List[TvSerie]) =>
79
+        value.foreach((tvSrie: TvSerie) => logger.info(s"$tvSrie"))
74
         logger.info("SUCCESS")
80
         logger.info("SUCCESS")
75
     })
81
     })
76
-
77
-    tvSries
82
+    Await.result(tvSries,2 minutes)
83
+    val tvSriesList : List[TvSerie] = tvSries.value.get.get
84
+    tvSriesList
78
   }
85
   }
79
 
86
 
87
+
80
   private def getTvSerieIdByPrimaryTitle(primaryTitle: String): Future[Option[String]] = {
88
   private def getTvSerieIdByPrimaryTitle(primaryTitle: String): Future[Option[String]] = {
81
     val source: Source[Map[String, String], _] = buildSource(inputFile = titleBasics)
89
     val source: Source[Map[String, String], _] = buildSource(inputFile = titleBasics)
82
 
90
 
178
 
186
 
179
   override def getAllTvSeries(): Unit = {
187
   override def getAllTvSeries(): Unit = {
180
     val source: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
188
     val source: Source[Map[String, String], _] = buildAndValidateSource(inputFile = titleBasics)
181
-    val sink: Sink[TvSeries, Future[Done]] = buildAllTvSeriesSink(logger = logger)
189
+    val sink: Sink[TvSerie, Future[Done]] = buildAllTvSeriesSink(logger = logger)
182
 
190
 
183
     val startingTime: Long = System.currentTimeMillis()
191
     val startingTime: Long = System.currentTimeMillis()
184
     //graph sink->flow->sink
192
     //graph sink->flow->sink
192
         case Failure(error: Error) => logger.error(s"$error")
200
         case Failure(error: Error) => logger.error(s"$error")
193
       }
201
       }
194
   }
202
   }
195
-
196
 }
203
 }
197
 
204
 
198
 
205
 

Powered by TurnKey Linux.