首页 > 解决方案 > CorDapp 在 CRaSH Shell 中工作,但 API 无法识别 CorDapp

问题描述

我正在尝试公开 CorDapp 的 API,但未显示函数。查看示例(https://github.com/roger3cev/obligation-cordapp)时,我收到以下页面:https : //imgur.com/a/ifOdrAd,但是当我加载我的 CorDapp 时,它说有本地主机上没有安装 Cordapps 和 /api 返回 404。在项目中,我觉得问题出在此处:https ://github.com/PronoyC/InsureFlight/tree/master/cordapp/src/main/kotlin/com /保险飞行。我知道这很模糊,但我找不到任何指示特定区域的错误。任何帮助,将不胜感激。

InsureFlightApi.kt:

package com.insureflight

import net.corda.core.contracts.Amount
import net.corda.core.contracts.UniqueIdentifier
import net.corda.core.messaging.CordaRPCOps
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.getOrThrow
import com.insureflight.flows.IssuePolicy
import com.insureflight.flows.PayoutPolicy
import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.getCashBalances
import net.corda.finance.flows.CashIssueFlow
import java.util.*
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.QueryParam
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response
import javax.ws.rs.core.Response.Status.BAD_REQUEST
import javax.ws.rs.core.Response.Status.CREATED

@Path("insureflight")
class InsureFlightApi(val rpcOps: CordaRPCOps) {

private val myIdentity = rpcOps.nodeInfo().legalIdentities.first()

@GET
@Path("me")
@Produces(MediaType.APPLICATION_JSON)
fun me() = mapOf("me" to myIdentity)

@GET
@Path("peers")
@Produces(MediaType.APPLICATION_JSON)
fun peers() = mapOf("peers" to rpcOps.networkMapSnapshot()
        .filter { nodeInfo -> nodeInfo.legalIdentities.first() != myIdentity }
        .map { it.legalIdentities.first().name.organisation })

@GET
@Path("policies")
@Produces(MediaType.APPLICATION_JSON)
fun policies() = rpcOps.vaultQuery(Policy::class.java).states

@GET
@Path("cash")
@Produces(MediaType.APPLICATION_JSON)
fun cash() = rpcOps.vaultQuery(Cash.State::class.java).states

@GET
@Path("cash-balances")
@Produces(MediaType.APPLICATION_JSON)
fun getCashBalances() = rpcOps.getCashBalances()

@GET
@Path("self-issue-cash")
fun selfIssueCash(@QueryParam(value = "amount") amount: Int,
                  @QueryParam(value = "currency") currency: String): Response {

    // 1. Prepare issue request.
    val issueAmount = Amount(amount.toLong(), Currency.getInstance(currency))
    val notary = rpcOps.notaryIdentities().firstOrNull() ?: throw IllegalStateException("Could not find a notary.")
    val issueRef = OpaqueBytes.of(0)
    val issueRequest = CashIssueFlow.IssueRequest(issueAmount, issueRef, notary)

    // 2. Start flow and wait for response.
    val (status, message) = try {
        val flowHandle = rpcOps.startFlowDynamic(CashIssueFlow::class.java, issueRequest)
        val result = flowHandle.use { it.returnValue.getOrThrow() }
        CREATED to result.stx.tx.outputs.single().data
    } catch (e: Exception) {
        BAD_REQUEST to e.message
    }

    // 3. Return the response.
    return Response.status(status).entity(message).build()
}

@GET
@Path("issue-policy")
fun issuePolicy(@QueryParam(value = "premium") premium: Int,
                @QueryParam(value = "currency") currency: String,
                @QueryParam(value = "client") client: String,
                @QueryParam(value = "underwriter") underwriter: String,
                @QueryParam(value = "flight") flight: String,
                @QueryParam(value = "fStatus") fStatus: String): Response {

    // 1. Create a premium object.
    val issuePremium = Amount(premium.toLong() * 100, Currency.getInstance(currency))

    // 2. Start the IssuePolicy flow. We block and wait for the flow to return.
    val (status, message) = try {
        val flowHandle = rpcOps.startFlowDynamic(
                IssuePolicy.Initiator::class.java,
                issuePremium,
                client,
                underwriter,
                flight,
                fStatus,
                true
        )

        val result = flowHandle.use { it.returnValue.getOrThrow() }
        CREATED to "Transaction id ${result.id} committed to ledger.\n${result.tx.outputs.single().data}"
    } catch (e: Exception) {
        BAD_REQUEST to e.message
    }

    // 3. Return the result.
    return Response.status(status).entity(message).build()
}

@GET
@Path("payout-policy")
fun settlePolicy(@QueryParam(value = "id") id: String,
                 @QueryParam(value = "delayedMinutes") delayedMinutes: Int,
                 @QueryParam(value = "fStatus") fStatus: String): Response {
    // 1. Get party objects for the counterparty.
    val linearId = UniqueIdentifier.fromString(id)

    // 2. Start the SettlePolicy flow. We block and wait for the flow to return.
    val (status, message) = try {
        val flowHandle = rpcOps.startFlowDynamic(
                PayoutPolicy.Initiator::class.java,
                linearId,
                delayedMinutes,
                fStatus,
                true
        )

        flowHandle.use { flowHandle.returnValue.getOrThrow() }
        CREATED to "Policy $linearId has been settled."
    } catch (e: Exception) {
        BAD_REQUEST to e.message
    }

    // 3. Return the result.
    return Response.status(status).entity(message).build()
}
}

InsureFlightPlugin.kt(ObligationPlugin.kt 与此非常相似):

package com.insureflight

import net.corda.core.messaging.CordaRPCOps
import net.corda.webserver.services.WebServerPluginRegistry
import java.util.function.Function

class InsureFlightPlugin : WebServerPluginRegistry {
override val webApis: List<Function<CordaRPCOps, out Any>> = listOf(Function(::InsureFlightApi))
override val staticServeDirs: Map<String, String> = mapOf(
        "policy" to javaClass.classLoader.getResource("policyWeb").toExternalForm()
)
}

标签: corda

解决方案


Kid101 是正确的。您必须注册 InsureFlightPlugin,如下所示:


推荐阅读