-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(pollux): CredentialSchema service, repository and sql (#416)
- Loading branch information
1 parent
90a5d00
commit ffa5f7e
Showing
14 changed files
with
715 additions
and
4 deletions.
There are no files selected for viewing
102 changes: 102 additions & 0 deletions
102
pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/model/CredentialSchema.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package io.iohk.atala.pollux.core.model | ||
|
||
import java.time.{OffsetDateTime, ZoneOffset} | ||
import java.util.UUID | ||
import io.circe.Json | ||
import zio.* | ||
|
||
//TODO: test CredentialSchema DAL | ||
//TODO: define the business logic: | ||
// 1. create new schema | ||
// 2. update the existing schema | ||
// 3. delete the existing schema | ||
// 4. business rules for breaking changes and versioning | ||
// | ||
//TODO: implement a new CredentialSchema endpoint | ||
|
||
type Schema = zio.json.ast.Json | ||
|
||
/** @param guid | ||
* Globally unique identifier of the CredentialSchema object It's calculated as a UUID from string that contains the | ||
* following fields: author, id and version | ||
* @param id | ||
* Locally unique identifier of the CredentialSchema. It is UUID When the version of the credential schema changes | ||
* this `id` keeps the same value | ||
* @param name | ||
* Human readable name of the CredentialSchema | ||
* @param version | ||
* Version of the CredentialSchema | ||
* @param author | ||
* DID of the CredentialSchema's author | ||
* @param authored | ||
* Datetime stamp of the schema creation | ||
* @param tags | ||
* Tags of the CredentialSchema used for convenient lookup | ||
* @param description | ||
* Human readable description of the schema | ||
* @param schema | ||
* Internal schema object that depends on concrete implementation For W3C JsonSchema it is a JsonSchema object For | ||
* AnonCreds schema is a AnonCreds schema | ||
*/ | ||
case class CredentialSchema( | ||
guid: UUID, | ||
id: UUID, | ||
name: String, | ||
version: String, | ||
author: String, | ||
authored: OffsetDateTime, | ||
tags: Seq[String], | ||
description: String, | ||
schemaType: String, | ||
schema: Schema | ||
) { | ||
def longId = CredentialSchema.makeLongId(author, id, version) | ||
} | ||
|
||
object CredentialSchema { | ||
|
||
def makeLongId(author: String, id: UUID, version: String) = | ||
s"$author/${id.toString}?version=${version}" | ||
def makeGUID(author: String, id: UUID, version: String) = | ||
UUID.fromString(makeLongId(author, id, version)) | ||
def make(in: Input) = { | ||
for { | ||
id <- zio.Random.nextUUID | ||
ts <- zio.Clock.currentDateTime.map( | ||
_.atZoneSameInstant(ZoneOffset.UTC).toOffsetDateTime | ||
) | ||
guid = makeGUID(in.author, id, in.version) | ||
} yield CredentialSchema( | ||
guid = guid, | ||
id = id, | ||
name = in.name, | ||
version = in.version, | ||
author = in.author, | ||
authored = ts, | ||
tags = in.tags, | ||
description = in.description, | ||
schemaType = in.schemaType, | ||
schema = in.schema | ||
) | ||
} | ||
|
||
val defaultAgentDid = "did:prism:agent" | ||
|
||
case class Input( | ||
name: String, | ||
version: String, | ||
description: String, | ||
authored: Option[OffsetDateTime], | ||
tags: Seq[String], | ||
author: String = defaultAgentDid, | ||
schemaType: String, | ||
schema: Schema | ||
) | ||
|
||
case class Filter( | ||
author: Option[String] = None, | ||
name: Option[String] = None, | ||
version: Option[String] = None, | ||
tags: Option[String] = None | ||
) | ||
} |
20 changes: 20 additions & 0 deletions
20
...core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialSchemaRepository.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package io.iohk.atala.pollux.core.repository | ||
|
||
import io.iohk.atala.pollux.core.model.CredentialSchema | ||
import io.iohk.atala.pollux.core.model.CredentialSchema.* | ||
import io.iohk.atala.pollux.core.repository.Repository.SearchCapability | ||
import java.util.UUID | ||
|
||
trait CredentialSchemaRepository[F[_]] | ||
extends Repository[F, CredentialSchema] | ||
with SearchCapability[F, CredentialSchema.Filter, CredentialSchema] { | ||
def create(cs: CredentialSchema): F[CredentialSchema] | ||
|
||
def getByGuid(guid: UUID): F[Option[CredentialSchema]] | ||
|
||
def update(cs: CredentialSchema): F[Option[CredentialSchema]] | ||
|
||
def delete(guid: UUID): F[Option[CredentialSchema]] | ||
|
||
def deleteAll(): F[Long] | ||
} |
16 changes: 16 additions & 0 deletions
16
pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/repository.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package io.iohk.atala.pollux.core.repository | ||
|
||
import io.iohk.atala.pollux.core.repository.Repository.{SearchQuery, SearchResult} | ||
|
||
trait Repository[F[_], T] | ||
|
||
object Repository { | ||
case class SearchQuery[Filter](filter: Filter, skip: Int, limit: Int) | ||
|
||
case class SearchResult[T](entries: Seq[T], count: Long, totalCount: Long) | ||
|
||
trait SearchCapability[F[_], Filter, T] { | ||
self: Repository[F, T] => | ||
def search(query: SearchQuery[Filter]): F[SearchResult[T]] | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
...x/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialSchemaService.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package io.iohk.atala.pollux.core.service | ||
|
||
import zio.{Task, ZIO, ZLayer, IO} | ||
import io.iohk.atala.pollux.core.model.CredentialSchema | ||
import io.iohk.atala.pollux.core.model.CredentialSchema.* | ||
|
||
import java.util.UUID | ||
trait CredentialSchemaService { | ||
type Result[T] = IO[CredentialSchemaService.Error, T] | ||
|
||
/** @param in | ||
* CredentialSchema form for creating the instance | ||
* @return | ||
* Created instance of the Credential Schema | ||
*/ | ||
def create(in: CredentialSchema.Input): Result[CredentialSchema] | ||
|
||
/** @param guid | ||
* Globally unique UUID of the credential schema | ||
* @return | ||
* The instance of the credential schema or credential service error | ||
*/ | ||
def getByGUID(guid: UUID): Result[CredentialSchema] | ||
|
||
def update(in: CredentialSchema.Input): Result[CredentialSchema] | ||
|
||
def delete(id: UUID): Result[CredentialSchema] | ||
} | ||
|
||
object CredentialSchemaService { | ||
sealed trait Error | ||
|
||
object Error { | ||
def apply(throwable: Throwable): Error = RepositoryError(throwable) | ||
|
||
final case class RepositoryError(cause: Throwable) extends Error | ||
|
||
final case class NotFoundError(guid: UUID) extends Error | ||
|
||
final case class UnexpectedError(msg: String) extends Error | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
...b/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialSchemaServiceImpl.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package io.iohk.atala.pollux.core.service | ||
import io.iohk.atala.pollux.core.model.CredentialSchema | ||
import io.iohk.atala.pollux.core.repository.CredentialSchemaRepository | ||
import zio.Task | ||
import zio.ZIO.getOrFailWith | ||
import CredentialSchemaService.Error.* | ||
|
||
import java.util.UUID | ||
|
||
class CredentialSchemaServiceImpl( | ||
credentialSchemaRepository: CredentialSchemaRepository[Task] | ||
) extends CredentialSchemaService { | ||
override def create(in: CredentialSchema.Input): Result[CredentialSchema] = { | ||
for { | ||
credentialSchema <- CredentialSchema.make(in) | ||
createdCredentialSchema <- credentialSchemaRepository | ||
.create(credentialSchema) | ||
.mapError(t => RepositoryError(t)) | ||
} yield createdCredentialSchema | ||
} | ||
|
||
override def getByGUID(guid: UUID): Result[CredentialSchema] = { | ||
credentialSchemaRepository | ||
.getByGuid(guid) | ||
.mapError[CredentialSchemaService.Error](t => RepositoryError(t)) | ||
.flatMap( | ||
getOrFailWith(NotFoundError(guid))(_) | ||
) | ||
} | ||
|
||
def getBy( | ||
author: String, | ||
id: UUID, | ||
version: String | ||
): Result[CredentialSchema] = { | ||
getByGUID(CredentialSchema.makeGUID(author, id, version)) | ||
} | ||
|
||
// TODO: Implement a business logic for a real schema update | ||
override def update(in: CredentialSchema.Input): Result[CredentialSchema] = { | ||
for { | ||
cs <- CredentialSchema.make(in) | ||
updated_opt <- credentialSchemaRepository | ||
.update(cs) | ||
.mapError(RepositoryError.apply) | ||
updated <- getOrFailWith(NotFoundError(cs.guid))(updated_opt) | ||
} yield updated | ||
} | ||
|
||
override def delete(guid: UUID): Result[CredentialSchema] = { | ||
for { | ||
deleted_row_opt <- credentialSchemaRepository | ||
.delete(guid) | ||
.mapError(RepositoryError.apply) | ||
deleted_row <- getOrFailWith(NotFoundError(guid))(deleted_row_opt) | ||
} yield deleted_row | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
pollux/lib/sql-doobie/src/main/resources/sql/pollux/V8__credential_schema_tables.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
CREATE TABLE public.credential_schema | ||
( | ||
guid UUID PRIMARY KEY default gen_random_uuid(), | ||
id UUID NOT NULL, | ||
schema_type varchar(63) NOT NULL, | ||
name VARCHAR(128) NOT NULL, | ||
version VARCHAR(64) NOT NULL, | ||
tags VARCHAR(64) ARRAY NULL, | ||
description TEXT NULL, | ||
schema json NOT NULL, | ||
author VARCHAR(255) NOT NULL, | ||
authored TIMESTAMP WITH TIME ZONE NOT NULL, | ||
proof_id UUID NULL, | ||
UNIQUE (name, version, author) | ||
); | ||
|
||
CREATE INDEX credential_schema_name_index ON public.credential_schema (name); | ||
CREATE INDEX credential_schema_schema_type_index ON public.credential_schema (schema_type); | ||
CREATE INDEX credential_schema_version_index ON public.credential_schema (version); | ||
CREATE INDEX credential_schema_tags_index ON public.credential_schema (tags); | ||
CREATE INDEX credential_schema_author_index ON public.credential_schema (author); | ||
CREATE INDEX credential_schema_authored_index ON public.credential_schema (authored); | ||
|
||
|
||
|
Oops, something went wrong.