我正在尝试公开针对CorDapp的API,但功能未显示。在查看示例(https://github.com/roger3cev/obligation-cordapp)时,我收到以下页面:https://imgur.com/a/ifOdrAd,但是,当我加载CorDapp时,它说没有安装Cordapps,并且localhost上的/ api返回404。该项目,我觉得问题出在这里https://github.com/PronoyC/InsureFlight/tree/master/cordapp/src/main/kotlin/com/insureflight。我知道这很模糊,但找不到任何指示特定区域的错误。任何帮助将不胜感激。
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()
)
}
答案 0 :(得分:2)
Kid101是正确的。您必须像在此一样注册InsureFlightPlugin:义务-cordapp / kotlin-source / src / main / resources / META-INF / services / net.corda.webserver.services.WebServerPluginRegistry