Skip to content

Commit adb5e26

Browse files
committed
add GrpService, update GrpcClient and GrpcServices
1 parent 6c6086b commit adb5e26

File tree

5 files changed

+104
-17
lines changed

5 files changed

+104
-17
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ThisBuild / organization := "app.softnetwork"
88

99
name := "generic-persistence-api"
1010

11-
ThisBuild / version := "0.6.1"
11+
ThisBuild / version := "0.6.2"
1212

1313
ThisBuild / scalaVersion := "2.12.18"
1414

server/src/main/scala/app/softnetwork/api/server/GrpcServer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ trait GrpcServer extends PersistenceGuardian with Server {
4444
}
4545
}
4646
case Failure(ex) =>
47-
classicSystem.log.error("Failed to bind HTTP endpoint, terminating system", ex)
47+
classicSystem.log.error(ex, "Failed to bind HTTP endpoint, terminating system")
4848
classicSystem.terminate()
4949
}
5050
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package app.softnetwork.api.server
2+
3+
import akka.actor.typed.ActorSystem
4+
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
5+
import akka.http.scaladsl.server.Directives
6+
import akka.http.scaladsl.server.Route
7+
8+
import scala.concurrent.Future
9+
10+
trait GrpcService extends Directives {
11+
12+
def grpcService: ActorSystem[_] => PartialFunction[HttpRequest, Future[HttpResponse]]
13+
14+
def route: ActorSystem[_] => Route = system => handle(grpcService(system))
15+
}
Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
package app.softnetwork.api.server
22

33
import akka.actor.typed.ActorSystem
4-
import akka.grpc.scaladsl.ServiceHandler
5-
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
6-
import akka.http.scaladsl.server.Directives.handle
7-
import akka.http.scaladsl.server.Route
4+
import akka.http.scaladsl.server.{Route, RouteConcatenation}
85

9-
import scala.concurrent.Future
6+
trait GrpcServices extends RouteConcatenation {
107

11-
trait GrpcServices {
12-
13-
def grpcServices: ActorSystem[_] => Seq[PartialFunction[HttpRequest, Future[HttpResponse]]] = _ =>
14-
Seq.empty
8+
def grpcServices: ActorSystem[_] => Seq[GrpcService] = _ => Seq.empty
159

1610
final def grpcRoutes: ActorSystem[_] => Route = system =>
17-
handle(
18-
ServiceHandler.concatOrNotFound(
19-
grpcServices(system): _*
20-
)
21-
)
11+
concat(grpcServices(system).map(_.route(system)): _*)
2212

2313
}

server/src/main/scala/app/softnetwork/api/server/client/GrpcClient.scala

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package app.softnetwork.api.server.client
22

33
import akka.actor.typed.ActorSystem
4-
import akka.grpc.scaladsl.AkkaGrpcClient
4+
import akka.grpc.scaladsl.{AkkaGrpcClient, SingleResponseRequestBuilder}
55

6+
import java.net.PasswordAuthentication
67
import scala.concurrent.ExecutionContext
78

89
trait GrpcClient {
@@ -13,4 +14,85 @@ trait GrpcClient {
1314
def name: String
1415

1516
def grpcClient: AkkaGrpcClient
17+
18+
/** add headers to grpc request
19+
* @param request
20+
* - grpc request
21+
* @param headers
22+
* - headers
23+
* @tparam Req
24+
* - Request
25+
* @tparam Res
26+
* - Response
27+
* @return
28+
* request with headers
29+
*/
30+
def withHeaders[Req, Res](
31+
request: SingleResponseRequestBuilder[Req, Res],
32+
headers: Seq[(String, String)]
33+
): SingleResponseRequestBuilder[Req, Res] = {
34+
headers.foldLeft(request) { case (acc, (k, v)) =>
35+
acc.addHeader(k, v)
36+
}
37+
}
38+
39+
/** add authorization header to grpc request
40+
* @param request
41+
* - grpc request
42+
* @param value
43+
* - authorization value
44+
* @tparam Req
45+
* - Request
46+
* @tparam Res
47+
* - Response
48+
* @return
49+
* request with authorization header
50+
*/
51+
def withAuthorization[Req, Res](
52+
request: SingleResponseRequestBuilder[Req, Res],
53+
value: String
54+
): SingleResponseRequestBuilder[Req, Res] = {
55+
withHeaders(request, Seq("Authorization" -> value))
56+
}
57+
58+
/** add oauth2 authorization header to grpc request
59+
* @param request
60+
* - grpc request
61+
* @param token
62+
* - oauth2 token
63+
* @tparam Req
64+
* - Request
65+
* @tparam Res
66+
* - Response
67+
* @return
68+
* request with oauth2 authorization
69+
*/
70+
def oauth2[Req, Res](
71+
request: SingleResponseRequestBuilder[Req, Res],
72+
token: String
73+
): SingleResponseRequestBuilder[Req, Res] = {
74+
withAuthorization(request, s"Bearer $token")
75+
}
76+
77+
/** add basic authorization header to grpc request
78+
* @param request
79+
* - grpc request
80+
* @param credentials
81+
* - basic credentials
82+
* @tparam Req
83+
* - Request
84+
* @tparam Res
85+
* - Response
86+
* @return
87+
* request with basic authorization
88+
*/
89+
def basic[Req, Res](
90+
request: SingleResponseRequestBuilder[Req, Res],
91+
credentials: PasswordAuthentication
92+
): SingleResponseRequestBuilder[Req, Res] = {
93+
val token = java.util.Base64.getEncoder.encodeToString(
94+
s"${credentials.getUserName}:${new String(credentials.getPassword)}".getBytes
95+
)
96+
withAuthorization(request, s"Basic $token")
97+
}
1698
}

0 commit comments

Comments
 (0)