Skip to content

Commit

Permalink
#862 Added ability to edit baskets join service.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisjstevo committed Nov 5, 2023
1 parent e39dc90 commit 9c41539
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 376 deletions.
354 changes: 5 additions & 349 deletions vuu-ui/packages/vuu-data/src/inlined-worker.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions vuu/src/main/resources/logback-socket.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
<appender-ref ref="server-inout"/>
</logger>

<!--logger name = "org.finos.vuu.viewport" level="DEBUG">
<appender-ref ref="STDOUT"/>
</logger-->

<logger name="org.finos.vuu.net.DefaultMessageHandler" level="DEBUG">
<appender-ref ref="server-inout"/>
<totalSizeCap>20MB</totalSizeCap>
Expand Down
2 changes: 1 addition & 1 deletion vuu/src/main/resources/runconfigurations/SimulMain.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<option name="MAIN_CLASS_NAME" value="org.finos.vuu.SimulMain" />
<module name="vuu" />
<option name="PROGRAM_PARAMETERS" value="-Xmx20G -Xlog:gc*=debug:stdout " />
<option name="VM_PARAMETERS" value="-Dlogback.configurationFile=logback-socket.xml" />
<option name="VM_PARAMETERS" value="-Dlogback.configurationFile=logback.xml" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.finos.vuu.*" />
Expand Down
36 changes: 25 additions & 11 deletions vuu/src/main/scala/org/finos/vuu/core/module/ModuleFactory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,35 +47,42 @@ case class ModuleFactoryNode protected(tableDefs: TableDefs,
vsName: String, staticServedResources: List[StaticServedResource],
rest: List[VuuServer => RestService],
viewPortDefs: Map[String, (DataTable, Provider, ProviderContainer, TableContainer) => ViewPortDef],
tableDefContainer: TableDefContainer = new TableDefContainer(Map())) {
tableDefContainer: TableDefContainer = new TableDefContainer(Map()),
var unrealizedViewPortDefs: Map[TableDefContainer => JoinTableDef, (DataTable, Provider, ProviderContainer, TableContainer) => ViewPortDef]
) {

def addTable(tableDef: TableDef, func: (DataTable, VuuServer) => Provider): ModuleFactoryNode = {
val noViewPortDefFunc = (dt: DataTable, prov: Provider, providerContainer: ProviderContainer, tableContainer: TableContainer) => NoViewPortDef
ModuleFactoryNode(tableDefs.add(tableDef, func), rpc, vsName, staticServedResources, rest, viewPortDefs ++ Map(tableDef.name -> noViewPortDefFunc), tableDefContainer)
ModuleFactoryNode(tableDefs.add(tableDef, func), rpc, vsName, staticServedResources, rest, viewPortDefs ++ Map(tableDef.name -> noViewPortDefFunc), tableDefContainer, unrealizedViewPortDefs)
}

def addTable(tableDef: TableDef, func: (DataTable, VuuServer) => Provider, func2: (DataTable, Provider, ProviderContainer, TableContainer) => ViewPortDef): ModuleFactoryNode = {
ModuleFactoryNode(tableDefs.add(tableDef, func), rpc, vsName, staticServedResources, rest, viewPortDefs ++ Map(tableDef.name -> func2), tableDefContainer)
ModuleFactoryNode(tableDefs.add(tableDef, func), rpc, vsName, staticServedResources, rest, viewPortDefs ++ Map(tableDef.name -> func2), tableDefContainer, unrealizedViewPortDefs)
}

def addSessionTable(tableDef: TableDef, func2: (DataTable, Provider, ProviderContainer, TableContainer) => ViewPortDef): ModuleFactoryNode = {
ModuleFactoryNode(tableDefs.add(tableDef, (dt, vs) => NullProvider), rpc, vsName, staticServedResources, rest, viewPortDefs ++ Map(tableDef.name -> func2), tableDefContainer)
ModuleFactoryNode(tableDefs.add(tableDef, (dt, vs) => NullProvider), rpc, vsName, staticServedResources, rest, viewPortDefs ++ Map(tableDef.name -> func2), tableDefContainer, unrealizedViewPortDefs)
}

def addSessionTable(tableDef: TableDef): ModuleFactoryNode = {
ModuleFactoryNode(tableDefs.add(tableDef, (dt, vs) => NullProvider), rpc, vsName, staticServedResources, rest, viewPortDefs, tableDefContainer)
ModuleFactoryNode(tableDefs.add(tableDef, (dt, vs) => NullProvider), rpc, vsName, staticServedResources, rest, viewPortDefs, tableDefContainer, unrealizedViewPortDefs)
}

def addJoinTable(func: TableDefContainer => JoinTableDef): ModuleFactoryNode = {
ModuleFactoryNode(tableDefs.addJoin(func), rpc, vsName, staticServedResources, rest, viewPortDefs, tableDefContainer)
ModuleFactoryNode(tableDefs.addJoin(func), rpc, vsName, staticServedResources, rest, viewPortDefs, tableDefContainer, unrealizedViewPortDefs)
}

def addJoinTable(func: TableDefContainer => JoinTableDef, func2: (DataTable, Provider, ProviderContainer, TableContainer) => ViewPortDef): ModuleFactoryNode = {
unrealizedViewPortDefs = unrealizedViewPortDefs ++ Map(func -> func2)
ModuleFactoryNode(tableDefs.addJoin(func), rpc, vsName, staticServedResources, rest, viewPortDefs, tableDefContainer, unrealizedViewPortDefs)
}

def addRpcHandler(rpcFunc: VuuServer => RpcHandler): ModuleFactoryNode = {
ModuleFactoryNode(tableDefs, rpc ++ List(rpcFunc), vsName, staticServedResources, rest, viewPortDefs, tableDefContainer)
ModuleFactoryNode(tableDefs, rpc ++ List(rpcFunc), vsName, staticServedResources, rest, viewPortDefs, tableDefContainer, unrealizedViewPortDefs)
}

def addRestService(restFunc: VuuServer => RestService): ModuleFactoryNode = {
ModuleFactoryNode(tableDefs, rpc, vsName, staticServedResources, rest ++ List(restFunc), viewPortDefs, tableDefContainer)
ModuleFactoryNode(tableDefs, rpc, vsName, staticServedResources, rest ++ List(restFunc), viewPortDefs, tableDefContainer, unrealizedViewPortDefs)
}

/**
Expand All @@ -86,7 +93,7 @@ case class ModuleFactoryNode protected(tableDefs: TableDefs,
* @param canBrowse can users browse the contents of the directory (listings)
*/
def addStaticResource(uriDirectory: String, path: Path, canBrowse: Boolean): ModuleFactoryNode = {
ModuleFactoryNode(tableDefs, rpc, vsName, staticServedResources ++ List(StaticServedResource(uriDirectory, path, canBrowse)), rest, viewPortDefs, tableDefContainer)
ModuleFactoryNode(tableDefs, rpc, vsName, staticServedResources ++ List(StaticServedResource(uriDirectory, path, canBrowse)), rest, viewPortDefs, tableDefContainer, unrealizedViewPortDefs)
}

def asModule(): ViewServerModule = {
Expand All @@ -98,9 +105,16 @@ case class ModuleFactoryNode protected(tableDefs: TableDefs,

tableDefContainer.add(this.vsName, mutableTableDefs)

var joinViewPortDefs = Map[String, (DataTable, Provider, ProviderContainer, TableContainer) => ViewPortDef]()

//we do this loop to allow join tables to depend on other realized join tables
tableDefs.joinDefs.foreach(toJTFunc => {
val realizedJoinTableDef = toJTFunc(tableDefContainer)
unrealizedViewPortDefs.get(toJTFunc) match {
case Some(viewPortDef) =>
joinViewPortDefs = joinViewPortDefs ++ Map(realizedJoinTableDef.name -> viewPortDef)
case None =>
}
mutableTableDefs = mutableTableDefs.addRealized(realizedJoinTableDef)
tableDefContainer.add(this.vsName, mutableTableDefs)
})
Expand Down Expand Up @@ -130,7 +144,7 @@ case class ModuleFactoryNode protected(tableDefs: TableDefs,

override def restServicesUnrealized: List[VuuServer => RestService] = rest

override def viewPortDefs: Map[String, (DataTable, Provider, ProviderContainer, TableContainer) => ViewPortDef] = parentRef.viewPortDefs
override def viewPortDefs: Map[String, (DataTable, Provider, ProviderContainer, TableContainer) => ViewPortDef] = parentRef.viewPortDefs ++ joinViewPortDefs
}

}
Expand All @@ -143,7 +157,7 @@ object ModuleFactory {
implicit def stringToString(s: String): FieldDefString = new FieldDefString(s)

def withNamespace(ns: String)(implicit tableDefContainer: TableDefContainer): ModuleFactoryNode = {
ModuleFactoryNode(TableDefs(List(), List(), List()), List(), ns, List(), List(), Map(), tableDefContainer)
ModuleFactoryNode(TableDefs(List(), List(), List()), List(), ns, List(), List(), Map(), tableDefContainer, Map())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.finos.toolbox.lifecycle.LifecycleContainer
import org.finos.toolbox.time.Clock
import org.finos.vuu.api.{JoinSpec, JoinTableDef, JoinTo, LeftOuterJoin, Link, TableDef, ViewPortDef, VisualLinks}
import org.finos.vuu.core.module.basket.provider.{AlgoProvider, BasketConstituentProvider, BasketProvider, NullProvider, PriceStrategyProvider}
import org.finos.vuu.core.module.basket.service.{BasketService, BasketTradingConstituentService}
import org.finos.vuu.core.module.basket.service.{BasketService, BasketTradingConstituentJoinService, BasketTradingConstituentService}
import org.finos.vuu.core.module.price.PriceModule
import org.finos.vuu.core.module.simul.SimulationModule
import org.finos.vuu.core.module.{DefaultModule, ModuleFactory, TableDefContainer, ViewServerModule}
Expand All @@ -14,9 +14,11 @@ object BasketModule extends DefaultModule {

private final val NAME = "BASKET"

final val BasketTable = "basket"
final val BasketTradingTable = "basketTrading"
final val BasketConstituentTable = "basketConstituent"
final val BasketTradingConstituent = "basketTradingConstituent"
final val BasketTradingConstituentJoin = "basketTradingConstituentJoin"

def apply()(implicit clock: Clock, lifecycle: LifecycleContainer, tableDefContainer: TableDefContainer): ViewServerModule = {

Expand All @@ -30,7 +32,7 @@ object BasketModule extends DefaultModule {
.addTable(
//this table should contain one row for each of .FTSE, .DJI, .HSI, .etc...
TableDef(
name = "basket",
name = BasketTable,
keyField = B.Id,
columns = Columns.fromNames(B.Id.string(), B.Name.string(), B.NotionalValue.double(), B.NotionalValueUsd.double()),
VisualLinks(),
Expand Down Expand Up @@ -113,16 +115,21 @@ object BasketModule extends DefaultModule {
)
.addJoinTable(tableDefs =>
JoinTableDef(
name = "basketTrdConsPrices",
name = BasketTradingConstituentJoin,
baseTable = tableDefs.get(NAME, BasketTradingConstituent),
joinColumns = Columns.allFrom(tableDefs.get(NAME, BasketTradingConstituent)) ++ Columns.allFromExcept(tableDefs.get(PriceModule.NAME, "prices"), "ric"),
joins =
JoinTo(
table = tableDefs.get(PriceModule.NAME, "prices"),
joinSpec = JoinSpec(left = "ric", right = "ric", LeftOuterJoin)
),
joinFields = Seq()
))
joinFields = Seq(),
),
(table, _, _, tableContainer) => ViewPortDef(
columns = table.getTableDef.columns,
service = new BasketTradingConstituentJoinService(table, tableContainer)
)
)
.asModule()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@ 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
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.ClientSessionId
import org.finos.vuu.net.{ClientSessionId, RequestContext}
import org.finos.vuu.net.rpc.RpcHandler
import org.finos.vuu.viewport.{NoAction, SelectionViewPortMenuItem, ViewPortAction, ViewPortMenu, ViewPortSelection}

import java.util.concurrent.atomic.AtomicInteger

object BasketService{
val counter = new AtomicInteger(0)
}

class BasketService(val table: DataTable, val tableContainer: TableContainer)(implicit clock: Clock) extends RpcHandler with StrictLogging {

private val counter = new AtomicInteger(0)
//private val counter = new AtomicInteger(0)

import org.finos.vuu.core.module.basket.BasketModule.{BasketTradingColumnNames => BT}
import org.finos.vuu.core.module.basket.BasketModule.{BasketConstituentColumnNames => BC}
Expand Down Expand Up @@ -43,29 +48,38 @@ class BasketService(val table: DataTable, val tableContainer: TableContainer)(im
RowWithData(instanceKey, Map(BT.InstanceId -> instanceKey, BT.Status -> "OFF-MARKET", BT.BasketId -> basketKey))
}

def createBasketFromRpc(basketKey: String, name: String)(ctx: RequestContext): ViewPortAction = {
createBasket(basketKey, name)
}

def createBasket(selection: ViewPortSelection, session: ClientSessionId): ViewPortAction = {

val basketKey = selection.rowKeyIndex.map({ case (key, _) => key }).toList.head

val instanceKey = getAndPadCounter(session)

createBasket(basketKey, instanceKey)
}

private def createBasket(basketKey: String, name: String): ViewPortAction = {

val constituents = getConstituentsForBasketKey(basketKey)

tableContainer.getTable(BasketModule.BasketTradingTable) match {
case table: DataTable =>
table.processUpdate(instanceKey, mkTradingBasketRow(instanceKey, basketKey), clock.now())
table.processUpdate(name, mkTradingBasketRow(name, basketKey), clock.now())
case null =>
logger.error("Cannot find the Basket Trading table.")
}

tableContainer.getTable(BasketModule.BasketTradingConstituent) match {
case table: DataTable =>
constituents.foreach( rowData => {
val constituentKey = instanceKey + "." + rowData.get(BTC.Ric)
val constituentKey = name + "." + rowData.get(BTC.Ric)
val weighting = rowData.get(BTC.Weighting).asInstanceOf[Double]
val quantity = (weighting * 100).asInstanceOf[Long]
val side = rowData.get(BTC.Side).toString
table.processUpdate(constituentKey, mkTradingConstituentRow(side, basketKey, instanceKey, constituentKey, quantity, rowData), clock.now())
table.processUpdate(constituentKey, mkTradingConstituentRow(side, basketKey, name, constituentKey, quantity, rowData), clock.now())
})
case null =>
logger.error("Cannot find the Basket Trading Constituent.")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package org.finos.vuu.core.module.basket.service

import com.typesafe.scalalogging.StrictLogging
import org.finos.toolbox.time.Clock
import org.finos.vuu.api.JoinTableDef
import org.finos.vuu.core.module.basket.BasketModule.BasketTradingConstituentColumnNames.InstanceIdRic
import org.finos.vuu.core.table.{DataTable, JoinTable, RowWithData, TableContainer}
import org.finos.vuu.net.ClientSessionId
import org.finos.vuu.net.rpc.{EditRpcHandler, RpcHandler}
import org.finos.vuu.viewport._

class BasketTradingConstituentJoinService(val table: DataTable, val tableContainer: TableContainer)(implicit clock: Clock) extends RpcHandler with EditRpcHandler with StrictLogging {

def onDeleteRow(key: String, vp: ViewPort, session: ClientSessionId): ViewPortEditAction = {
ViewPortEditSuccess()
}

def onDeleteCell(key: String, column: String, vp: ViewPort, session: ClientSessionId): ViewPortEditAction = {
ViewPortEditSuccess()
}

def onAddRow(key: String, data: Map[String, Any], vp: ViewPort, session: ClientSessionId): ViewPortEditAction = {
ViewPortEditSuccess()
}

private def onEditCell(key: String, columnName: String, data: Any, vp: ViewPort, session: ClientSessionId): ViewPortEditAction = {
val joinTable = vp.table.asTable.asInstanceOf[JoinTable]
val baseTableDef = joinTable.getTableDef.asInstanceOf[JoinTableDef].baseTable
joinTable.sourceTables.get(baseTableDef.name) match {
case Some(table: DataTable) =>
table.processUpdate(key, RowWithData(key, Map(InstanceIdRic -> key, columnName -> data)), clock.now())
ViewPortEditSuccess()
case None =>
ViewPortEditFailure("Could not find base table")
}
}

private def onEditRow(key: String, row: Map[String, Any], vp: ViewPort, session: ClientSessionId): ViewPortEditAction = {
val table = vp.table.asTable
table.processUpdate(key, RowWithData(key, row), clock.now())
ViewPortEditSuccess()
}

private def onFormSubmit(vp: ViewPort, session: ClientSessionId): ViewPortAction = {
// val table = vp.table.asTable
// val primaryKeys = table.primaryKeys
// val headKey = primaryKeys.head
// val sequencerNumber = table.pullRow(headKey).get("sequenceNumber").asInstanceOf[Int].toLong
//
// if (sequencerNumber > 0) {
// logger.info("I would now send this fix seq to a fix engine to reset, we're all good:" + sequencerNumber)
// CloseDialogViewPortAction(vp.id)
// } else {
// logger.error("Seq number not set, returning error")
// ViewPortEditFailure("Sequencer number has not been set.")
// }
CloseDialogViewPortAction(vp.id)
}

private def onFormClose(vp: ViewPort, session: ClientSessionId): ViewPortAction = {
CloseDialogViewPortAction(vp.id)
}


override def deleteRowAction(): ViewPortDeleteRowAction = ViewPortDeleteRowAction("", this.onDeleteRow)

override def deleteCellAction(): ViewPortDeleteCellAction = ViewPortDeleteCellAction("", this.onDeleteCell)

override def addRowAction(): ViewPortAddRowAction = ViewPortAddRowAction("", this.onAddRow)

override def editCellAction(): ViewPortEditCellAction = ViewPortEditCellAction("", this.onEditCell)

override def editRowAction(): ViewPortEditRowAction = ViewPortEditRowAction("", this.onEditRow)

override def onFormSubmit(): ViewPortFormSubmitAction = ViewPortFormSubmitAction("", this.onFormSubmit)

override def onFormClose(): ViewPortFormCloseAction = ViewPortFormCloseAction("", this.onFormClose)

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.finos.vuu.core.module.basket.service

import com.typesafe.scalalogging.StrictLogging
import org.finos.toolbox.time.Clock
import org.finos.vuu.core.module.basket.BasketModule.BasketTradingConstituentColumnNames.InstanceIdRic
import org.finos.vuu.core.table.{DataTable, RowWithData, TableContainer}
import org.finos.vuu.net.ClientSessionId
import org.finos.vuu.net.rpc.{EditRpcHandler, RpcHandler}
Expand All @@ -23,7 +24,7 @@ class BasketTradingConstituentService(val table: DataTable, val tableContainer:

private def onEditCell(key: String, columnName: String, data: Any, vp: ViewPort, session: ClientSessionId): ViewPortEditAction = {
val table = vp.table.asTable
table.processUpdate(key, RowWithData(key, Map(columnName -> data)), clock.now())
table.processUpdate(key, RowWithData(key, Map(InstanceIdRic -> key, columnName -> data)), clock.now())
ViewPortEditSuccess()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,6 @@ class VuuJoinTableProvider(implicit timeProvider: Clock, lifecycle: LifecycleCon

def eventToKey(tableName: String, ev: util.HashMap[String, Any]): String = {
val keyField = sourceTableDefsByName.get(tableName).keyField
if(keyField == null)
println("here")

ev.get(keyField).toString
}

Expand Down Expand Up @@ -214,7 +211,7 @@ class VuuJoinTableProvider(implicit timeProvider: Clock, lifecycle: LifecycleCon

//for each key in left table, send left update, including additional keys
leftKeys.foreach(key => {
logger.debug(s"Publishing update for left key: ${key}")
logger.debug(s"Publishing update for left key: $key")
publishUpdateForLeftTableAndKey(joinTableDef, joinTable.asInstanceOf[JoinTable], joinTableDef.baseTable.name, key, joinSink.getEventDataSink(joinTableDef.baseTable.name).getEventState(key))
})
}
Expand Down

0 comments on commit 9c41539

Please sign in to comment.