Skip to content

Commit

Permalink
Update zio-http to 3.0.0-RC3 (#165)
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio <Pinheiro>
  • Loading branch information
FabioPinheiro authored and Fabio committed Apr 30, 2024
1 parent 02c939f commit f0b30fc
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 154 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ lazy val V = new {
val zio = "2.0.18"
val zioJson = "0.6.2"
// val zioMunitTest = "0.1.1"
val zioHttp = "3.0.0-RC2"
val zioHttp = "3.0.0-RC3"
val zioConfig = "4.0.0-RC16"
val zioLogging = "2.1.14"
val zioSl4j = "2.1.14"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,12 @@ class MessageDispatcherJVM(client: Client) extends MessageDispatcher {
.pipe(e => Header.ContentType(ZMediaType.application.any.copy(subType = "didcomm-encrypted+json")))
val xForwardedHostHeader = xForwardedHost.map(x => Header.Custom(customName = MyHeaders.xForwardedHost, x))

// xForwardedHost.map(x => Header.(MyHeaders.xForwardedHost, x))
for {
res <- Client
.request(
url = destination,
method = Method.POST,
headers = Headers(Seq(Some(contentTypeHeader), xForwardedHostHeader).flatten),
content = Body.fromCharSequence(msg.toJson),
Request
.post(destination, Body.fromCharSequence(msg.toJson))
.setHeaders(Headers(Seq(Some(contentTypeHeader), xForwardedHostHeader).flatten))
)
.tapError(ex => ZIO.logWarning(s"Fail when calling '$destination': ${ex.toString}"))
.mapError(ex => DispatcherError(ex))
Expand All @@ -51,5 +49,7 @@ class MessageDispatcherJVM(client: Client) extends MessageDispatcher {
case true => ZIO.logWarning(data)
case false => ZIO.logInfo(data)
} yield (data)
}.provideEnvironment(ZEnvironment(client))
}
.provideSomeLayer(Scope.default)
.provideEnvironment(ZEnvironment(client))
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/*
package io.iohk.atala.mediator.utils
import zio.*
Expand Down Expand Up @@ -50,3 +51,4 @@ object MiddlewareUtils {
}
}
*/
57 changes: 32 additions & 25 deletions mediator/src/main/scala/io/iohk/atala/mediator/app/IndexHtml.scala
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
package io.iohk.atala.mediator.app

import zio.http.Response
import zio.http._
import fmgp.did.DID

object IndexHtml {
// TODO use the html.Html.fromDomElement()
def html(identity: DID) = Response.html(s"""<html>
|<head>
| <meta charset="UTF-8">
| <title>IOHK Mediator</title>
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
| <meta name="did" content="${identity.did}">
| <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
| <link href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" rel="stylesheet">
| <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
| <script>
| var callback = function () {
| alert('A callback was triggered');
| }
| </script>
| <!-- My APP -->
| <script type="text/javascript" src="public/webapp-fastopt-bundle.js"></script>
|</head>
|
|<body style="margin:0;">
| <div id="app-container"></div>
|</body>
|
|</html>""".stripMargin)
def html(identity: DID) =
Response(
status = Status.Ok,
headers = Headers(Header.ContentType(MediaType.text.html).untyped),
body = Body.fromString(
s"""<!DOCTYPE html>
|<html>
|<head>
| <meta charset="UTF-8">
| <title>IOHK Mediator</title>
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
| <meta name="did" content="${identity.did}">
| <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
| <link href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" rel="stylesheet">
| <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
| <script>
| var callback = function () {
| alert('A callback was triggered');
| }
| </script>
| <!-- My APP -->
| <script type="text/javascript" src="public/webapp-fastopt-bundle.js"></script>
|</head>
|
|<body style="margin:0;">
| <div id="app-container"></div>
|</body>
|
|</html>""".stripMargin
),
)
}
173 changes: 77 additions & 96 deletions mediator/src/main/scala/io/iohk/atala/mediator/app/MediatorAgent.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import io.iohk.atala.mediator.db.*
import io.iohk.atala.mediator.protocols.*
import io.iohk.atala.mediator.utils.*
import io.netty.handler.codec.http.HttpHeaderNames
import reactivemongo.api.bson.Macros.{*, given}
import reactivemongo.api.bson.{*, given}
import zio.*
import zio.http.*
Expand All @@ -23,7 +22,6 @@ import zio.json.*
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Try
import scala.io.Source
import zio.http.internal.middlewares.Cors.CorsConfig
import zio.http.Header.AccessControlAllowOrigin
import zio.http.Header.AccessControlAllowMethods

Expand Down Expand Up @@ -223,18 +221,20 @@ object MediatorAgent {
def make(id: DID, keyStore: KeyStore): ZIO[Any, Nothing, MediatorAgent] = ZIO.succeed(MediatorAgent(id, keyStore))

def didCommApp = {
Http.collectZIO[Request] {
case req @ Method.GET -> Root / "headers" =>
Routes(
Method.GET / "headers" -> handler { (req: Request) =>
val data = req.headers.toSeq.map(e => (e.headerName, e.renderedValue))
ZIO.succeed(Response.text("HEADERS:\n" + data.mkString("\n") + "\nRemoteAddress:" + req.remoteAddress)).debug
case req @ Method.GET -> Root / "health" => ZIO.succeed(Response.ok)
case Method.GET -> Root / "version" => ZIO.succeed(Response.text(MediatorBuildInfo.version))
case Method.GET -> Root / "did" =>
},
Method.GET / "health" -> handler { (req: Request) => ZIO.succeed(Response.ok) },
Method.GET / "version" -> handler { (req: Request) => ZIO.succeed(Response.text(MediatorBuildInfo.version)) },
Method.GET / "did" -> handler { (req: Request) =>
for {
agent <- ZIO.service[MediatorAgent]
ret <- ZIO.succeed(Response.text(agent.id.string))
} yield (ret)
case Method.GET -> Root / "invitation" =>
},
Method.GET / "invitation" -> handler { (req: Request) =>
for {
agent <- ZIO.service[MediatorAgent]
annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq)
Expand All @@ -247,7 +247,8 @@ object MediatorAgent {
_ <- ZIO.log("New mediate invitation MsgID: " + invitation.id.value)
ret <- ZIO.succeed(Response.json(invitation.toPlaintextMessage.toJson))
} yield (ret)
case Method.GET -> Root / "invitationOOB" =>
},
Method.GET / "invitationOOB" -> handler { (req: Request) =>
for {
agent <- ZIO.service[MediatorAgent]
annotationMap <- ZIO.logAnnotations.map(_.map(e => LogAnnotation(e._1, e._2)).toSeq)
Expand All @@ -263,98 +264,78 @@ object MediatorAgent {
OutOfBandPlaintext.from(invitation.toPlaintextMessage).makeURI("")
)
)

} yield (ret)
case req @ Method.POST -> Root
if req.headers
// .header(Header.ContentType) // TODO BUG? this does not work
.get("content-type")
.exists { h =>
// TODO after fix BUG
// h.mediaType.mainType == "application" &&
// (h.mediaType.subType == "didcomm-signed+json" || h.mediaType.subType == "didcomm-encrypted+json")
// TODO after update lib
// h.mediaType.mainType == ZMediaTypes.mainType &&
// (h.mediaType.subType == MediaTypes.SIGNED.subType || h.mediaType.subType == MediaTypes.ENCRYPTED.subType)
h == MediaTypes.SIGNED.typ || h == MediaTypes.ENCRYPTED.typ
} =>
for {
agent <- ZIO.service[MediatorAgent]
data <- req.body.asString
ret <- agent
.receiveMessage(data)
.map {
case None => Response.ok
case Some(value: SignedMessage) => Response.json(value.toJson)
case Some(value: EncryptedMessage) => Response.json(value.toJson)
}
.catchAll {
case MediatorDidError(error) =>
ZIO.logError(s"Error MediatorDidError: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case MediatorThrowable(error) =>
ZIO.logError(s"Error MediatorThrowable: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case StorageCollection(error) =>
ZIO.logError(s"Error StorageCollection: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case StorageThrowable(error) =>
ZIO.logError(s"Error StorageThrowable: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case DuplicateMessage(error) =>
ZIO.logError(s"Error DuplicateKeyError: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case MissingProtocolError(piuri) =>
ZIO.logError(s"MissingProtocolError ('$piuri')") *>
ZIO.succeed(Response.status(Status.BadRequest)) // TODO
}
} yield ret
// TODO [return_route extension](https://github.com/decentralized-identity/didcomm-messaging/blob/main/extensions/return_route/main.md)
case req @ Method.POST -> Root =>
ZIO
.logError(s"Request Headers: ${req.headers.mkString(",")}")
.as(
Response
.text(s"The content-type must be ${MediaTypes.SIGNED.typ} or ${MediaTypes.ENCRYPTED.typ}")
.copy(status = Status.BadRequest)
)
case req @ Method.GET -> Root => { // html.Html.fromDomElement()
},
Method.POST / trailing -> handler { (req: Request) =>
{
if (
req.headers
.get("content-type")
.exists { h => h == MediaTypes.SIGNED.typ || h == MediaTypes.ENCRYPTED.typ }
) {
for {
agent <- ZIO.service[MediatorAgent]
data <- req.body.asString
.catchAll(ex => ZIO.fail(Response.badRequest("Unable to read the body of the request")))
ret <- agent
.receiveMessage(data)
.map {
case None => Response.ok
case Some(value: SignedMessage) => Response.json(value.toJson)
case Some(value: EncryptedMessage) => Response.json(value.toJson)
}
.catchAll {
case MediatorDidError(error) =>
ZIO.logError(s"Error MediatorDidError: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case MediatorThrowable(error) =>
ZIO.logError(s"Error MediatorThrowable: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case StorageCollection(error) =>
ZIO.logError(s"Error StorageCollection: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case StorageThrowable(error) =>
ZIO.logError(s"Error StorageThrowable: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case DuplicateMessage(error) =>
ZIO.logError(s"Error DuplicateKeyError: $error") *>
ZIO.succeed(Response.status(Status.BadRequest))
case MissingProtocolError(piuri) =>
ZIO.logError(s"MissingProtocolError ('$piuri')") *>
ZIO.succeed(Response.status(Status.BadRequest)) // TODO
}
} yield ret
} else
ZIO
.logError(s"Request Headers: ${req.headers.mkString(",")}")
.as(
Response
.text(s"The content-type must be ${MediaTypes.SIGNED.typ} or ${MediaTypes.ENCRYPTED.typ}")
.copy(status = Status.BadRequest)
)
}
},
Method.GET / trailing -> handler { (req: Request) =>
for {
agent <- ZIO.service[MediatorAgent]
_ <- ZIO.log("index.html")
ret <- ZIO.succeed(IndexHtml.html(agent.id))
} yield ret
}
}: Http[
Operations & Resolver & MessageDispatcher & MediatorAgent & MessageItemRepo & UserAccountRepo & OutboxMessageRepo,
Throwable,
Request,
Response
]
} ++ Http
.fromResource(s"public/webapp-fastopt-bundle.js.gz")
.map(_.setHeaders(Headers(Header.ContentType(MediaType.application.javascript), Header.ContentEncoding.GZip)))
.when {
case Method.GET -> Root / "public" / "webapp-fastopt-bundle.js" => true
case _ => false
}
@@ HttpAppMiddleware.cors(
CorsConfig(
allowedOrigin = {
// case origin @ Origin.Value(_, host, _) if host == "dev" => Some(AccessControlAllowOrigin.Specific(origin))
case _ => Some(AccessControlAllowOrigin.All)
},
allowedMethods = AccessControlAllowMethods(Method.GET, Method.POST, Method.OPTIONS),
)
},
Method.GET / "public" / string("path") -> handler { (path: String, req: Request) =>
// RoutesMiddleware
// TODO https://zio.dev/reference/stream/zpipeline/#:~:text=ZPipeline.gzip%20%E2%80%94%20The%20gzip%20pipeline%20compresses%20a%20stream%20of%20bytes%20as%20using%20gzip%20method%3A
val fullPath = s"public/$path"
val classLoader = Thread.currentThread().getContextClassLoader()
val headerContentType = fullPath match
case s if s.endsWith(".html") => Header.ContentType(MediaType.text.html)
case s if s.endsWith(".js") => Header.ContentType(MediaType.text.javascript)
case s if s.endsWith(".css") => Header.ContentType(MediaType.text.css)
case s if s.endsWith(".svg") => Header.ContentType(MediaType.image.`svg+xml`)
case s => Header.ContentType(MediaType.text.plain)
Handler.fromResource(fullPath).map(_.addHeader(headerContentType))
}.flatten
)
// @@
// HttpAppMiddleware.updateHeaders(headers =>
// Headers(
// headers.map(h =>
// if (h.key == HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN) {
// Header(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*")
// } else h
// )
// )
// )
}.sandbox.toHttpApp

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import zio.config.*
import zio.config.magnolia.*
import zio.config.typesafe.*
import zio.http.*
import zio.http.Http.{Empty, Static}
import zio.http.ZClient.ClientLive
import zio.json.*
import zio.logging.LogFormat.*
import zio.logging.backend.SLF4J
Expand Down Expand Up @@ -57,17 +55,6 @@ object MediatorStandalone extends ZIOAppDefault {
override val bootstrap: ZLayer[ZIOAppArgs, Any, Any] =
Runtime.removeDefaultLoggers >>> SLF4J.slf4j(mediatorColorFormat)

// val app: HttpApp[ // type HttpApp[-R, +Err] = Http[R, Err, Request, Response]
// Hub[String] & Operations & MessageDispatcher & MediatorAgent & Resolver & MessageItemRepo & UserAccountRepo &
// OutboxMessageRepo,
// Throwable
// ]
val app: Http[
Operations & Resolver & UserAccountRepo & OutboxMessageRepo & MessageDispatcher & MediatorAgent & MessageItemRepo,
(HttpAppMiddleware[Nothing, Any, Nothing, Any] | HttpAppMiddleware[Nothing, Any, Nothing, Any])#OutErr[Throwable],
Request,
Response
] = MediatorAgent.didCommApp
override val run = for {
_ <- Console.printLine( // https://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=Mediator
"""███╗ ███╗███████╗██████╗ ██╗ █████╗ ████████╗ ██████╗ ██████╗
Expand Down Expand Up @@ -103,18 +90,7 @@ object MediatorStandalone extends ZIOAppDefault {
client = Scope.default >>> Client.default
inboundHub <- Hub.bounded[String](5)
myServer <- Server
.serve(
(app @@ (MiddlewareUtils.annotateHeaders ++ MiddlewareUtils.serverTime))
.tapUnhandledZIO(ZIO.logError("Unhandled Endpoint"))
.tapErrorCauseZIO(cause => ZIO.logErrorCause(cause)) // THIS is to log all the erros
.mapError(err =>
Response(
status = Status.BadRequest,
headers = Headers.empty,
body = Body.fromString(err.toString()), // Body.fromString(err.getMessage()),
)
)
)
.serve(MediatorAgent.didCommApp @@ (Middleware.cors))
.provideSomeLayer(DidPeerResolver.layerDidPeerResolver)
.provideSomeLayer(mediatorConfig.agentLayer) // .provideSomeLayer(AgentByHost.layer)
.provideSomeLayer(
Expand Down
3 changes: 2 additions & 1 deletion webapp/src/main/scala/io/iohk/atala/mediator/AppUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ object AppUtils {
href := "https://atalaprism.io",
target := "_blank",
img(
src := "https://atalaprism.io/images/atala-prism-logo-suite.svg",
// src := "https://atalaprism.io/images/atala-prism-logo-suite.svg",
src := "public/atala-prism-logo-suite.svg", // Note: this is not the best server for CDN
className := "logo vanilla",
alt := "Prism Mediator"
),
Expand Down

0 comments on commit f0b30fc

Please sign in to comment.