mirror of
https://github.com/corda/corda.git
synced 2025-05-02 08:43:15 +00:00
CORDA-599: Fix IRS demo (#1460)
* [CORDA-559]: Fixed incorrectly referenced deal notional amounts in views. * [CORDA-559]: Fixed missing parties in IRS demo deal view. * [CORDA-559]: Fixed failing creation of deals in IRS demo. * [CORDA-559]: Added to changelog. * [CORDA-559]: Fixed the broken integration test in IRS demo.
This commit is contained in:
parent
8415a01a47
commit
15aa4036b6
@ -129,6 +129,11 @@ UNRELEASED
|
|||||||
|
|
||||||
* Test type ``NodeHandle`` now has method ``stop(): CordaFuture<Unit>`` that terminates the referenced node.
|
* Test type ``NodeHandle`` now has method ``stop(): CordaFuture<Unit>`` that terminates the referenced node.
|
||||||
|
|
||||||
|
* Fixed some issues in IRS demo:
|
||||||
|
* Fixed leg and floating leg notional amounts were not displayed for created deals neither in single nor in list view.
|
||||||
|
* Parties were not displayed for created deals in single view.
|
||||||
|
* Non-default notional amounts caused the creation of new deals to fail.
|
||||||
|
|
||||||
Milestone 14
|
Milestone 14
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
package net.corda.irs
|
package net.corda.irs
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParseException
|
||||||
|
import com.fasterxml.jackson.core.JsonParser
|
||||||
|
import com.fasterxml.jackson.core.TreeNode
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||||
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import net.corda.client.rpc.CordaRPCClient
|
import net.corda.client.rpc.CordaRPCClient
|
||||||
|
import net.corda.core.contracts.UniqueIdentifier
|
||||||
import net.corda.core.messaging.vaultTrackBy
|
import net.corda.core.messaging.vaultTrackBy
|
||||||
import net.corda.core.node.services.ServiceInfo
|
import net.corda.core.node.services.ServiceInfo
|
||||||
import net.corda.core.toFuture
|
import net.corda.core.toFuture
|
||||||
@ -63,6 +72,7 @@ class IRSDemoTest : IntegrationTestCategory {
|
|||||||
val (_, nodeAApi, nodeBApi) = listOf(controller, nodeA, nodeB).zip(listOf(controllerAddr, nodeAAddr, nodeBAddr)).map {
|
val (_, nodeAApi, nodeBApi) = listOf(controller, nodeA, nodeB).zip(listOf(controllerAddr, nodeAAddr, nodeBAddr)).map {
|
||||||
val mapper = net.corda.client.jackson.JacksonSupport.createDefaultMapper(it.first.rpc)
|
val mapper = net.corda.client.jackson.JacksonSupport.createDefaultMapper(it.first.rpc)
|
||||||
registerFinanceJSONMappers(mapper)
|
registerFinanceJSONMappers(mapper)
|
||||||
|
registerIRSModule(mapper)
|
||||||
HttpApi.fromHostAndPort(it.second, "api/irs", mapper = mapper)
|
HttpApi.fromHostAndPort(it.second, "api/irs", mapper = mapper)
|
||||||
}
|
}
|
||||||
val nextFixingDates = getFixingDateObservable(nodeA.configuration)
|
val nextFixingDates = getFixingDateObservable(nodeA.configuration)
|
||||||
@ -133,7 +143,30 @@ class IRSDemoTest : IntegrationTestCategory {
|
|||||||
return deals
|
return deals
|
||||||
}
|
}
|
||||||
|
|
||||||
fun<T> Observable<T>.firstWithTimeout(timeout: Duration, pred: (T) -> Boolean) {
|
fun <T> Observable<T>.firstWithTimeout(timeout: Duration, pred: (T) -> Boolean) {
|
||||||
first(pred).toFuture().getOrThrow(timeout)
|
first(pred).toFuture().getOrThrow(timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun registerIRSModule(mapper: ObjectMapper) {
|
||||||
|
val module = SimpleModule("finance").apply {
|
||||||
|
addDeserializer(InterestRateSwap.State::class.java, InterestRateSwapStateDeserializer(mapper))
|
||||||
|
}
|
||||||
|
mapper.registerModule(module)
|
||||||
|
}
|
||||||
|
|
||||||
|
class InterestRateSwapStateDeserializer(private val mapper: ObjectMapper) : JsonDeserializer<InterestRateSwap.State>() {
|
||||||
|
override fun deserialize(parser: JsonParser, context: DeserializationContext): InterestRateSwap.State {
|
||||||
|
return try {
|
||||||
|
val node = parser.readValueAsTree<TreeNode>()
|
||||||
|
val fixedLeg: InterestRateSwap.FixedLeg = mapper.readValue(node.get("fixedLeg").toString())
|
||||||
|
val floatingLeg: InterestRateSwap.FloatingLeg = mapper.readValue(node.get("floatingLeg").toString())
|
||||||
|
val calculation: InterestRateSwap.Calculation = mapper.readValue(node.get("calculation").toString())
|
||||||
|
val common: InterestRateSwap.Common = mapper.readValue(node.get("common").toString())
|
||||||
|
val linearId: UniqueIdentifier = mapper.readValue(node.get("linearId").toString())
|
||||||
|
InterestRateSwap.State(fixedLeg = fixedLeg, floatingLeg = floatingLeg, calculation = calculation, common = common, linearId = linearId)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw JsonParseException(parser, "Invalid interest rate swap state(s) ${parser.text}: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,7 +597,7 @@ class InterestRateSwap : Contract {
|
|||||||
/**
|
/**
|
||||||
* The state class contains the 4 major data classes.
|
* The state class contains the 4 major data classes.
|
||||||
*/
|
*/
|
||||||
@JsonIgnoreProperties("parties", "participants", ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
data class State(
|
data class State(
|
||||||
val fixedLeg: FixedLeg,
|
val fixedLeg: FixedLeg,
|
||||||
val floatingLeg: FloatingLeg,
|
val floatingLeg: FloatingLeg,
|
||||||
|
@ -37,7 +37,7 @@ define(['viewmodel/FixedRate'], (fixedRateViewModel) => {
|
|||||||
_.assign(fixedLeg.fixedRate, fixedRateViewModel);
|
_.assign(fixedLeg.fixedRate, fixedRateViewModel);
|
||||||
|
|
||||||
fixedLeg.fixedRate = Number(fixedLeg.fixedRate) / 100;
|
fixedLeg.fixedRate = Number(fixedLeg.fixedRate) / 100;
|
||||||
fixedLeg.notional.token = common.baseCurrency;
|
fixedLeg.notional = fixedLeg.notional + ' ' + common.baseCurrency;
|
||||||
fixedLeg.effectiveDate = formatDateForNode(common.effectiveDate);
|
fixedLeg.effectiveDate = formatDateForNode(common.effectiveDate);
|
||||||
fixedLeg.terminationDate = formatDateForNode(common.terminationDate);
|
fixedLeg.terminationDate = formatDateForNode(common.terminationDate);
|
||||||
fixedLeg.fixedRate = { ratioUnit: { value: fixedLeg.fixedRate } };
|
fixedLeg.fixedRate = { ratioUnit: { value: fixedLeg.fixedRate } };
|
||||||
@ -46,7 +46,7 @@ define(['viewmodel/FixedRate'], (fixedRateViewModel) => {
|
|||||||
fixedLeg.paymentCalendar = calendarLookup[common.baseCurrency];
|
fixedLeg.paymentCalendar = calendarLookup[common.baseCurrency];
|
||||||
delete fixedLeg.dayCountBasis;
|
delete fixedLeg.dayCountBasis;
|
||||||
|
|
||||||
floatingLeg.notional.token = common.baseCurrency;
|
floatingLeg.notional = floatingLeg.notional + ' ' + common.baseCurrency;
|
||||||
floatingLeg.effectiveDate = formatDateForNode(common.effectiveDate);
|
floatingLeg.effectiveDate = formatDateForNode(common.effectiveDate);
|
||||||
floatingLeg.terminationDate = formatDateForNode(common.terminationDate);
|
floatingLeg.terminationDate = formatDateForNode(common.terminationDate);
|
||||||
floatingLeg.dayCountBasisDay = floatingLeg.dayCountBasis.day;
|
floatingLeg.dayCountBasisDay = floatingLeg.dayCountBasis.day;
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
define(['utils/dayCountBasisLookup'], (dayCountBasisLookup) => {
|
define(['utils/dayCountBasisLookup'], (dayCountBasisLookup) => {
|
||||||
return {
|
return {
|
||||||
fixedRatePayer: "O=Bank A,L=London,C=GB",
|
fixedRatePayer: "O=Bank A,L=London,C=GB",
|
||||||
notional: {
|
notional: 2500000000,
|
||||||
quantity: 2500000000
|
|
||||||
},
|
|
||||||
paymentFrequency: "SemiAnnual",
|
paymentFrequency: "SemiAnnual",
|
||||||
effectiveDateAdjustment: null,
|
effectiveDateAdjustment: null,
|
||||||
terminationDateAdjustment: null,
|
terminationDateAdjustment: null,
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
define(['utils/dayCountBasisLookup'], (dayCountBasisLookup) => {
|
define(['utils/dayCountBasisLookup'], (dayCountBasisLookup) => {
|
||||||
return {
|
return {
|
||||||
floatingRatePayer: "O=Bank B,L=New York,C=US",
|
floatingRatePayer: "O=Bank B,L=New York,C=US",
|
||||||
notional: {
|
notional: 2500000000,
|
||||||
quantity: 2500000000
|
|
||||||
},
|
|
||||||
paymentFrequency: "Quarterly",
|
paymentFrequency: "Quarterly",
|
||||||
effectiveDateAdjustment: null,
|
effectiveDateAdjustment: null,
|
||||||
terminationDateAdjustment: null,
|
terminationDateAdjustment: null,
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Notional</label>
|
<label>Notional</label>
|
||||||
<input type="text" name="quantity" ng-model="deal.fixedLeg.notional.quantity" fcsa-number/>
|
<input type="text" name="quantity" ng-model="deal.fixedLeg.notional" fcsa-number/>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Fixed Rate</label>
|
<label>Fixed Rate</label>
|
||||||
@ -99,7 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Notional</label>
|
<label>Notional</label>
|
||||||
<input type="text" name="quantity" ng-model="deal.floatingLeg.notional.quantity" fcsa-number/>
|
<input type="text" name="quantity" ng-model="deal.floatingLeg.notional" fcsa-number/>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>Payment Frequency</label>
|
<label>Payment Frequency</label>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<tr class="center aligned">
|
<tr class="center aligned">
|
||||||
<td>Parties</td>
|
<td>Parties</td>
|
||||||
<td>
|
<td>
|
||||||
<span ng-repeat="party in deal.parties">
|
<span ng-repeat="party in deal.participants">
|
||||||
{{party}}<span ng-show="!$last">,</span>
|
{{party}}<span ng-show="!$last">,</span>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
@ -55,7 +55,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr class="center aligned">
|
<tr class="center aligned">
|
||||||
<td>Notional</td>
|
<td>Notional</td>
|
||||||
<td>{{deal.fixedLeg.notional.quantity | number}} {{deal.fixedLeg.notional.token}}</td>
|
<td>{{deal.fixedLeg.notional}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="center aligned">
|
<tr class="center aligned">
|
||||||
<td>Payment Frequency</td>
|
<td>Payment Frequency</td>
|
||||||
@ -124,7 +124,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr class="center aligned">
|
<tr class="center aligned">
|
||||||
<td>Notional</td>
|
<td>Notional</td>
|
||||||
<td>{{deal.floatingLeg.notional.quantity | number}} {{deal.floatingLeg.notional.token}}</td>
|
<td>{{deal.floatingLeg.notional}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="center aligned">
|
<tr class="center aligned">
|
||||||
<td>Payment Frequency</td>
|
<td>Payment Frequency</td>
|
||||||
|
@ -48,9 +48,9 @@
|
|||||||
<tr class="center aligned" ng-repeat="deal in deals">
|
<tr class="center aligned" ng-repeat="deal in deals">
|
||||||
<td><a href="#/deal/{{deal.ref}}">{{deal.ref}}</a></td>
|
<td><a href="#/deal/{{deal.ref}}">{{deal.ref}}</a></td>
|
||||||
<td class="single line">{{renderX500Name(deal.fixedLeg.fixedRatePayer)}}</td>
|
<td class="single line">{{renderX500Name(deal.fixedLeg.fixedRatePayer)}}</td>
|
||||||
<td class="single line">{{deal.fixedLeg.notional.quantity | number}} {{deal.fixedLeg.notional.token}}</td>
|
<td class="single line">{{deal.fixedLeg.notional}}</td>
|
||||||
<td class="single line">{{renderX500Name(deal.floatingLeg.floatingRatePayer)}}</td>
|
<td class="single line">{{renderX500Name(deal.floatingLeg.floatingRatePayer)}}</td>
|
||||||
<td class="single line">{{deal.floatingLeg.notional.quantity | number}} {{deal.floatingLeg.notional.token}}</td>
|
<td class="single line">{{deal.floatingLeg.notional}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user