科尔达服务101
我今天想寫(xiě)一篇簡(jiǎn)短的要點(diǎn)文章。 我真的很好奇我能多快出版此書(shū)。 所以走吧
這篇文章是關(guān)于Corda Services(使用Corda 3.2版)的。 這些是什么? 作為經(jīng)常使用Spring的開(kāi)發(fā)人員,我個(gè)人會(huì)說(shuō)它們就像Beans。 Spring Beans可以做的還很多,但是從根本上講,它們非常相似。 無(wú)論如何,讓我們停止談?wù)揝pring,而專(zhuān)注于Corda。
您需要知道的最低限度
Corda服務(wù)是Flow外部的類(lèi),當(dāng)前只能從正在執(zhí)行的Flow或其他服務(wù)(依次由Flow調(diào)用)中調(diào)用。 與subFlow相似,它們?cè)试S您重用代碼,但出于不同的原因應(yīng)使用它們。 例如,庫(kù)查詢功能的集合或節(jié)點(diǎn)內(nèi)的啟動(dòng)trackBy 。 這些都是我傾向于使用服務(wù)的方式。
Corda服務(wù)是通過(guò)使用@CordaService批注以及擴(kuò)展SingletonSerializeAsToken來(lái)定義的。 完成此操作后,在加載Cordapp并啟動(dòng)節(jié)點(diǎn)時(shí),將初始化您剛剛定義的服務(wù):
@CordaService class MessageRepository(private val serviceHub: AppServiceHub) : SingletonSerializeAsToken() {private companion object {val log = loggerFor()}init {log.info("I am alive!")}fun findAll(pageSpec: PageSpecification): Vault.Page =serviceHub.vaultService.queryBy(QueryCriteria.LinearStateQueryCriteria(), pageSpec) }serviceHub提供對(duì)您所需一切的訪問(wèn)。 在此示例中,服務(wù)訪問(wèn)vaultService以從節(jié)點(diǎn)的保管庫(kù)檢索狀態(tài)。
現(xiàn)在可以根據(jù)需要在Flows或其他服務(wù)中使用它。 以下摘錄摘自我的流程之一:
private fun repository() = serviceHub.cordaService(MessageRepository::class.java)serviceHub適用于所有流量,并提供cordaService功能。 對(duì)于輸入,它需要您嘗試檢索的服務(wù)的類(lèi)。 在這種情況下,正在加載MessageRepository 。
一點(diǎn)點(diǎn)更多信息
這就是開(kāi)始使用Corda Services所需的全部。 但。 我會(huì)為您提供更多信息,以便您不會(huì)犯一些與我相同的錯(cuò)誤。
第一課。 從Flow調(diào)用服務(wù)時(shí)。 不要將其注入Flow的構(gòu)造函數(shù)中。 而是從call函數(shù)內(nèi)部的任何位置或此后使用的任何其他函數(shù)調(diào)用它。 如果您不這樣做,則會(huì)看到以下錯(cuò)誤消息:
java.lang.IllegalStateException: This can only be done after the flow has been started.上面是從測(cè)試調(diào)用Flow時(shí)會(huì)得到的錯(cuò)誤。 如果從RPC調(diào)用,您將得到以下內(nèi)容:
Caused by: java.lang.reflect.InvocationTargetException: null Caused by: java.lang.IllegalStateException: This can only be done after the flow has been started.根據(jù)您選擇的Web框架,可能具有較長(zhǎng)的stacktrace。
目前尚不清楚,在這一點(diǎn)上注入服務(wù)會(huì)導(dǎo)致這些錯(cuò)誤,并且您可能會(huì)發(fā)現(xiàn)它們是由于其他原因而彈出的。 但是,至少在Corda 3.2 ,我認(rèn)為可以肯定地說(shuō),您不應(yīng)在構(gòu)造函數(shù)內(nèi)部或Flow初始化期間執(zhí)行任何操作。
為了使這一點(diǎn)更加清楚,下面是在較早的代碼片段中插入了該服務(wù)的代碼:
@InitiatingFlow @StartableByRPC class ReplyToMessagesFlow : FlowLogic<List>() {@Suspendableoverride fun call(): List {return messages().map { reply(it) }}private fun messages() =repository().findAll(PageSpecification(1, 100)).states.filter { it.state.data.recipient == ourIdentity }private fun repository() = serviceHub.cordaService(MessageRepository::class.java)@Suspendableprivate fun reply(message: StateAndRef) = subFlow(SendMessageFlow(response(message), message))private fun response(message: StateAndRef): MessageState {val state = message.state.datareturn state.copy(contents = "Thanks for your message: ${state.contents}",recipient = state.sender,sender = state.recipient)} }如您所見(jiàn),該服務(wù)被注入到repository函數(shù)中,該函數(shù)又被call 。 按照這種結(jié)構(gòu),一切都將正常工作。
第二課。 不要忘記在服務(wù)的構(gòu)造函數(shù)中包含serviceHub: AppServiceHub (可以隨意調(diào)用serviceHub )。 如果不這樣做,它將不會(huì)創(chuàng)建服務(wù),并且在嘗試訪問(wèn)該服務(wù)時(shí)會(huì)彈出以下錯(cuò)誤消息:
Caused by: java.lang.IllegalArgumentException: Corda service com.lankydanblog.tutorial.services.MessageRepository does not exist盡管在這種情況下有一線希望……您極不可能這樣做。 因?yàn)闆](méi)有AppServiceHub實(shí)例,使用您自己的服務(wù)實(shí)際上無(wú)能為力。 您將無(wú)權(quán)訪問(wèn)Vault或任何其他內(nèi)置服務(wù)。 所以,總的來(lái)說(shuō),這一課是毫無(wú)意義的,但我仍然陷入了這個(gè)陷阱……
這就是全部?
該死,我想我實(shí)際上曾經(jīng)寫(xiě)過(guò)一篇短篇文章! 是好還是壞? 我不是100%確定...
無(wú)論如何,我非常努力地想想更多的信息片段。 但是我不能。 使Corda Service正常工作的最低限度的確很容易。
話雖這么說(shuō),在過(guò)去的幾周中,我了解到您可以在Flows中無(wú)法完成的服務(wù)中完成一些非??岫杏玫墓ぷ?。 我希望在某個(gè)時(shí)候涵蓋這一主題!
結(jié)論
Corda Services允許您在Flow外部創(chuàng)建類(lèi),在此您可以在邏輯上對(duì)與Flow的執(zhí)行沒(méi)有直接關(guān)系的代碼進(jìn)行分組。 我最喜歡的使用服務(wù)的方法是將保管庫(kù)查詢功能分組到一個(gè)類(lèi)中(這與我在Spring世界中所做的差不多)。 您需要采取一些步驟來(lái)確保正確創(chuàng)建服務(wù)。 首先,使用@CordaService對(duì)其進(jìn)行@CordaService并擴(kuò)展SingletonSerializeAsToken 。 其次,確保以正確的方式將它們注入到Flow中,除了構(gòu)造函數(shù)(或Kotlin中的init )以外,幾乎在任何地方都沒(méi)有。 最后,請(qǐng)記住在服務(wù)的構(gòu)造函數(shù)中包含AppServiceHub 。 一旦能夠使用Corda服務(wù),就可以將代碼從Flow中分離出來(lái)。 不僅使流程更短,而且使流程更易于理解,同時(shí)增加了您花費(fèi)寶貴時(shí)間編寫(xiě)的代碼的可重用性。
這篇文章使用的代碼可以在我的GitHub上找到 。 該存儲(chǔ)庫(kù)中還有很多內(nèi)容未包含在本文中。
如果您認(rèn)為這篇文章有幫助,可以在Twitter上@LankyDanDev關(guān)注我,以跟上我的新文章。
翻譯自: https://www.javacodegeeks.com/2018/08/corda-services-101.html
總結(jié)
- 上一篇: apache camel_轻量级的开源集
- 下一篇: intent隐式和显式_Neo4j:使隐