Skip to content

Commit

Permalink
feat(pollux): add dal for the credential schema ATL-1342 (#298)
Browse files Browse the repository at this point in the history
* feat(pollux): add schema-registry DAL

* chore(pollux): fix migration

* chore(pollux): fix formatting
  • Loading branch information
yshyn-iohk committed Jan 13, 2023
1 parent e990a92 commit f43320f
Show file tree
Hide file tree
Showing 10 changed files with 744 additions and 3 deletions.
1 change: 1 addition & 0 deletions pollux/lib/build.sbt
Expand Up @@ -16,6 +16,7 @@ inThisBuild(
)

val commonSettings = Seq(
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework")),
githubTokenSource := TokenSource.Environment("ATALA_GITHUB_TOKEN"),
resolvers += Resolver.githubPackages("input-output-hk"),
// Needed for Kotlin coroutines that support new memory management mode
Expand Down
37 changes: 34 additions & 3 deletions pollux/lib/project/Dependencies.scala
Expand Up @@ -10,16 +10,29 @@ object Dependencies {
val shared = "0.2.0"
val mercury = "0.15.0"
val flyway = "9.8.3"
val testContainersScalaPostgresql = "0.40.11"
val quill = "4.6.0"
val logback = "1.4.5"
}

private lazy val logback = "ch.qos.logback" % "logback-classic" % Versions.logback % Test
private lazy val slf4jApi = "org.slf4j" % "slf4j-api" % "2.0.6" % Test
private lazy val slf4jSimple = "org.slf4j" % "slf4j-simple" % "2.0.6" % Test

private lazy val zio = "dev.zio" %% "zio" % Versions.zio
private lazy val zioCatsInterop = "dev.zio" %% "zio-interop-cats" % Versions.zioCatsInterop
private lazy val zioTest = "dev.zio" %% "zio-test" % Versions.zio % Test
private lazy val zioTestSbt = "dev.zio" %% "zio-test-sbt" % Versions.zio % Test
private lazy val zioTestMagnolia = "dev.zio" %% "zio-test-magnolia" % Versions.zio % Test

private lazy val doobiePostgres = "org.tpolecat" %% "doobie-postgres" % Versions.doobie
private lazy val doobieHikari = "org.tpolecat" %% "doobie-hikari" % Versions.doobie

private lazy val flyway = "org.flywaydb" % "flyway-core" % Versions.flyway

private lazy val quillDoobie = "io.getquill" %% "quill-doobie" % Versions.quill exclude("org.scala-lang.modules", "scala-java8-compat_3")
private lazy val testcontainers = "com.dimafeng" %% "testcontainers-scala-postgresql" % Versions.testContainersScalaPostgresql % Test

// We have to exclude bouncycastle since for some reason bitcoinj depends on bouncycastle jdk15to18
// (i.e. JDK 1.5 to 1.8), but we are using JDK 11
private lazy val prismCrypto = "io.iohk.atala" % "prism-crypto-jvm" % Versions.prismSdk excludeAll
Expand All @@ -36,8 +49,26 @@ object Dependencies {
"io.iohk.atala" %% "mercury-protocol-present-proof" % Versions.mercury
private lazy val mercuryResolver = "io.iohk.atala" %% "mercury-resolver" % Versions.mercury
// Dependency Modules
private lazy val baseDependencies: Seq[ModuleID] = Seq(zio, prismCrypto, shared)
private lazy val doobieDependencies: Seq[ModuleID] = Seq(doobiePostgres, doobieHikari, flyway)
private lazy val baseDependencies: Seq[ModuleID] = Seq(
zio,
zioTest,
zioTestSbt,
zioTestMagnolia,
prismCrypto,
shared,
logback,
slf4jApi,
slf4jSimple
)

private lazy val doobieDependencies: Seq[ModuleID] = Seq(
zioCatsInterop,
doobiePostgres,
doobieHikari,
flyway,
quillDoobie,
testcontainers
)

// Project Dependencies
lazy val coreDependencies: Seq[ModuleID] =
Expand All @@ -46,5 +77,5 @@ object Dependencies {
mercuryProtocolPresentProof,
mercuryResolver
)
lazy val sqlDoobieDependencies: Seq[ModuleID] = baseDependencies ++ doobieDependencies ++ Seq(zioCatsInterop)
lazy val sqlDoobieDependencies: Seq[ModuleID] = baseDependencies ++ doobieDependencies
}
@@ -0,0 +1,40 @@
CREATE TABLE public.verifiable_credential_schema
(
id UUID PRIMARY KEY default gen_random_uuid(),
name VARCHAR(128) NOT NULL,
version VARCHAR(64) NOT NULL,
tags VARCHAR(64) ARRAY NULL,
description TEXT NULL,
attributes VARCHAR(64) ARRAY NOT NULL,
author VARCHAR(255) NOT NULL,
authored TIMESTAMP WITH TIME ZONE NOT NULL,
proof_id UUID NULL,
UNIQUE (name, version, author)
);

CREATE INDEX name_index ON public.verifiable_credential_schema (name);
CREATE INDEX version_index ON public.verifiable_credential_schema (version);
CREATE INDEX tags_index ON public.verifiable_credential_schema (tags);
CREATE INDEX attributes_index ON public.verifiable_credential_schema (attributes);
CREATE INDEX author_index ON public.verifiable_credential_schema (author);
CREATE INDEX authored_index ON public.verifiable_credential_schema (authored);

CREATE TABLE public.proof
(
id UUID primary key default gen_random_uuid(),
type VARCHAR(128) NOT NULL,
created TIMESTAMP WITH TIME ZONE NOT NULL,
verification_method VARCHAR(128) NOT NULL,
proof_purpose VARCHAR(128) NOT NULL,
proof_value TEXT NOT NULL,
domain VARCHAR(255) NULL
);



CREATE INDEX type_index ON public.proof (type);
CREATE INDEX verification_method_index ON public.proof (verification_method);
CREATE INDEX proof_purpose_index ON public.proof (proof_purpose)



@@ -0,0 +1,104 @@
package io.iohk.atala.pollux.sql.model

import io.getquill.doobie.DoobieContext
import io.getquill.{Literal, SnakeCase, SqlMirrorContext}

import java.time.{OffsetDateTime, ZonedDateTime}
import java.util.UUID

case class VerifiableCredentialSchema(
id: UUID,
name: String,
version: String,
tags: List[String],
description: Option[String],
attributes: List[String],
author: String,
authored: OffsetDateTime
) {
lazy val uniqueConstraintKey = author + name + version
}

object VerifiableCredentialSchema {
object sql extends DoobieContext.Postgres(SnakeCase) {

import io.getquill.*
import io.getquill.idiom.*

def insert(schema: VerifiableCredentialSchema) = run {
quote {
query[VerifiableCredentialSchema].insertValue(lift(schema))
}
}

def findBy(id: UUID) = run {
quote {
query[VerifiableCredentialSchema]
.filter(schema => schema.id == lift(id))
.take(1)
}
}

def update(schema: VerifiableCredentialSchema) = run {
quote {
query[VerifiableCredentialSchema]
.filter(s => s.id == lift(schema.id))
.updateValue(lift(schema))
.returning(s => s)
}
}

def delete(id: UUID) = run {
quote {
query[VerifiableCredentialSchema]
.filter(schema => schema.id == lift(id))
.delete
.returning(_.id)
}
}

def deleteAll = run {
quote {
query[VerifiableCredentialSchema].delete
}
}

def totalCount = run {
quote {
query[VerifiableCredentialSchema].size
}
}

def lookup(
authorOpt: Option[String] = None,
nameOpt: Option[String] = None,
versionOpt: Option[String] = None,
attributeOpt: Option[String] = None,
tagOpt: Option[String] = None,
offsetOpt: Option[Int] = Some(0),
limitOpt: Option[Int] = Some(100)
) = {
val quotedQuery = limitOpt
.fold(quote(query[VerifiableCredentialSchema]))(limit =>
quote(query[VerifiableCredentialSchema].take(lift(limit)))
)

val dynamicQuery = quotedQuery.dynamic
.filterOpt(authorOpt)((vcs, author) => quote(vcs.author.like(author)))
.filterOpt(nameOpt)((vcs, name) => quote(vcs.name.like(name)))
.filterOpt(versionOpt)((vcs, version) => quote(vcs.version.like(version)))
.filter(vcs =>
attributeOpt
.fold(quote(true))(attr => quote(vcs.attributes.contains(lift(attr))))
)
.filter(vcs =>
tagOpt
.fold(quote(true))(tag => quote(vcs.tags.contains(lift(tag))))
)
.dropOpt(offsetOpt)
.sortBy(vcs => vcs.id)

dynamicQuery
}
}
}
@@ -0,0 +1,20 @@
first_name
second_name
date_of_birth
country_of_residence
country_of_birth
marriage_status
sex
degree
alumni_of
resident_of
member_of
owner_of
grade
score
flight_destination
flight_origin
board_number
booking_reference
expired_date
issuance_date
@@ -0,0 +1,40 @@
DrivingLicence
Passport
VaccinationCertificate
FlightTicket
MarriageCertificate
BachelorDegree
MasterDegree
PhDDegree
AWSCertifiedCloudPractitioner
AWSCertifiedDeveloper
AWSCertifiedSysOpsAdministrator–Associate(SOA-C02)
AWSCertifiedSolutionsArchitect
AWSCertifiedDevOpsEngineer
AWSCertifiedSolutionsArchitect
AWSCertifiedAdvancedNetworking
AWSCertifiedSecurity–Specialty
AWSCertifiedMachineLearning–Specialty
AWSCertifiedDatabase
AWSCertifiedDataAnalytics
AWSCertifiedSAPonAWS
GoogleCertifiedProfessionalCloudArchitect
GoogleCertifiedProfessionalDataEngineer
GoogleCertifiedProfessionalCloudDeveloper
GoogleCertifiedGSuiteAdministrator
GoogleCertifiedAssociateCloudEngineer
GoogleCertifiedProfessionalCloudNetworkEngineer
GoogleCertifiedProfessionalCloudSecurityEngineer
GoogleCertifiedProfessionalCloudDevOpsEngineer
GoogleCertifiedProfessionalCloudSolutionsArchitect
GoogleCertifiedProfessionalCloudSecurityManager
MicrosoftCertifiedSolutionsAssociate(MCSA):CloudPlatform
MicrosoftCertifiedSolutionsExpert(MCSE):CloudPlatformandInfrastructure
MicrosoftCertifiedSolutionsDeveloper(MCSD):AppBuilder
MicrosoftCertifiedSolutionsAssociate(MCSA):WindowsServer2016
MicrosoftCertifiedSolutionsExpert(MCSE):Productivity
MicrosoftCertifiedSolutionsExpert(MCSE):Mobility
MicrosoftCertifiedSolutionsAssociate(MCSA):Office365
MicrosoftCertifiedSolutionsExpert(MCSE):DataManagement&Analytics
MicrosoftCertifiedSolutionsExpert(MCSE):BusinessApplications
MicrosoftCertifiedSolutionsAssociate(MCSA):LinuxonAzure
20 changes: 20 additions & 0 deletions pollux/lib/sql-doobie/src/test/resources/logback.xml
@@ -0,0 +1,20 @@
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%level] %logger{15} - %message%n%rEx%xException{10}</pattern>
</encoder>
</appender>

<appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="STDOUT"/>
</appender>

<logger name="io.getquill" level="OFF"/>
<logger name="com.zaxxer.hikari" level="OFF"/>

<root level="INFO">
<appender-ref ref="ASYNCSTDOUT"/>
</root>

</configuration>

0 comments on commit f43320f

Please sign in to comment.