diff --git a/kotlin-samples/advanceCustomQuery/README.md b/kotlin-samples/advanceCustomQuery/README.md index 14a6267..45c9306 100644 --- a/kotlin-samples/advanceCustomQuery/README.md +++ b/kotlin-samples/advanceCustomQuery/README.md @@ -90,72 +90,86 @@ In order to demonstrate the custom query functionality, we will need to create a ``` Notice, the `chatName` and `message` are annotated with "from Dave". +#### Step 4: Create a Follow-up Chat Entry from Alice +Pick a VNode identity to initiate the chat, and get its short hash. (Let's pick Alice. Dont pick Bob because Bob is the person who we will have the chat with). +Go to `POST /flow/{holdingidentityshorthash}`, enter the identity short hash(Alice's hash) and request body: +``` +{ + "clientRequestId": "create-2", + "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.CreateNewChatFlow", + "requestBody": { + "chatName":"Follow up with Bob", + "otherMember":"CN=Bob, OU=Test Dept, O=R3, L=London, C=GB", + "message": "Are you there bob?" + } +} +``` ### Querying -#### Step 4: Perform Generic Query at Bob +#### Step 5: Perform Generic Query at Bob As a contrast, we will perform a generic query at Bob to query all the chat entries that Bob receives. This will print out all the chats that Bob has, including the message from Dave. ``` { "clientRequestId": "list-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListChatsFlow", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListChatsFlow", "requestBody": {} } ``` -#### Step 5: Perform Custom Filter Query to fetch all messages with hello +#### Step 6: Perform Custom Filter Query to fetch all messages with hello Now, we will perform the filter custom query, we will select Alice to trigger the flow with the following requestBody. Note that the `ListAllMsgsWithHello` is hard coded to query only every message with "hello" in the chat entries. ``` { "clientRequestId": "listMsgsWithHello-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListAllMsgsWithHello", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListAllMsgsWithHello", "requestBody": {} } ``` -#### Step 6: Perform Custom Transform Query to fetch all contents +#### Step 7: Perform Custom Transform Query to fetch all contents Now, we will perform the custom transform query, we will select Alice to trigger the flow with the following requestBody. This will fetch all message contents only. So it will return only the message and not the messageFrom or ID. ``` { - "clientRequestId": "ListMsgContents-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListAllMsgContents", + "clientRequestId": "ListOnlyMessagesFromResult-1", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListAllMsgContents", "requestBody": {} } ``` -#### Step 7: Perform Custom Count Query to get the total number of messages sent or received +#### Step 8: Perform Custom Count Query to get the total number of messages sent or received Now, we will perform the custom count query, we will select Alice to trigger the flow with the following requestBody. which will return the number of messages sent and received by Alice. ``` { "clientRequestId": "ListNumberOfTotalMessages-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListNumberOfTotalMessages", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListNumberOfTotalMessages", "requestBody": {} } ``` -#### Step 8: Perform Custom Combined Filter and Transform Query +#### Step 9: Perform Custom Combined Filter and Transform Query Now, we will perform the custom combined filter and transform query, we will select Alice to trigger the flow with the following requestBody. -This will list all the message contents that include the word "Hello" in it. Combining step 6 and 5 together in one query +This will list all the message contents that include the word "Hello" in it. Combining step 7 and 6 together in one query ``` { - "clientRequestId": "ListAllMsgContentsIncludingHello-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListAllMsgContentsIncludingHello", + "clientRequestId": "ListOnlyMessagesFromResultIncludingHello-1", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListAllMsgContentsIncludingHello", "requestBody": {} } ``` -#### Step 9: Perform Custom Combined Count and Filter Query +#### Step 10: Perform Custom Combined Count and Filter Query Now, we will perform the custom query, we will select Alice to trigger the flow with the following requestBody. -This will list the number of messages sent and received by Alice that include the word "Hello" in it. Combining step 5 and 7 together in one query. +This will list the number of messages sent and received by Alice that include the word "Hello" in it. Combining step 6 and 8 together in one query. ``` { "clientRequestId": "ListNumberOfTotalMessagesIncludingHello-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListNumberOfTotalMessagesIncludingHello", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListNumberOfTotalMessagesIncludingHello", "requestBody": {} } ``` diff --git a/kotlin-samples/advanceCustomQuery/contracts/src/main/kotlin/com/r3/developers/advanceCustomQuery/states/CustomChatQuery.kt b/kotlin-samples/advanceCustomQuery/contracts/src/main/kotlin/com/r3/developers/advanceCustomQuery/states/CustomChatQuery.kt index 23d9e49..477a8a7 100644 --- a/kotlin-samples/advanceCustomQuery/contracts/src/main/kotlin/com/r3/developers/advanceCustomQuery/states/CustomChatQuery.kt +++ b/kotlin-samples/advanceCustomQuery/contracts/src/main/kotlin/com/r3/developers/advanceCustomQuery/states/CustomChatQuery.kt @@ -10,13 +10,13 @@ import net.corda.v5.ledger.utxo.query.registration.VaultNamedQueryBuilderFactory class ChatCustomQueryFactory : VaultNamedQueryFactory { override fun create(vaultNamedQueryBuilderFactory: VaultNamedQueryBuilderFactory) { - vaultNamedQueryBuilderFactory.create("GET_ALL_MSG") + vaultNamedQueryBuilderFactory.create("GET_ALL_MSG") //used only in the other "simple" sample .whereJson( "WHERE visible_states.custom_representation ? 'com.r3.developers.advanceCustomQuery.states.ChatState' " ) .register() - vaultNamedQueryBuilderFactory.create("GET_MSG_FROM") + vaultNamedQueryBuilderFactory.create("GET_MSG_FROM") //used only in the other "simple" sample .whereJson( "WHERE visible_states.custom_representation -> 'com.r3.developers.advanceCustomQuery.states.ChatState' ->> 'messageContentFrom' = :nameOfSender" ) @@ -25,61 +25,66 @@ class ChatCustomQueryFactory : VaultNamedQueryFactory { .whereJson( "WHERE visible_states.custom_representation ? 'com.r3.developers.advanceCustomQuery.states.ChatState' " ) - .filter(CustomQueryFilter()) + .filter(CustomQueryFilter()) //applies the filter to this query .register() vaultNamedQueryBuilderFactory.create("GET_ALL_MSGS_CONTENT") .whereJson( "WHERE visible_states.custom_representation ? 'com.r3.developers.advanceCustomQuery.states.ChatState' " ) - .map(CustomQueryTransformer()) + .map(CustomQueryTransformer()) //applies the transformer to this query .register() vaultNamedQueryBuilderFactory.create("GET_MSG_AMOUNT") .whereJson( "WHERE visible_states.custom_representation ? 'com.r3.developers.advanceCustomQuery.states.ChatState' " ) - .collect(CustomQueryCollector()) + .collect(CustomQueryCollector()) //applies the collector to this query .register() vaultNamedQueryBuilderFactory.create("GET_MSG_AMOUNT_HAS_HELLO") .whereJson( "WHERE visible_states.custom_representation ? 'com.r3.developers.advanceCustomQuery.states.ChatState' " ) - .filter(CustomQueryFilter()) - .collect(CustomQueryCollector()) + .filter(CustomQueryFilter()) //applies the filter to this query + .collect(CustomQueryCollector()) //applies the collector after the filter has been applied .register() vaultNamedQueryBuilderFactory.create("GET_ALL_MSGS_CONTENT_HAS_HELLO") .whereJson( "WHERE visible_states.custom_representation ? 'com.r3.developers.advanceCustomQuery.states.ChatState' " ) - .filter(CustomQueryFilter()) - .map(CustomQueryTransformer()) + .filter(CustomQueryFilter()) //applies the filter to this query + .map(CustomQueryTransformer()) //applies the transformer after the filter has been applied .register() } } + +// for filtering states of type ChatState. class CustomQueryFilter : VaultNamedQueryStateAndRefFilter { override fun filter(data: StateAndRef, parameters: MutableMap): Boolean { - return data.state.contractState.message.lowercase().contains("hello") - } + return data.state.contractState.message.lowercase().contains("hello") // It returns true if the 'message' field in the state's contractState is lowercase and contains "hello". + } //return type is a boolean that will be checking for which entry passes and which fails. The query return type is still a StateAndRef } + +// for transforming states of type ChatState into a String. class CustomQueryTransformer : VaultNamedQueryStateAndRefTransformer { + // It returns the 'message' field from the state's contractState. override fun transform(data: StateAndRef, parameters: MutableMap): String { return data.state.contractState.message - } + } //return type is a String. This also alters the return type for the query to a String. Ensure that the query serializes the result to String } + +// to collect transformed data into a final result. It operates on String inputs and produces an Int result. class CustomQueryCollector : VaultNamedQueryCollector { - override fun collect( - resultSet: MutableList, - parameters: MutableMap - ): VaultNamedQueryCollector.Result { - return VaultNamedQueryCollector.Result( - listOf(resultSet.size), - true - ) - } -} \ No newline at end of file + // It returns a result containing the size of the resultSet + override fun collect(resultSet: MutableList, parameters: MutableMap): + VaultNamedQueryCollector.Result { + return VaultNamedQueryCollector.Result(listOf(resultSet.size), true) + } + //return type is a int. This also alters the return type for the query to a int. Ensure that the query serializes the result to integer + +} diff --git a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgContents.kt b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgContents.kt similarity index 92% rename from kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgContents.kt rename to kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgContents.kt index 138dbb4..11b2d99 100644 --- a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgContents.kt +++ b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgContents.kt @@ -1,4 +1,4 @@ -package com.r3.developers.advanceCustomQuery.workflows +package com.r3.developers.advanceCustomQuery.listUtil import net.corda.v5.application.flows.ClientRequestBody import net.corda.v5.application.flows.ClientStartableFlow @@ -48,7 +48,7 @@ class ListAllMsgContents : ClientStartableFlow { RequestBody for triggering the flow via REST: { "clientRequestId": "ListMsgContents-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListAllMsgContents", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListAllMsgContents", "requestBody": {} } */ diff --git a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgContentsIncludingHello.kt b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgContentsIncludingHello.kt similarity index 91% rename from kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgContentsIncludingHello.kt rename to kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgContentsIncludingHello.kt index db82dc7..0c823af 100644 --- a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgContentsIncludingHello.kt +++ b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgContentsIncludingHello.kt @@ -1,4 +1,4 @@ -package com.r3.developers.advanceCustomQuery.workflows +package com.r3.developers.advanceCustomQuery.listUtil import net.corda.v5.application.flows.ClientRequestBody import net.corda.v5.application.flows.ClientStartableFlow @@ -48,7 +48,7 @@ class ListAllMsgContentsIncludingHello : ClientStartableFlow { RequestBody for triggering the flow via REST: { "clientRequestId": "ListAllMsgContentsIncludingHello-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListAllMsgContentsIncludingHello", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListAllMsgContentsIncludingHello", "requestBody": {} } */ diff --git a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgsWithHello.kt b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgsWithHello.kt similarity index 93% rename from kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgsWithHello.kt rename to kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgsWithHello.kt index fbb20a5..55fd27f 100644 --- a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListAllMsgsWithHello.kt +++ b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListAllMsgsWithHello.kt @@ -1,4 +1,4 @@ -package com.r3.developers.advanceCustomQuery.workflows +package com.r3.developers.advanceCustomQuery.listUtil import com.r3.developers.advanceCustomQuery.states.ChatState import net.corda.v5.application.flows.ClientRequestBody @@ -60,7 +60,7 @@ class ListAllMsgsWithHello : ClientStartableFlow { RequestBody for triggering the flow via REST: { "clientRequestId": "listMsgsWithHello-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListAllMsgsWithHello", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListAllMsgsWithHello", "requestBody": {} } */ diff --git a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListChatsByCustomQueryFlow.kt b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListChatsByCustomQueryFlow.kt similarity index 93% rename from kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListChatsByCustomQueryFlow.kt rename to kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListChatsByCustomQueryFlow.kt index 0a41421..f67ebbf 100644 --- a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListChatsByCustomQueryFlow.kt +++ b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListChatsByCustomQueryFlow.kt @@ -1,4 +1,4 @@ -package com.r3.developers.advanceCustomQuery.workflows +package com.r3.developers.advanceCustomQuery.listUtil import com.r3.developers.advanceCustomQuery.states.ChatState import net.corda.v5.application.flows.ClientRequestBody @@ -59,7 +59,7 @@ class ListChatsByCustomQueryFlow : ClientStartableFlow { RequestBody for triggering the flow via REST: { "clientRequestId": "customlist-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListChatsByCustomQueryFlow", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListChatsByCustomQueryFlow", "requestBody": {} } */ diff --git a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListChatsFlow.kt b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListChatsFlow.kt similarity index 94% rename from kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListChatsFlow.kt rename to kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListChatsFlow.kt index d4259f8..4b56c3a 100644 --- a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListChatsFlow.kt +++ b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListChatsFlow.kt @@ -1,4 +1,4 @@ -package com.r3.developers.advanceCustomQuery.workflows +package com.r3.developers.advanceCustomQuery.listUtil import com.r3.developers.advanceCustomQuery.states.ChatState import net.corda.v5.application.flows.ClientRequestBody @@ -56,7 +56,7 @@ class ListChatsFlow : ClientStartableFlow { RequestBody for triggering the flow via REST: { "clientRequestId": "list-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListChatsFlow", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListChatsFlow", "requestBody": {} } */ diff --git a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListNumberOfTotalMessages.kt b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListNumberOfTotalMessages.kt similarity index 91% rename from kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListNumberOfTotalMessages.kt rename to kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListNumberOfTotalMessages.kt index 7307ba9..f7c2afe 100644 --- a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListNumberOfTotalMessages.kt +++ b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListNumberOfTotalMessages.kt @@ -1,4 +1,4 @@ -package com.r3.developers.advanceCustomQuery.workflows +package com.r3.developers.advanceCustomQuery.listUtil import net.corda.v5.application.flows.ClientRequestBody import net.corda.v5.application.flows.ClientStartableFlow @@ -48,7 +48,7 @@ class ListNumberOfTotalMessages : ClientStartableFlow { RequestBody for triggering the flow via REST: { "clientRequestId": "ListNumberOfTotalMessages-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListNumberOfTotalMessages", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListNumberOfTotalMessages", "requestBody": {} } */ diff --git a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListNumberOfTotalMessagesIncludingHello.kt b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListNumberOfTotalMessagesIncludingHello.kt similarity index 91% rename from kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListNumberOfTotalMessagesIncludingHello.kt rename to kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListNumberOfTotalMessagesIncludingHello.kt index 28db820..f5b22eb 100644 --- a/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/workflows/ListNumberOfTotalMessagesIncludingHello.kt +++ b/kotlin-samples/advanceCustomQuery/workflows/src/main/kotlin/com/r3/developers/advanceCustomQuery/listUtil/ListNumberOfTotalMessagesIncludingHello.kt @@ -1,4 +1,4 @@ -package com.r3.developers.advanceCustomQuery.workflows +package com.r3.developers.advanceCustomQuery.listUtil import net.corda.v5.application.flows.ClientRequestBody import net.corda.v5.application.flows.ClientStartableFlow @@ -48,7 +48,7 @@ class ListNumberOfTotalMessagesIncludingHello : ClientStartableFlow { RequestBody for triggering the flow via REST: { "clientRequestId": "ListNumberOfTotalMessagesIncludingHello-1", - "flowClassName": "com.r3.developers.advanceCustomQuery.workflows.ListNumberOfTotalMessagesIncludingHello", + "flowClassName": "com.r3.developers.advanceCustomQuery.listUtil.ListNumberOfTotalMessagesIncludingHello", "requestBody": {} } */