科尔达服务101

我今天想写一篇简短的要点文章。 我真的很好奇我能多快出版此书。 所以走吧

这篇文章是关于Corda Services的(使用Corda 3.2版)。 这些是什么? 作为经常使用Spring的开发人员,我个人会说它们就像Beans。 Spring Beans可以做的还很多,但是从根本上讲,它们非常相似。 无论如何,让我们停止谈论Spring,而专注于Corda。

科尔达服务

您需要知道的最低限度

Corda服务是Flow外部的类,当前只能从正在执行的Flow内或从另一个服务(依次由Flow调用)中调用。 与subFlow相似,它们允许您重用代码,但出于不同的原因应使用它们。 例如,保管库查询功能的集合或节点内的启动trackBy 。 这些都是我倾向于使用服务的方式。

Corda服务是通过使用@CordaService批注以及扩展SingletonSerializeAsToken来定义的。 完成此操作后,在加载Cordapp并启动节点时,将初始化您刚刚定义的服务:

@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提供对您所需一切的访问。 在此示例中,服务访问vaultService以从节点的保管库检索状态。

现在可以根据需要在Flows或其他服务中使用它。 以下摘录摘自我的流程之一:

private fun repository() = serviceHub.cordaService(MessageRepository::class.java)

serviceHub适用于所有流量,并提供cordaService功能。 对于输入,它需要您尝试检索的服务的类。 在这种情况下,正在加载MessageRepository

一点点更多信息

这就是开始使用Corda Services所需的全部。 但。 我会为您提供更多信息,以便您不会犯一些与我相同的错误。

第一课。 从Flow调用服务时。 不要将其注入Flow的构造函数中。 而是从call函数内部的任何位置或此后使用的任何其他函数调用它。 如果您不这样做,则会看到以下错误消息:

java.lang.IllegalStateException: This can only be done after the flow has been started.

上面是从测试调用Flow时会得到的错误。 如果从RPC调用,您将得到以下内容:

Caused by: java.lang.reflect.InvocationTargetException: null
Caused by: java.lang.IllegalStateException: This can only be done after the flow has been started.

根据您选择的Web框架,可能具有较长的stacktrace。

目前尚不清楚,在这一点上注入服务会导致这些错误,您可能会发现它们是由于其他原因而弹出的。 但是,至少在Corda 3.2 ,我认为可以肯定地说,您不应在构造函数内部或Flow初始化期间执行任何操作。

为了使这一点更加清楚,下面是在较早的代码片段中插入了该服务的代码:

@InitiatingFlow
@StartableByRPC
class ReplyToMessagesFlow : FlowLogic<List>() {

    @Suspendable
    override 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)

    @Suspendable
    private fun reply(message: StateAndRef) = subFlow(SendMessageFlow(response(message), message))

    private fun response(message: StateAndRef): MessageState {
        val state = message.state.data
        return state.copy(
            contents = "Thanks for your message: ${state.contents}",
            recipient = state.sender,
            sender = state.recipient
        )
    }
}

如您所见,该服务被注入到repository函数中,该函数又被call 。 按照这种结构,一切都会很好。

第二课。 不要忘记在服务的构造函数中包含serviceHub: AppServiceHub (可以随意调用serviceHub )。 如果不这样做,它将不会创建服务,并且在尝试访问该服务时会弹出以下错误消息:

Caused by: java.lang.IllegalArgumentException: Corda service com.lankydanblog.tutorial.services.MessageRepository does not exist

尽管在这种情况下有一线希望……您极不可能这样做。 因为没有AppServiceHub实例,使用您自己的服务实际上无能为力。 您将无权访问Vault或任何其他内置服务。 所以,总的来说,这一课是毫无意义的,但我仍然陷入了这个陷阱……

这就是全部?

该死,我想我实际上曾经写过一篇短篇文章! 是好还是坏? 我不确定100%是否…

无论如何,我非常努力地想想更多的信息摘要。 但是我不能。 使Corda Service正常工作的最低要求确实很容易。

话虽如此,在过去的几周中,我了解到您可以在Flows中无法完成的服务中完成一些非常酷而有用的工作。 我希望在某个时候涵盖这一主题!

结论

Corda Services允许您在Flow外部创建类,您可以在其中对与Flow的执行没有直接关系的代码进行逻辑分组。 我最喜欢的使用服务的方法是将保管库查询功能分组到一个类中(这与我在Spring世界中所做的差不多)。 您需要采取一些步骤来确保正确创建服务。 首先,使用@CordaService对其进行注释,并扩展SingletonSerializeAsToken 。 其次,确保以正确的方式将它们注入到Flow中,除了构造函数(或Kotlin中的init )以外,几乎在任何地方都没有。 最后,请记住在服务的构造函数中包含AppServiceHub 。 一旦能够使用Corda服务,就可以将代码从Flow中分离出来。 不仅使流程更短,而且使流程更易于理解,同时增加了您花费宝贵时间编写的代码的可重用性。

这篇文章使用的代码可以在我的GitHub上找到。 该存储库中有很多内容未包含在此文章中。

如果您认为这篇文章有帮助,可以在Twitter上@LankyDanDev关注我,以跟上我的新文章。

翻译自: https://www.javacodegeeks.com/2018/08/corda-services-101.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值