diff --git a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketService.scala b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketService.scala index 0f815215a..b720d80ad 100644 --- a/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketService.scala +++ b/example/basket/src/main/scala/org/finos/vuu/core/module/basket/service/BasketService.scala @@ -4,17 +4,22 @@ import com.typesafe.scalalogging.StrictLogging import org.finos.toolbox.time.Clock import org.finos.vuu.core.module.basket.BasketModule import org.finos.vuu.core.module.basket.BasketModule.{BasketConstituentTable, Sides} -import org.finos.vuu.core.module.basket.service.BasketService.counter import org.finos.vuu.core.table.{DataTable, RowData, RowWithData, TableContainer} import org.finos.vuu.net.rpc.RpcHandler import org.finos.vuu.net.{ClientSessionId, RequestContext} import org.finos.vuu.order.oms.OmsApi import org.finos.vuu.viewport._ - import java.util.concurrent.atomic.AtomicInteger -object BasketService{ - val counter = new AtomicInteger(0) +object BasketTradeId { + + private val counter: AtomicInteger = new AtomicInteger(0) + var current:String = "NoneInitalised" //this is for testing but only works if tests that use this doesnt run in parallel + def oneNew(user:String): String = { + val counterValue = counter.incrementAndGet() + current = user + "-" + "".padTo(5 - counterValue.toString.length, "0").mkString + counterValue + current + } } trait BasketServiceIF{ @@ -25,11 +30,6 @@ class BasketService(val table: DataTable, val tableContainer: TableContainer, va import org.finos.vuu.core.module.basket.BasketModule.{BasketConstituentColumnNames => BC, BasketTradingColumnNames => BT, BasketTradingConstituentColumnNames => BTC} - private def getAndPadCounter(session: ClientSessionId): String = { - val counterValue = counter.incrementAndGet() - session.user + "-" + "".padTo(5 - counterValue.toString.length, "0").mkString + counterValue - } - private def getConstituentsForSourceBasket(basketId: String): List[RowData] = { val table = tableContainer.getTable(BasketConstituentTable) val keys = table.primaryKeys.toList @@ -68,13 +68,13 @@ class BasketService(val table: DataTable, val tableContainer: TableContainer, va val basketId = selection.rowKeyIndex.map({ case (key, _) => key }).toList.head - val instanceKey = getAndPadCounter(session) + val instanceKey = BasketTradeId.oneNew(session.user) createBasketInternal(basketId, instanceKey, instanceKey, session) } def createBasket(basketId: String, name: String)(ctx: RequestContext): ViewPortAction = { - val basketTradeId = getAndPadCounter(ctx.session) + val basketTradeId = BasketTradeId.oneNew(ctx.session.user) createBasketInternal(basketId, name, basketTradeId, ctx.session) } diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketCreateTest.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketCreateTest.scala index c0a31d6d2..f847d55e6 100644 --- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketCreateTest.scala +++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketCreateTest.scala @@ -5,7 +5,7 @@ import org.finos.toolbox.lifecycle.LifecycleContainer import org.finos.toolbox.time.{Clock, TestFriendlyClock} import org.finos.vuu.api.ViewPortDef import org.finos.vuu.core.module.TableDefContainer -import org.finos.vuu.core.module.basket.service.{BasketServiceIF, BasketTradingServiceIF} +import org.finos.vuu.core.module.basket.service.{BasketServiceIF, BasketTradeId, BasketTradingServiceIF} import org.finos.vuu.core.module.price.PriceModule import org.finos.vuu.core.table.TableTestHelper.combineQs import org.finos.vuu.order.oms.OmsApi @@ -54,21 +54,21 @@ class BasketCreateTest extends VuuServerTestCase { val basketService = vuuServer.getViewPortRpcServiceProxy[BasketServiceIF](viewportBasket) - val action = basketService.createBasket(".FTSE", "chris-001")(vuuServer.requestContext) + val action = basketService.createBasket(".FTSE", "TestBasket")(vuuServer.requestContext) val viewportBasketTrading = vuuServer.createViewPort(BasketModule.NAME, BasketTradingTable) val basketTradingService = vuuServer.getViewPortRpcServiceProxy[BasketTradingServiceIF](viewportBasketTrading) //CJS: I don't like this forced cast, need to look at that a bit - basketTradingService.editCellAction().func("chris-001", BT.Units, 100.asInstanceOf[Object], viewportBasketTrading, vuuServer.session) + basketTradingService.editCellAction().func(BasketTradeId.current, BT.Units, 100.asInstanceOf[Object], viewportBasketTrading, vuuServer.session) vuuServer.runOnce() assertVpEq(combineQsForVp(viewportBasketTrading)) { Table( ("basketId", "instanceId", "basketName", "units", "status", "filledPct", "totalNotionalUsd", "totalNotional", "fxRateToUsd", "side"), - (".FTSE", "chris-001", "chris-001", 100, "OFF-MARKET", null, null, null, null, "Buy") + (".FTSE", BasketTradeId.current, "TestBasket", 100, "OFF-MARKET", null, null, null, null, "Buy") ) } } diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketMutateOffMarketTest.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketMutateOffMarketTest.scala index c46c500af..8c9489cbd 100644 --- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketMutateOffMarketTest.scala +++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketMutateOffMarketTest.scala @@ -6,7 +6,7 @@ import org.finos.toolbox.time.{Clock, TestFriendlyClock} import org.finos.vuu.api.ViewPortDef import org.finos.vuu.core.module.TableDefContainer import org.finos.vuu.core.module.basket.BasketModule.{BasketColumnNames => B, BasketConstituentColumnNames => BC} -import org.finos.vuu.core.module.basket.service.{BasketServiceIF, BasketTradingServiceIF} +import org.finos.vuu.core.module.basket.service.{BasketServiceIF, BasketTradeId, BasketTradingServiceIF} import org.finos.vuu.core.module.price.PriceModule import org.finos.vuu.order.oms.OmsApi import org.finos.vuu.test.{TestVuuServer, VuuServerTestCase} @@ -69,6 +69,7 @@ class BasketMutateOffMarketTest extends VuuServerTestCase { Then("Get the Basket RPC Service and call create basket") val basketService = vuuServer.getViewPortRpcServiceProxy[BasketServiceIF](vpBasket) basketService.createBasket(".FTSE", "MyCustomBasket")(vuuServer.requestContext) + val basketTradeInstanceId = BasketTradeId.current val vpBasketTrading = vuuServer.createViewPort(BasketModule.NAME, BasketTradingTable) @@ -79,7 +80,7 @@ class BasketMutateOffMarketTest extends VuuServerTestCase { assertVpEq(combineQsForVp(vpBasketTrading)) { Table( ("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"), - ("testUser-00001", ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Buy") + (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Buy") ) } @@ -90,16 +91,16 @@ class BasketMutateOffMarketTest extends VuuServerTestCase { assertVpEq(combineQsForVp(vpBasketTradingCons)) { Table( ("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"), - (10L, "Buy", "testUser-00001", "testUser-00001.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), - (10L, "Sell", "testUser-00001", "testUser-00001.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), - (10L, "Buy", "testUser-00001", "testUser-00001.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING") + (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), + (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), + (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING") ) } val basketTradingService = vuuServer.getViewPortRpcServiceProxy[BasketTradingServiceIF](vpBasketTrading) When("we edit the side of the parent basket") - basketTradingService.editCellAction().func("testUser-00001", "side", "Sell", vpBasketTrading, vuuServer.session) + basketTradingService.editCellAction().func(basketTradeInstanceId, "side", "Sell", vpBasketTrading, vuuServer.session) Then("get all the updates that have occurred for all view ports from the outbound queue") val updates = combineQs(vpBasketTrading) @@ -108,7 +109,7 @@ class BasketMutateOffMarketTest extends VuuServerTestCase { assertVpEq(filterByVp(vpBasketTrading, updates)) { Table( ("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"), - ("testUser-00001", ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Sell") + (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Sell") ) } @@ -117,73 +118,75 @@ class BasketMutateOffMarketTest extends VuuServerTestCase { assertVpEq(filterByVp(vpBasketTradingCons, updates)) { Table( ("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"), - (10L, "Sell", "testUser-00001", "testUser-00001.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), - (10L, "Buy", "testUser-00001", "testUser-00001.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), - (10L, "Sell", "testUser-00001", "testUser-00001.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING") + (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), + (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), + (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING") ) } When("we edit the units of the parent basket") - basketTradingService.editCellAction().func("testUser-00001", "units", 1000L.asInstanceOf[Object], vpBasketTrading, vuuServer.session) + basketTradingService.editCellAction().func(basketTradeInstanceId, "units", 1000L.asInstanceOf[Object], vpBasketTrading, vuuServer.session) And("assert the basket trading constituent table has increased the units") assertVpEq(filterByVp(vpBasketTradingCons, combineQs(vpBasketTrading))) { Table( ("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"), - (100L, "Sell", "testUser-00001", "testUser-00001.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), - (100L, "Buy", "testUser-00001", "testUser-00001.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), - (100L, "Sell", "testUser-00001", "testUser-00001.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING") + (100L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), + (100L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), + (100L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING") ) } } } - //todo this only works if running one test at a time. BasketService singleton object is used to create the basket trade id and doesnt get reset between tests -// Scenario("Check updating trade basket side with no change does not update constituents side") { -// import BasketModule._ -// implicit val clock: Clock = new TestFriendlyClock(10001L) -// implicit val lifecycle: LifecycleContainer = new LifecycleContainer() -// implicit val tableDefContainer: TableDefContainer = new TableDefContainer(Map()) -// implicit val metricsProvider: MetricsProvider = new MetricsProviderImpl -// -// withVuuServer(PriceModule(), BasketModule()) { -// vuuServer => -// -// vuuServer.login("testUser", "testToken2") -// -// GivenBasketTradeExist(vuuServer, ".FTSE", "MyCustomBasket") -// -// val vpBasketTrading = vuuServer.createViewPort(BasketModule.NAME, BasketTradingTable) -// val vpBasketTradingCons = vuuServer.createViewPort(BasketModule.NAME, BasketTradingConstituentTable) -// val basketTradingService = vuuServer.getViewPortRpcServiceProxy[BasketTradingServiceIF](vpBasketTrading) -// -// When("we edit the side of the parent basket to same side as current value") -// basketTradingService.editCellAction().func("testUser-00001", "side", "Buy", vpBasketTrading, vuuServer.session) -// vuuServer.runOnce() -// -// Then("get all the updates that have occurred for all view ports from the outbound queue") -// val updates2 = combineQs(vpBasketTrading) -// -// And("assert the basket trading table has not changed side....") -// assertVpEq(filterByVp(vpBasketTrading, updates2)) { -// Table( -// ("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"), -// ("testUser-00001", ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Buy") -// ) -// } -// -// And("assert the basket trading constituent table has not changed sides") -// assertVpEq(filterByVp(vpBasketTradingCons, updates2)) { -// Table( -// ("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId"), -// (10L, "Buy", "testUser-00001", "testUser-00001.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2), -// (10L, "Sell", "testUser-00001", "testUser-00001.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2), -// (10L, "Buy", "testUser-00001", "testUser-00001.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2) -// ) -// } -// } -// } + Scenario("Check updating trade basket side with no change does not update constituents side") { + import BasketModule._ + implicit val clock: Clock = new TestFriendlyClock(10001L) + implicit val lifecycle: LifecycleContainer = new LifecycleContainer() + implicit val tableDefContainer: TableDefContainer = new TableDefContainer(Map()) + implicit val metricsProvider: MetricsProvider = new MetricsProviderImpl + + val omsApi = OmsApi() + withVuuServer(PriceModule(), BasketModule(omsApi)) { + vuuServer => + + vuuServer.login("testUser", "testToken2") + + GivenBasketTradeExist(vuuServer, ".FTSE", "MyCustomBasket") + val basketTradeInstanceId = BasketTradeId.current + + val vpBasketTrading = vuuServer.createViewPort(BasketModule.NAME, BasketTradingTable) + val vpBasketTradingCons = vuuServer.createViewPort(BasketModule.NAME, BasketTradingConstituentTable) + val basketTradingService = vuuServer.getViewPortRpcServiceProxy[BasketTradingServiceIF](vpBasketTrading) + + When("we edit the side of the parent basket to same side as current value") + basketTradingService.editCellAction().func(basketTradeInstanceId, "side", "Buy", vpBasketTrading, vuuServer.session) + vuuServer.runOnce() + + Then("get all the updates that have occurred for all view ports from the outbound queue") + val updates2 = combineQs(vpBasketTrading) + + And("assert the basket trading table has not changed side....") + assertVpEq(filterByVp(vpBasketTrading, updates2)) { + Table( + ("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"), + (basketTradeInstanceId, ".FTSE", "MyCustomBasket", "OFF-MARKET", 1, null, null, null, null, "Buy") + ) + } + + And("assert the basket trading constituent table has not changed sides") + assertVpEq(filterByVp(vpBasketTradingCons, updates2)) { + Table( + ("quantity", "side", "instanceId", "instanceIdRic", "basketId", "ric", "description", "notionalUsd", "notionalLocal", "venue", "algo", "algoParams", "pctFilled", "weighting", "priceSpread", "limitPrice", "priceStrategyId", "filledQty", "orderStatus"), + (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.BP.L", ".FTSE", "BP.L", "Beyond Petroleum", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), + (10L, "Sell", basketTradeInstanceId, s"$basketTradeInstanceId.BT.L", ".FTSE", "BT.L", "British Telecom", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING"), + (10L, "Buy", basketTradeInstanceId, s"$basketTradeInstanceId.VOD.L", ".FTSE", "VOD.L", "Vodafone", null, null, null, -1, null, null, 0.1, null, null, 2, 0, "PENDING") + ) + } + } + } } + def GivenBasketTradeExist(vuuServer: TestVuuServer, basketId: String, basketTradeName: String): Unit = { val basketProvider = vuuServer.getProvider(BasketModule.NAME, BasketModule.BasketTable) basketProvider.tick(".FTSE", Map(B.Id -> ".FTSE", B.Name -> ".FTSE 100", B.NotionalValue -> 1000001, B.NotionalValueUsd -> 1500001)) diff --git a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketSendToMarketTest.scala b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketSendToMarketTest.scala index 315e5cb88..36fc23848 100644 --- a/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketSendToMarketTest.scala +++ b/example/basket/src/test/scala/org/finos/vuu/core/module/basket/BasketSendToMarketTest.scala @@ -6,7 +6,7 @@ import org.finos.toolbox.time.{Clock, TestFriendlyClock} import org.finos.vuu.api.ViewPortDef import org.finos.vuu.core.module.TableDefContainer import org.finos.vuu.core.module.basket.BasketTestCaseHelper.{tickBasketDef, tickConstituentsDef, tickPrices} -import org.finos.vuu.core.module.basket.service.{BasketServiceIF, BasketTradingServiceIF} +import org.finos.vuu.core.module.basket.service.{BasketServiceIF, BasketTradeId, BasketTradingServiceIF} import org.finos.vuu.core.module.price.PriceModule import org.finos.vuu.order.oms.OmsApi import org.finos.vuu.test.VuuServerTestCase @@ -50,7 +50,8 @@ class BasketSendToMarketTest extends VuuServerTestCase { Then("Get the Basket RPC Service and call create basket") val basketService = vuuServer.getViewPortRpcServiceProxy[BasketServiceIF](vpBasket) - basketService.createBasket(".FTSE", "chris-001")(vuuServer.requestContext) + basketService.createBasket(".FTSE", "TestBasket")(vuuServer.requestContext) + val basketTradeInstanceId = BasketTradeId.current val vpBasketTrading = vuuServer.createViewPort(BasketModule.NAME, BasketTradingTable) @@ -59,7 +60,7 @@ class BasketSendToMarketTest extends VuuServerTestCase { val tradingService = vuuServer.getViewPortRpcServiceProxy[BasketTradingServiceIF](vpBasketTrading) And("send the basket to market") - tradingService.sendToMarket("chris-001")(vuuServer.requestContext) + tradingService.sendToMarket(basketTradeInstanceId)(vuuServer.requestContext) vuuServer.runOnce() @@ -67,7 +68,7 @@ class BasketSendToMarketTest extends VuuServerTestCase { assertVpEq(combineQsForVp(vpBasketTrading)) { Table( ("instanceId", "basketId", "basketName", "status", "units", "filledPct", "fxRateToUsd", "totalNotional", "totalNotionalUsd", "side"), - ("chris-001", ".FTSE", "chris-001", "ON_MARKET", 1, null, null, null, null, "Buy") + (basketTradeInstanceId, ".FTSE", "TestBasket", "ON_MARKET", 1, null, null, null, null, "Buy") ) } }