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) update schema logic - agent part. ATL-3164 #452

Merged
merged 6 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
48 changes: 48 additions & 0 deletions prism-agent/service/api/http/prism-agent-openapi-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,54 @@ paths:
"500":
$ref: "./shared/responses.yaml#/components/responses/InternalServerError"

/schema-registry/{author}/{id}:
yshyn-iohk marked this conversation as resolved.
Show resolved Hide resolved
put:
tags:
- Schema Registry
summary: Publish the new version of the credential schema to the schema registry
description:
Publish the new version of the credential schema record with metadata
and internal JSON Schema on behalf of Cloud Agent. The credential schema will
be signed by the keys of Cloud Agent and issued by the DID that corresponds
to it.
operationId: updateSchema
parameters:
- name: author
in: path
description:
DID of the identity which authored the credential schema. A piece
of Metadata.
required: true
schema:
type: string
- name: id
in: path
description:
A locally unique identifier to address the schema. UUID is generated
by the backend.
required: true
schema:
type: string
format: uuid
requestBody:
description: JSON object required for the credential schema update
content:
application/json:
schema:
$ref: "./pollux/schemas.yaml#/components/schemas/CredentialSchemaInput"
required: true
responses:
"200":
description: The credential schema record is successfully updated
content:
application/json:
schema:
$ref: "./pollux/schemas.yaml#/components/schemas/CredentialSchemaResponse"
"400":
$ref: "./shared/responses.yaml#/components/responses/BadRequest"
"500":
$ref: "./shared/responses.yaml#/components/responses/InternalServerError"

/schema-registry/schemas/{guid}:
get:
tags:
Expand Down
2 changes: 1 addition & 1 deletion prism-agent/service/project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object Dependencies {
val akka = "2.6.20"
val akkaHttp = "10.2.9"
val castor = "0.8.1"
val pollux = "0.41.0"
val pollux = "0.42.0"
val connect = "0.12.0"
val bouncyCastle = "1.70"
val logback = "1.4.5"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,24 @@ 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,
CredentialSchemaService,
CredentialSchemaServiceImpl
VerificationPolicyServiceImpl
}
import io.iohk.atala.pollux.credentialschema.controller.{CredentialSchemaController, CredentialSchemaControllerImpl}
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.pollux.sql.repository.{
JdbcCredentialRepository,
JdbcCredentialSchemaRepository,
JdbcPresentationRepository,
JdbcVerificationPolicyRepository,
JdbcCredentialSchemaRepository,
DbConfig as PolluxDbConfig
}
import io.iohk.atala.connect.sql.repository.DbConfig as ConnectDbConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,42 @@ object SchemaRegistryEndpoints {
)
.tag("Schema Registry")

val updateSchemaEndpoint: PublicEndpoint[
(RequestContext, String, UUID, CredentialSchemaInput),
FailureResponse,
CredentialSchemaResponse,
Any
] =
endpoint.put
.in(extractFromRequest[RequestContext](RequestContext.apply))
.in(
"schema-registry" /
path[String]("author").description(CredentialSchemaResponse.annotations.author.description) /
path[UUID]("id").description(CredentialSchemaResponse.annotations.id.description)
)
.in(
jsonBody[CredentialSchemaInput]
.description(
"JSON object required for the credential schema update"
)
)
.out(
statusCode(StatusCode.Ok)
.description(
"The credential schema record is successfully updated"
)
)
.out(jsonBody[CredentialSchemaResponse])
.description("Credential schema record")
.errorOut(basicFailures)
.name("updateSchema")
.summary("Publish the new version of the credential schema to the schema registry")
.description(
"Publish the new version of the credential schema record with metadata and internal JSON Schema on behalf of Cloud Agent. " +
"The credential schema will be signed by the keys of Cloud Agent and issued by the DID that corresponds to it."
)
.tag("Schema Registry")

val getSchemaByIdEndpoint: PublicEndpoint[
(RequestContext, UUID),
FailureResponse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.iohk.atala.api.http.model.{CollectionStats, Order, Pagination, Paginat
import io.iohk.atala.api.http.{FailureResponse, InternalServerError, NotFound, RequestContext}
import io.iohk.atala.pollux.credentialschema.SchemaRegistryEndpoints.{
createSchemaEndpoint,
updateSchemaEndpoint,
getSchemaByIdEndpoint,
lookupSchemasByQueryEndpoint,
testEndpoint
Expand Down Expand Up @@ -35,6 +36,12 @@ class SchemaRegistryServerEndpoints(
credentialSchemaController.createSchema(schemaInput)(ctx)
}

val updateSchemaServerEndpoint: ZServerEndpoint[Any, Any] =
updateSchemaEndpoint.zServerLogic {
case (ctx: RequestContext, author: String, id: UUID, schemaInput: CredentialSchemaInput) =>
credentialSchemaController.updateSchema(author, id, schemaInput)(ctx)
}

val getSchemaByIdServerEndpoint: ZServerEndpoint[Any, Any] =
getSchemaByIdEndpoint.zServerLogic { case (ctx: RequestContext, guid: UUID) =>
credentialSchemaController.getSchemaByGuid(guid)(ctx)
Expand All @@ -61,6 +68,7 @@ class SchemaRegistryServerEndpoints(
val all: List[ZServerEndpoint[Any, Any]] =
List(
createSchemaServerEndpoint,
updateSchemaServerEndpoint,
getSchemaByIdServerEndpoint,
lookupSchemasByQueryServerEndpoint,
testServerEndpoint
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ trait CredentialSchemaController {
def createSchema(in: CredentialSchemaInput)(implicit
rc: RequestContext
): IO[FailureResponse, CredentialSchemaResponse]

def updateSchema(author: String, id: UUID, in: CredentialSchemaInput)(implicit
rc: RequestContext
): IO[FailureResponse, CredentialSchemaResponse]

def getSchemaByGuid(id: UUID)(implicit
rc: RequestContext
): IO[FailureResponse, CredentialSchemaResponse]
Expand All @@ -43,8 +48,13 @@ object CredentialSchemaController {
error match {
case RepositoryError(cause: Throwable) =>
InternalServerError(cause.getMessage)
case NotFoundError(guid: UUID) =>
NotFound(s"CredentialSchema is not found by guid $guid")
case NotFoundError(_, _, message) =>
NotFound(message)
case UpdateError(id, version, author, message) =>
BadRequest(
msg = s"Credential schema update error: id=$id, version=$version",
errors = List(message)
)
case UnexpectedError(msg: String) => InternalServerError(msg)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import io.iohk.atala.pollux.credentialschema.http.CredentialSchemaInput.toDomain
import io.iohk.atala.pollux.credentialschema.http.CredentialSchemaResponse.fromDomain
import io.iohk.atala.pollux.credentialschema.http.{
CredentialSchemaInput,
CredentialSchemaResponsePage,
CredentialSchemaResponse,
CredentialSchemaResponsePage,
FilterInput
}
import zio.{IO, Task, URLayer, ZIO, ZLayer}
Expand All @@ -29,6 +29,14 @@ class CredentialSchemaControllerImpl(service: CredentialSchemaService) extends C
.map(cs => fromDomain(cs).withBaseUri(rc.request.uri))
}

override def updateSchema(author: String, id: UUID, in: CredentialSchemaInput)(implicit
rc: RequestContext
): IO[FailureResponse, CredentialSchemaResponse] = {
service
.update(id, toDomain(in).copy(author = author))
.map(cs => fromDomain(cs).withBaseUri(rc.request.uri))
}

override def getSchemaByGuid(guid: UUID)(implicit
rc: RequestContext
): IO[FailureResponse, CredentialSchemaResponse] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ case class CredentialSchemaInput(
@description(annotations.tags.description)
@encodedExample(annotations.tags.example)
tags: Seq[String],
@description(annotations.author.description)
@encodedExample(annotations.author.example)
@validate(pattern(DIDRefRegex))
author: String
)
object CredentialSchemaInput {
def toDomain(in: CredentialSchemaInput): Input =
Expand All @@ -42,7 +46,7 @@ object CredentialSchemaInput {
description = in.description.getOrElse(""),
`type` = in.`type`,
schema = in.schema,
author = "did:prism:agent",
author = in.author,
authored = None
)
given encoder: JsonEncoder[CredentialSchemaInput] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ object CredentialSchemaBasicSpec extends ZIOSpecDefault with CredentialSchemaTes
.fromJson[zio.json.ast.Json]
.toOption
.get,
tags = List("test")
tags = List("test"),
author = "did:prism:agent"
)

def spec = (
Expand Down Expand Up @@ -94,7 +95,8 @@ object CredentialSchemaBasicSpec extends ZIOSpecDefault with CredentialSchemaTes
description = Option(credentialSchema.description),
`type` = credentialSchema.`type`,
schema = credentialSchema.schema,
tags = credentialSchema.tags
tags = credentialSchema.tags,
author = credentialSchema.author
)

credentialSchemaIsCreated = assert(schemaInput)(equalTo(actualFields))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,22 @@ trait CredentialSchemaGen {
val schemaTags: Gen[Any, List[String]] =
Gen.setOfBounded(0, 3)(schemaTag).map(_.toList)

val schemaAuthor = Gen.alphaNumericStringBounded(64, 64).map(id => s"did:prism:$id")

val schemaInput = for {
name <- schemaName
version <- schemaVersion
description <- schemaDescription
attributes <- schemaAttributes
author <- schemaAuthor
tags <- schemaTags
} yield CredentialSchemaInput(
name = name,
version = version,
description = Some(description),
`type` = "json",
schema = Arr(Obj("first_name" -> Str("String"))),
tags = tags
tags = tags,
author = author
)
}

Expand Down
5 changes: 3 additions & 2 deletions tests/e2e-tests/src/test/kotlin/common/CredentialSchemas.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import java.util.*

object CredentialSchemas {

val CREDENTIAL_SCHEMA_TYPE = "https://w3c-ccg.github.io/vc-json-schemas/schema/2.0/schema.json"

val SCHEMA_TYPE = "https://json-schema.org/draft/2019-09/schema"
Expand All @@ -28,7 +29,7 @@ object CredentialSchemas {

fun generate_with_name_suffix(suffix: String): CredentialSchema {
return CredentialSchema(
author = "University",
author = "did:prism:agent",
name = "${UUID.randomUUID()} $suffix",
description = "Simple student credentials schema",
type = CREDENTIAL_SCHEMA_TYPE,
Expand All @@ -39,7 +40,7 @@ object CredentialSchemas {
}

val STUDENT_SCHEMA = CredentialSchema(
author = "University",
author = "did:prism:agent",
name = UUID.randomUUID().toString(),
description = "Simple student credentials schema",
type = CREDENTIAL_SCHEMA_TYPE,
Expand Down