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:
Michele Sollecito 2017-09-13 09:42:16 +01:00 committed by GitHub
parent 8415a01a47
commit 15aa4036b6
9 changed files with 51 additions and 17 deletions

View File

@ -129,6 +129,11 @@ UNRELEASED
* 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
------------

View File

@ -1,6 +1,15 @@
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.core.contracts.UniqueIdentifier
import net.corda.core.messaging.vaultTrackBy
import net.corda.core.node.services.ServiceInfo
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 mapper = net.corda.client.jackson.JacksonSupport.createDefaultMapper(it.first.rpc)
registerFinanceJSONMappers(mapper)
registerIRSModule(mapper)
HttpApi.fromHostAndPort(it.second, "api/irs", mapper = mapper)
}
val nextFixingDates = getFixingDateObservable(nodeA.configuration)
@ -133,7 +143,30 @@ class IRSDemoTest : IntegrationTestCategory {
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)
}
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}")
}
}
}
}

View File

@ -597,7 +597,7 @@ class InterestRateSwap : Contract {
/**
* The state class contains the 4 major data classes.
*/
@JsonIgnoreProperties("parties", "participants", ignoreUnknown = true)
@JsonIgnoreProperties(ignoreUnknown = true)
data class State(
val fixedLeg: FixedLeg,
val floatingLeg: FloatingLeg,

View File

@ -37,7 +37,7 @@ define(['viewmodel/FixedRate'], (fixedRateViewModel) => {
_.assign(fixedLeg.fixedRate, fixedRateViewModel);
fixedLeg.fixedRate = Number(fixedLeg.fixedRate) / 100;
fixedLeg.notional.token = common.baseCurrency;
fixedLeg.notional = fixedLeg.notional + ' ' + common.baseCurrency;
fixedLeg.effectiveDate = formatDateForNode(common.effectiveDate);
fixedLeg.terminationDate = formatDateForNode(common.terminationDate);
fixedLeg.fixedRate = { ratioUnit: { value: fixedLeg.fixedRate } };
@ -46,7 +46,7 @@ define(['viewmodel/FixedRate'], (fixedRateViewModel) => {
fixedLeg.paymentCalendar = calendarLookup[common.baseCurrency];
delete fixedLeg.dayCountBasis;
floatingLeg.notional.token = common.baseCurrency;
floatingLeg.notional = floatingLeg.notional + ' ' + common.baseCurrency;
floatingLeg.effectiveDate = formatDateForNode(common.effectiveDate);
floatingLeg.terminationDate = formatDateForNode(common.terminationDate);
floatingLeg.dayCountBasisDay = floatingLeg.dayCountBasis.day;

View File

@ -3,9 +3,7 @@
define(['utils/dayCountBasisLookup'], (dayCountBasisLookup) => {
return {
fixedRatePayer: "O=Bank A,L=London,C=GB",
notional: {
quantity: 2500000000
},
notional: 2500000000,
paymentFrequency: "SemiAnnual",
effectiveDateAdjustment: null,
terminationDateAdjustment: null,

View File

@ -3,9 +3,7 @@
define(['utils/dayCountBasisLookup'], (dayCountBasisLookup) => {
return {
floatingRatePayer: "O=Bank B,L=New York,C=US",
notional: {
quantity: 2500000000
},
notional: 2500000000,
paymentFrequency: "Quarterly",
effectiveDateAdjustment: null,
terminationDateAdjustment: null,

View File

@ -39,7 +39,7 @@
</div>
<div class="field">
<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 class="field">
<label>Fixed Rate</label>
@ -99,7 +99,7 @@
</div>
<div class="field">
<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 class="field">
<label>Payment Frequency</label>

View File

@ -13,7 +13,7 @@
<tr class="center aligned">
<td>Parties</td>
<td>
<span ng-repeat="party in deal.parties">
<span ng-repeat="party in deal.participants">
{{party}}<span ng-show="!$last">,</span>
</span>
</td>
@ -55,7 +55,7 @@
</tr>
<tr class="center aligned">
<td>Notional</td>
<td>{{deal.fixedLeg.notional.quantity | number}} {{deal.fixedLeg.notional.token}}</td>
<td>{{deal.fixedLeg.notional}}</td>
</tr>
<tr class="center aligned">
<td>Payment Frequency</td>
@ -124,7 +124,7 @@
</tr>
<tr class="center aligned">
<td>Notional</td>
<td>{{deal.floatingLeg.notional.quantity | number}} {{deal.floatingLeg.notional.token}}</td>
<td>{{deal.floatingLeg.notional}}</td>
</tr>
<tr class="center aligned">
<td>Payment Frequency</td>

View File

@ -48,9 +48,9 @@
<tr class="center aligned" ng-repeat="deal in deals">
<td><a href="#/deal/{{deal.ref}}">{{deal.ref}}</a></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">{{deal.floatingLeg.notional.quantity | number}} {{deal.floatingLeg.notional.token}}</td>
<td class="single line">{{deal.floatingLeg.notional}}</td>
</tr>
</tbody>
</table>