Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(prism-agent): migrate connect endpoints to Tapir #493

Merged
merged 14 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions infrastructure/shared/apisix/conf/apisix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ routes:
plugins:
proxy-rewrite:
regex_uri: ["^/prism-agent/(.*)", "/$1"]
- uri: /prism-agent/connections*
upstream_id: 4
plugins:
proxy-rewrite:
regex_uri: ["^/prism-agent/connections(/.*)?", "/connections$1"]
- uri: /prism-agent/connection-invitations
upstream_id: 4
plugins:
proxy-rewrite:
regex_uri: ["^/prism-agent/connection-invitations", "/connection-invitations"]
- uri: /didcomm
upstream_id: 3
plugins:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import io.circe.generic.auto.*
import io.circe.parser.*
import io.circe.syntax.*
import io.iohk.atala.agent.server.health.HealthInfo
import io.iohk.atala.connect.controller.ConnectionControllerImpl

import java.security.Security

Expand Down Expand Up @@ -154,7 +155,8 @@ object AgentApp extends ZIOAppDefault {
HttpModule.layers,
RepoModule.credentialSchemaServiceLayer,
AppModule.manageDIDServiceLayer,
RepoModule.verificationPolicyServiceLayer
RepoModule.verificationPolicyServiceLayer,
ConnectionControllerImpl.layer
)
} yield app

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,123 +5,88 @@ import akka.actor.setup.ActorSystemSetup
import akka.actor.typed.ActorSystem
import akka.actor.typed.scaladsl.Behaviors
import akka.http.scaladsl.server.Route
import doobie.util.transactor.Transactor
import io.iohk.atala.agent.server.http.{HttpRoutes, HttpServer, ZHttp4sBlazeServer, ZHttpEndpoints}
import io.iohk.atala.castor.core.service.{DIDService, DIDServiceImpl}
import io.iohk.atala.castor.core.util.DIDOperationValidator
import io.iohk.atala.agent.server.http.marshaller.{
ConnectionsManagementApiMarshallerImpl,
DIDApiMarshallerImpl,
DIDRegistrarApiMarshallerImpl
}
import io.iohk.atala.agent.server.http.service.{ConnectionsManagementApiServiceImpl, DIDApiServiceImpl}
import io.iohk.atala.agent.openapi.api.{ConnectionsManagementApi, DIDApi, DIDRegistrarApi}
import cats.effect.std.Dispatcher
import cats.implicits.*
import com.typesafe.config.ConfigFactory
import doobie.util.transactor.Transactor
import io.circe.{DecodingFailure, ParsingFailure}
import io.grpc.ManagedChannelBuilder
import io.iohk.atala.agent.openapi.api.*
import io.iohk.atala.agent.server.config.AppConfig
import io.iohk.atala.agent.walletapi.service.ManagedDIDService
import io.iohk.atala.agent.walletapi.model.error.DIDSecretStorageError
import io.iohk.atala.agent.server.config.{AgentConfig, AppConfig}
import io.iohk.atala.agent.server.http.marshaller.*
import io.iohk.atala.agent.server.http.service.*
import io.iohk.atala.agent.server.http.{HttpRoutes, HttpServer}
import io.iohk.atala.pollux.core.service.{
CredentialSchemaService,
CredentialSchemaServiceImpl,
CredentialService,
CredentialServiceImpl,
PresentationService,
PresentationServiceImpl,
VerificationPolicyService,
VerificationPolicyServiceImpl
}
import io.iohk.atala.pollux.credentialschema.controller.{CredentialSchemaController, CredentialSchemaControllerImpl}
import io.iohk.atala.agent.server.http.{HttpRoutes, HttpServer, ZHttp4sBlazeServer, ZHttpEndpoints}
import io.iohk.atala.agent.server.jobs.*
import io.iohk.atala.agent.server.sql.DbConfig as AgentDbConfig
import io.iohk.atala.agent.walletapi.model.error.DIDSecretStorageError
import io.iohk.atala.agent.walletapi.service.ManagedDIDService
import io.iohk.atala.agent.walletapi.sql.{JdbcDIDNonSecretStorage, JdbcDIDSecretStorage}
import io.iohk.atala.castor.core.service.{DIDService, DIDServiceImpl}
import io.iohk.atala.castor.core.util.DIDOperationValidator
import io.iohk.atala.connect.controller.{ConnectionController, ConnectionControllerImpl, ConnectionServerEndpoints}
import io.iohk.atala.connect.core.model.error.ConnectionServiceError
import io.iohk.atala.connect.core.repository.ConnectionRepository
import io.iohk.atala.connect.core.service.{ConnectionService, ConnectionServiceImpl}
import io.iohk.atala.connect.sql.repository.{JdbcConnectionRepository, DbConfig as ConnectDbConfig}
import io.iohk.atala.iris.proto.service.IrisServiceGrpc
import io.iohk.atala.iris.proto.service.IrisServiceGrpc.IrisServiceStub
import io.iohk.atala.pollux.core.repository.CredentialRepository
import io.iohk.atala.mercury.*
import io.iohk.atala.mercury.DidOps.*
import io.iohk.atala.mercury.model.*
import io.iohk.atala.mercury.model.error.*
import io.iohk.atala.mercury.protocol.connection.{ConnectionRequest, ConnectionResponse}
import io.iohk.atala.mercury.protocol.issuecredential.*
import io.iohk.atala.mercury.protocol.presentproof.*
import io.iohk.atala.pollux.core.model.error.CredentialServiceError.RepositoryError
import io.iohk.atala.pollux.core.model.error.{CredentialServiceError, PresentationError}
import io.iohk.atala.pollux.core.repository.{CredentialRepository, PresentationRepository}
import io.iohk.atala.pollux.core.service.*
import io.iohk.atala.pollux.credentialschema.controller.*
import io.iohk.atala.pollux.credentialschema.{SchemaRegistryServerEndpoints, VerificationPolicyServerEndpoints}
import io.iohk.atala.pollux.sql.repository.{
JdbcCredentialRepository,
JdbcCredentialSchemaRepository,
JdbcPresentationRepository,
JdbcVerificationPolicyRepository,
DbConfig as PolluxDbConfig
}
import io.iohk.atala.connect.sql.repository.DbConfig as ConnectDbConfig
import io.iohk.atala.agent.server.sql.DbConfig as AgentDbConfig
import io.iohk.atala.agent.server.jobs.*
import io.iohk.atala.pollux.vc.jwt.{PrismDidResolver, DidResolver as JwtDidResolver}
import io.iohk.atala.prism.protos.node_api.NodeServiceGrpc
import io.iohk.atala.resolvers.{DIDResolver, UniversalDidResolver}
import org.didcommx.didcomm.DIDComm
import org.didcommx.didcomm.model.UnpackParams
import org.didcommx.didcomm.secret.{Secret, SecretResolver}
import zhttp.http.*
import zhttp.service.Server
import zio.*
import zio.config.typesafe.TypesafeConfigSource
import zio.config.{ReadError, read}
import zio.interop.catz.*
import zio.stream.ZStream
import zhttp.http.*
import zhttp.service.Server

import java.util.concurrent.Executors
import io.iohk.atala.mercury.*
import io.iohk.atala.mercury.DidOps.*
import io.iohk.atala.mercury.model.*
import io.iohk.atala.mercury.model.error.*
import io.iohk.atala.mercury.protocol.issuecredential.*
import io.iohk.atala.pollux.core.model.error.CredentialServiceError.RepositoryError
import io.iohk.atala.prism.protos.node_api.NodeServiceGrpc

import java.io.IOException
import cats.implicits.*
import io.iohk.atala.pollux.credentialschema.SchemaRegistryServerEndpoints
import io.iohk.atala.pollux.core.repository.PresentationRepository
import io.iohk.atala.pollux.core.model.error.PresentationError
import io.iohk.atala.pollux.core.model.error.CredentialServiceError
import io.iohk.atala.connect.core.service.ConnectionService
import io.iohk.atala.connect.core.service.ConnectionServiceImpl
import io.iohk.atala.connect.core.repository.ConnectionRepository
import io.iohk.atala.connect.sql.repository.JdbcConnectionRepository
import io.iohk.atala.mercury.protocol.connection.ConnectionRequest
import io.iohk.atala.mercury.protocol.connection.ConnectionResponse
import io.iohk.atala.connect.core.model.error.ConnectionServiceError
import io.iohk.atala.pollux.credentialschema.{SchemaRegistryServerEndpoints, VerificationPolicyServerEndpoints}
import io.iohk.atala.connect.core.model.error.ConnectionServiceError
import io.iohk.atala.mercury.protocol.presentproof.*
import io.iohk.atala.agent.server.config.AgentConfig
import org.didcommx.didcomm.DIDComm
import io.iohk.atala.resolvers.UniversalDidResolver
import org.didcommx.didcomm.secret.SecretResolver
import org.didcommx.didcomm.model.UnpackParams
import org.didcommx.didcomm.secret.Secret
import io.circe.ParsingFailure
import io.circe.DecodingFailure
import io.iohk.atala.agent.walletapi.sql.{JdbcDIDNonSecretStorage, JdbcDIDSecretStorage}
import io.iohk.atala.resolvers.DIDResolver
import io.iohk.atala.pollux.vc.jwt.DidResolver as JwtDidResolver
import io.iohk.atala.pollux.vc.jwt.PrismDidResolver
import io.iohk.atala.mercury.DidAgent
import io.iohk.atala.pollux.credentialschema.controller.{
CredentialSchemaController,
VerificationPolicyController,
VerificationPolicyControllerImpl,
VerificationPolicyControllerInMemory
}
import java.util.concurrent.Executors

object Modules {

def app(port: Int): RIO[
DidOps & DidAgent & ManagedDIDService & AppConfig & DIDRegistrarApi & IssueCredentialsProtocolApi &
ConnectionsManagementApi & DIDApi & PresentProofApi & ActorSystem[Nothing],
DidOps & DidAgent & ManagedDIDService & AppConfig & DIDRegistrarApi & IssueCredentialsProtocolApi & DIDApi &
PresentProofApi & ActorSystem[Nothing],
Unit
] = {
val httpServerApp = HttpRoutes.routes.flatMap(HttpServer.start(port, _))

httpServerApp.unit
}

lazy val zioApp: RIO[CredentialSchemaController & VerificationPolicyController & AppConfig, Unit] = {
lazy val zioApp
: RIO[CredentialSchemaController & VerificationPolicyController & ConnectionController & AppConfig, Unit] = {
val zioHttpServerApp = for {
allSchemaRegistryEndpoints <- SchemaRegistryServerEndpoints.all
allVerificationPolicyEndpoints <- VerificationPolicyServerEndpoints.all
allConnectionEndpoints <- ConnectionServerEndpoints.all
allEndpoints = ZHttpEndpoints.withDocumentations[Task](
allSchemaRegistryEndpoints ++ allVerificationPolicyEndpoints
allSchemaRegistryEndpoints ++ allVerificationPolicyEndpoints ++ allConnectionEndpoints
)
appConfig <- ZIO.service[AppConfig]
httpServer <- ZHttp4sBlazeServer.start(allEndpoints, port = appConfig.agent.httpEndpoint.http.port)
Expand Down Expand Up @@ -205,7 +170,8 @@ object Modules {
.unit

private[this] def extractFirstRecipientDid(jsonMessage: String): IO[ParsingFailure | DecodingFailure, String] = {
import io.circe._, io.circe.parser._
import io.circe.*
import io.circe.parser.*
val doc = parse(jsonMessage).getOrElse(Json.Null)
val cursor = doc.hcursor
ZIO.fromEither(
Expand Down Expand Up @@ -525,17 +491,9 @@ object HttpModule {
(apiServiceLayer ++ apiMarshallerLayer) >>> ZLayer.fromFunction(new PresentProofApi(_, _))
}

val connectionsManagementApiLayer
: RLayer[DidOps & DidAgent & ManagedDIDService & AppConfig, ConnectionsManagementApi] = {
val serviceLayer = AppModule.connectionServiceLayer
val apiServiceLayer = serviceLayer >>> ConnectionsManagementApiServiceImpl.layer
val apiMarshallerLayer = ConnectionsManagementApiMarshallerImpl.layer
(apiServiceLayer ++ apiMarshallerLayer) >>> ZLayer.fromFunction(new ConnectionsManagementApi(_, _))
}

val layers =
didApiLayer ++ didRegistrarApiLayer ++
issueCredentialsProtocolApiLayer ++ connectionsManagementApiLayer ++ presentProofProtocolApiLayer
issueCredentialsProtocolApiLayer ++ presentProofProtocolApiLayer
}

object RepoModule {
Expand Down Expand Up @@ -638,4 +596,5 @@ object RepoModule {
JdbcVerificationPolicyRepository.layer >+>
VerificationPolicyServiceImpl.layer >+>
VerificationPolicyControllerImpl.layer

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,24 @@ package io.iohk.atala.agent.server.http

import akka.http.scaladsl.model.ContentType
import akka.http.scaladsl.server.Directives.*
import io.iohk.atala.agent.openapi.api.{
PresentProofApi,
DIDApi,
DIDRegistrarApi,
IssueCredentialsProtocolApi,
ConnectionsManagementApi
}
import zio.*
import akka.http.scaladsl.server.Route
import io.iohk.atala.agent.openapi.api.{DIDApi, DIDRegistrarApi, IssueCredentialsProtocolApi, PresentProofApi}
import zio.*

object HttpRoutes {

def routes: URIO[
DIDApi & DIDRegistrarApi & IssueCredentialsProtocolApi & ConnectionsManagementApi & PresentProofApi,
DIDApi & DIDRegistrarApi & IssueCredentialsProtocolApi & PresentProofApi,
Route
] =
for {
didApi <- ZIO.service[DIDApi]
disRegistrarApi <- ZIO.service[DIDRegistrarApi]
issueCredentialsProtocolApi <- ZIO.service[IssueCredentialsProtocolApi]
connectionsManagementApi <- ZIO.service[ConnectionsManagementApi]
presentProofApi <- ZIO.service[PresentProofApi]
} yield didApi.route ~
disRegistrarApi.route ~
issueCredentialsProtocolApi.route ~
connectionsManagementApi.route ~
presentProofApi.route ~
additionalRoute

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.iohk.atala.agent.server.http.marshaller

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import io.iohk.atala.agent.openapi.model.*
import io.iohk.atala.agent.server.http.model.OASModelPatches
import spray.json.{
DefaultJsonProtocol,
DeserializationException,
Expand All @@ -13,9 +14,8 @@ import spray.json.{
jsonWriter
}

import java.util.UUID
import java.time.OffsetDateTime
import io.iohk.atala.agent.server.http.model.OASModelPatches
import java.util.UUID

object JsonSupport extends JsonSupport

Expand Down Expand Up @@ -84,13 +84,6 @@ trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
given RootJsonFormat[RequestPresentationAction] = jsonFormat2(RequestPresentationAction.apply)
given RootJsonFormat[PresentationStatusPage] = jsonFormat6(PresentationStatusPage.apply)

// Connections Management
given RootJsonFormat[CreateConnectionRequest] = jsonFormat1(CreateConnectionRequest.apply)
given RootJsonFormat[AcceptConnectionInvitationRequest] = jsonFormat1(AcceptConnectionInvitationRequest.apply)
given RootJsonFormat[ConnectionsPage] = jsonFormat6(ConnectionsPage.apply)
given RootJsonFormat[Connection] = jsonFormat11(Connection.apply)
given RootJsonFormat[ConnectionInvitation] = jsonFormat4(ConnectionInvitation.apply)

// Manual model patches
given RootJsonFormat[OASModelPatches.DIDDocument] = jsonFormat10(OASModelPatches.DIDDocument.apply)
given RootJsonFormat[OASModelPatches.DIDResolutionResult] = jsonFormat4(OASModelPatches.DIDResolutionResult.apply)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import io.iohk.atala.agent.openapi.model.*
import io.iohk.atala.castor.core.model.did as castorDomain
import io.iohk.atala.agent.walletapi.model as walletDomain
import io.iohk.atala.pollux.core.model as polluxdomain
import io.iohk.atala.connect.core.model as connectdomain
import io.iohk.atala.shared.models.HexStrings.*
import io.iohk.atala.shared.models.Base64UrlStrings.*
import io.iohk.atala.shared.utils.Traverse.*
Expand All @@ -22,7 +21,6 @@ import io.iohk.atala.castor.core.model.did.w3c.PublicKeyRepr
import io.iohk.atala.castor.core.model.did.{LongFormPrismDID, PrismDID, ServiceType}

import java.util.UUID
import io.iohk.atala.connect.core.model.ConnectionRecord.Role
import io.iohk.atala.castor.core.util.UriUtils

trait OASDomainModelHelper {
Expand Down Expand Up @@ -156,37 +154,6 @@ trait OASDomainModelHelper {
})
)
}
extension (domain: connectdomain.ConnectionRecord) {
def toOAS: Connection = Connection(
label = domain.label,
self = "Connection",
kind = s"/connections/${domain.id.toString}",
connectionId = domain.id,
myDid = domain.role match
case Role.Inviter =>
domain.connectionResponse.map(_.from).orElse(domain.connectionRequest.map(_.to)).map(_.value)
case Role.Invitee =>
domain.connectionResponse.map(_.to).orElse(domain.connectionRequest.map(_.from)).map(_.value)
,
theirDid = domain.role match
case Role.Inviter =>
domain.connectionResponse.map(_.to).orElse(domain.connectionRequest.map(_.from)).map(_.value)
case Role.Invitee =>
domain.connectionResponse.map(_.from).orElse(domain.connectionRequest.map(_.to)).map(_.value)
,
state = domain.protocolState.toString,
createdAt = domain.createdAt.atOffset(ZoneOffset.UTC),
updatedAt = domain.updatedAt.map(_.atOffset(ZoneOffset.UTC)),
role = domain.role.toString,
invitation = ConnectionInvitation(
id = UUID.fromString(domain.invitation.id),
`type` = domain.invitation.`type`,
from = domain.invitation.from.value,
invitationUrl = s"https://domain.com/path?_oob=${domain.invitation.toBase64}"
)
)
}

extension (domain: polluxdomain.PresentationRecord) {
def toOAS: PresentationStatus = {
val connectionId = domain.connectionId
Expand Down
Loading