Skip to content

Commit aec0da6

Browse files
Added claims to accounts.
1 parent 3bc19fb commit aec0da6

File tree

8 files changed

+159
-103
lines changed

8 files changed

+159
-103
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ buildscript {
1414
junit_version = '5.3.1'
1515

1616
onixlabs_group = 'io.onixlabs'
17-
onixlabs_corda_core_release_version = '3.0.0-rc1'
17+
onixlabs_corda_core_release_version = '3.0.0'
1818

1919
cordapp_platform_version = 10
2020
cordapp_contract_name = 'ONIXLabs Corda Identity Framework Contract'

gradle.properties

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
name=onixlabs-corda-identity-framework
22
group=io.onixlabs
3-
version=3.0.0-rc1
4-
5-
kotlin.incremental=false
6-
kotlin.code.style=official
7-
3+
version=3.0.0
84
onixlabs.development.jarsign.keystore=../lib/onixlabs.development.pkcs12
95
onixlabs.development.jarsign.password=5891f47942424d2acbe108691fdb5ba258712fca7e4762be4327241ebf3dbfa3

onixlabs-corda-identity-framework-contract/src/main/kotlin/io/onixlabs/corda/identityframework/contract/accounts/Account.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ open class Account(
5353
* @return Returns a persistent state entity.
5454
*/
5555
override fun generateMappedObject(schema: MappedSchema): PersistentState = when (schema) {
56-
is AccountSchemaV1 -> AccountEntity(this)
56+
is AccountSchemaV1 -> AccountEntity.fromAccount(this)
5757
else -> throw IllegalArgumentException("Unrecognised schema: $schema.")
5858
}
5959

onixlabs-corda-identity-framework-contract/src/main/kotlin/io/onixlabs/corda/identityframework/contract/accounts/AccountSchema.kt

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,18 @@
1616

1717
package io.onixlabs.corda.identityframework.contract.accounts
1818

19-
import io.onixlabs.corda.identityframework.contract.claims.AbstractClaim
2019
import net.corda.core.crypto.NullKeys.NULL_PARTY
2120
import net.corda.core.identity.AbstractParty
22-
import net.corda.core.schemas.*
23-
import java.io.Serializable
21+
import net.corda.core.schemas.MappedSchema
22+
import net.corda.core.schemas.PersistentState
2423
import java.util.*
2524
import javax.persistence.*
26-
import kotlin.jvm.Transient
2725

2826
object AccountSchema {
2927

3028
object AccountSchemaV1 :
31-
MappedSchema(AccountSchema.javaClass, 1, listOf(AccountEntity::class.java, AccountClaim::class.java)) {
32-
override val migrationResource = super.migrationResource
29+
MappedSchema(AccountSchema.javaClass, 1, listOf(AccountEntity::class.java, AccountClaimEntity::class.java)) {
30+
override val migrationResource = "account-schema.changelog-master"
3331
}
3432

3533
@Entity
@@ -44,23 +42,48 @@ object AccountSchema {
4442
@Column(name = "owner", nullable = false)
4543
val owner: AbstractParty = NULL_PARTY,
4644

47-
@OneToMany(cascade = [CascadeType.PERSIST])
45+
@OneToMany(fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST])
4846
@JoinColumns(
49-
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
50-
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")
47+
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"),
48+
JoinColumn(name = "output_index", referencedColumnName = "output_index")
5149
)
52-
val claims: List<AccountClaim> = emptyList()
50+
@OrderColumn
51+
val claims: MutableSet<AccountClaimEntity> = mutableSetOf()
5352
) : PersistentState() {
54-
constructor(account: Account) : this(
55-
account.linearId.id,
56-
account.linearId.externalId,
57-
account.owner,
58-
account.claims.map { AccountClaim(it) })
53+
54+
companion object {
55+
fun fromAccount(account: Account): AccountEntity {
56+
val entity = AccountEntity(
57+
account.linearId.id,
58+
account.linearId.externalId,
59+
account.owner
60+
)
61+
62+
account.claims.forEach {
63+
val claimEntity = AccountClaimEntity(
64+
null,
65+
it.property,
66+
it.value.toString(),
67+
it.computeHash().toString(),
68+
entity
69+
)
70+
71+
entity.claims.add(claimEntity)
72+
}
73+
74+
return entity
75+
}
76+
}
5977
}
6078

6179
@Entity
6280
@Table(name = "onixlabs_account_claims")
63-
class AccountClaim(
81+
class AccountClaimEntity(
82+
@Id
83+
@GeneratedValue
84+
@Column(name = "id", unique = true, nullable = true)
85+
val id: UUID? = null,
86+
6487
@Column(name = "property", nullable = false)
6588
val property: String = "",
6689

@@ -70,25 +93,11 @@ object AccountSchema {
7093
@Column(name = "hash", nullable = false)
7194
val hash: String = "",
7295

73-
@EmbeddedId
74-
override val compositeKey: Key
75-
) : IndirectStatePersistable<Key> {
76-
constructor(claim: AbstractClaim<*>) : this(
77-
//UUID.randomUUID(),
78-
claim.property,
79-
claim.value.toString(),
80-
claim.computeHash().toString(),
81-
Key()
96+
@ManyToOne(fetch = FetchType.LAZY)
97+
@JoinColumns(
98+
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"),
99+
JoinColumn(name = "output_index", referencedColumnName = "output_index")
82100
)
83-
}
84-
85-
class Key(override val stateRef: PersistentStateRef? = null) : DirectStatePersistable, Serializable {
86-
override fun equals(other: Any?): Boolean {
87-
return this === other || (other is Key && other.stateRef == stateRef)
88-
}
89-
90-
override fun hashCode(): Int {
91-
return Objects.hash(stateRef)
92-
}
93-
}
101+
val account: AccountEntity? = null
102+
)
94103
}

onixlabs-corda-identity-framework-contract/src/main/resources/migration/account-schema.changelog-v1.xml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@
2121
<addPrimaryKey columnNames="output_index, transaction_id"
2222
constraintName="PK_onixlabs_account_states"
2323
tableName="onixlabs_account_states"/>
24-
<createIndex tableName="onixlabs_account_states" indexName="IDX_account_id">
25-
<column name="linear_id"/>
26-
</createIndex>
27-
<createIndex tableName="onixlabs_account_states" indexName="IDX_owner">
28-
<column name="owner"/>
29-
</createIndex>
3024
</changeSet>
3125
<changeSet author="ONIXLabs" id="create-onixlabs_account_claims">
3226
<createTable tableName="onixlabs_account_claims">
@@ -52,9 +46,6 @@
5246
<addPrimaryKey columnNames="id"
5347
constraintName="PK_onixlabs_account_claims"
5448
tableName="onixlabs_account_claims"/>
55-
<createIndex tableName="onixlabs_account_claims" indexName="IDX_account_claim_index">
56-
<column name="hash"/>
57-
</createIndex>
5849
<createIndex tableName="onixlabs_account_claims" indexName="IDX_transaction_reference">
5950
<column name="output_index"/>
6051
<column name="transaction_id"/>

onixlabs-corda-identity-framework-workflow/src/main/kotlin/io/onixlabs/corda/identityframework/workflow/Extensions.QueryDsl.Account.kt

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ import io.onixlabs.corda.core.services.QueryDsl
2020
import io.onixlabs.corda.core.services.QueryDslContext
2121
import io.onixlabs.corda.core.services.equalTo
2222
import io.onixlabs.corda.identityframework.contract.accounts.Account
23-
import io.onixlabs.corda.identityframework.contract.accounts.AccountSchema.AccountClaim
2423
import io.onixlabs.corda.identityframework.contract.accounts.AccountSchema.AccountEntity
25-
import io.onixlabs.corda.identityframework.contract.claims.AbstractClaim
2624
import net.corda.core.identity.AbstractParty
2725

2826
/**
@@ -34,33 +32,3 @@ import net.corda.core.identity.AbstractParty
3432
fun QueryDsl<out Account>.accountOwner(value: AbstractParty) {
3533
expression(AccountEntity::owner equalTo value)
3634
}
37-
38-
/**
39-
* Adds a vault query expression to filter by account claim equal to the specified value.
40-
*
41-
* @param value The value to filter by in the vault query expression.
42-
*/
43-
@QueryDslContext
44-
fun QueryDsl<out Account>.accountClaim(value: AbstractClaim<*>) {
45-
expression(AccountClaim::hash equalTo value.computeHash().toString())
46-
}
47-
48-
/**
49-
* Adds a vault query expression to filter by account claim equal property to the specified value.
50-
*
51-
* @param value The value to filter by in the vault query expression.
52-
*/
53-
@QueryDslContext
54-
fun QueryDsl<out Account>.accountClaimProperty(value: String) {
55-
expression(AccountClaim::property equalTo value)
56-
}
57-
58-
/**
59-
* Adds a vault query expression to filter by account claim equal value to the specified value.
60-
*
61-
* @param value The value to filter by in the vault query expression.
62-
*/
63-
@QueryDslContext
64-
fun QueryDsl<out Account>.accountClaimValue(value: Any) {
65-
expression(AccountClaim::value equalTo value.toString())
66-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2020-2021 ONIXLabs
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.onixlabs.corda.identityframework.workflow.accounts
18+
19+
import co.paralleluniverse.fibers.Suspendable
20+
import net.corda.core.contracts.StateRef
21+
import net.corda.core.crypto.SecureHash
22+
import net.corda.core.flows.FlowLogic
23+
import net.corda.core.flows.StartableByRPC
24+
import net.corda.core.flows.StartableByService
25+
import java.sql.ResultSet
26+
27+
@StartableByRPC
28+
@StartableByService
29+
class GetAccountStateRefsByClaimFlow(
30+
private val property: String? = null,
31+
private val value: Any? = null,
32+
private val hash: SecureHash? = null
33+
) : FlowLogic<List<StateRef>>() {
34+
35+
private companion object {
36+
const val TRANSACTION_ID = "transaction_id"
37+
const val OUTPUT_INDEX = "output_index"
38+
}
39+
40+
@Suspendable
41+
override fun call(): List<StateRef> {
42+
return if (property == null && value == null && hash == null) emptyList() else executeQuery(buildString {
43+
val criteria = mutableListOf<String>()
44+
45+
property?.let { criteria.add("property = '$it'") }
46+
value?.let { criteria.add("value = '$it'") }
47+
hash?.let { criteria.add("hash = '$it'") }
48+
49+
appendln("select $TRANSACTION_ID, $OUTPUT_INDEX")
50+
appendln("from onixlabs_account_claims")
51+
appendln("where ${criteria.joinToString("\nand ")}")
52+
})
53+
}
54+
55+
@Suspendable
56+
private fun executeQuery(query: String): List<StateRef> {
57+
return with(serviceHub.jdbcSession()) {
58+
val nativeQuery = nativeSQL(query)
59+
prepareStatement(nativeQuery).use {
60+
it.executeQuery().use(::getStateRefsFromResults)
61+
}
62+
}
63+
}
64+
65+
@Suspendable
66+
private fun getStateRefsFromResults(results: ResultSet): List<StateRef> {
67+
val stateRefs = mutableListOf<StateRef>()
68+
69+
while (results.next()) {
70+
val txHash = SecureHash.parse(results.getString(TRANSACTION_ID))
71+
val index = results.getInt(OUTPUT_INDEX)
72+
stateRefs.add(StateRef(txHash, index))
73+
}
74+
75+
return stateRefs
76+
}
77+
}

0 commit comments

Comments
 (0)