Skip to content

Commit 508676f

Browse files
chrisjstevochris
andauthored
#1213 added example of rowbuilder interface (#1214)
* #1213 added example of rowbuilder interface * #1213 Added extra functionality to row builder * #1213 resolved issue with fake table * #1213 resolved issue with fake table * #1213 resolved issue with InstrumentsProviderTest failing due to interface change. * #1213 Updated EasyCLA --------- Co-authored-by: chris <chris.stevenson@fake.com>
1 parent 4236412 commit 508676f

16 files changed

Lines changed: 298 additions & 49 deletions

File tree

example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketConstituentProvider.scala

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import org.finos.toolbox.lifecycle.LifecycleContainer
44
import org.finos.toolbox.thread.RunOnceLifeCycleRunner
55
import org.finos.toolbox.time.Clock
66
import org.finos.vuu.core.module.basket.BasketConstants
7+
import org.finos.vuu.core.module.basket.BasketModule.BasketConstituentColumnNames.{BasketId, Change, Description, LastTrade, Ric, RicBasketId, Side, Volume, Weighting}
78
import org.finos.vuu.core.module.basket.csv.BasketLoader
89
import org.finos.vuu.core.table.{DataTable, RowWithData}
910
import org.finos.vuu.provider.DefaultProvider
@@ -13,6 +14,16 @@ class BasketConstituentProvider(val table: DataTable)(implicit lifecycle: Lifecy
1314
private val runner = new RunOnceLifeCycleRunner("BasketConstituentProvider", runOnce)
1415
private val basketLoader = new BasketLoader()
1516

17+
private val ricCol = table.getTableDef.columnForName(Ric)
18+
private val basketIdCol = table.getTableDef.columnForName(BasketId)
19+
private val ricBasketIdCol = table.getTableDef.columnForName(RicBasketId)
20+
private val lastTradeCol = table.getTableDef.columnForName(LastTrade)
21+
private val changeCol = table.getTableDef.columnForName(Change)
22+
private val weightingCol = table.getTableDef.columnForName(Weighting)
23+
private val volumeCol = table.getTableDef.columnForName(Volume)
24+
private val sideCol = table.getTableDef.columnForName(Side)
25+
private val descCol = table.getTableDef.columnForName(Description)
26+
1627
lifecycle(this).dependsOn(runner)
1728

1829
import org.finos.vuu.core.module.basket.BasketModule.BasketConstituentColumnNames._
@@ -23,10 +34,13 @@ class BasketConstituentProvider(val table: DataTable)(implicit lifecycle: Lifecy
2334
}
2435

2536
def updateBasketConstituents(basketId: String): Unit = {
37+
2638
val list = basketLoader.loadConstituents(basketId)
39+
2740
list.foreach(row => {
2841

2942
if (row.nonEmpty) {
43+
3044
val symbol = row("Symbol").asInstanceOf[String]
3145
val name = row("Name")
3246
val lastTrade = row("Last Trade")
@@ -35,17 +49,20 @@ class BasketConstituentProvider(val table: DataTable)(implicit lifecycle: Lifecy
3549
val weighting = row("Weighting")
3650
val side = BasketConstants.Side.Buy
3751
val ricBasketId = symbol + "." + basketId
38-
table.processUpdate(ricBasketId, RowWithData(ricBasketId, Map(
39-
Ric -> symbol,
40-
BasketId -> basketId,
41-
RicBasketId -> ricBasketId,
42-
LastTrade -> lastTrade,
43-
Change -> change,
44-
Weighting -> weighting,
45-
Volume -> volume,
46-
Description -> name,
47-
Side -> side
48-
)), clock.now())
52+
53+
val rowData = table.newRow(ricBasketId)
54+
.setString(ricCol, symbol)
55+
.setString(basketIdCol, basketId)
56+
.setString(ricBasketIdCol, ricBasketId)
57+
.setString(lastTradeCol, Option(lastTrade).getOrElse("").toString)
58+
.setString(changeCol, Option(change).getOrElse("").toString)
59+
.setDouble(weightingCol, weighting.asInstanceOf[Double])
60+
.setString(volumeCol, Option(volume).getOrElse("").toString)
61+
.setString(descCol, name.toString)
62+
.setString(sideCol, side)
63+
.asRow
64+
65+
table.processUpdate(rowData, clock.now())
4966
}
5067
})
5168

example/basket/src/main/scala/org/finos/vuu/core/module/basket/provider/BasketProvider.scala

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@ class BasketProvider(val table: DataTable)(implicit lifecycle: LifecycleContaine
1313
private val runner = new RunOnceLifeCycleRunner("BasketProvider", runOnce)
1414
private val basketLoader = new BasketLoader()
1515

16+
private val idColumn = table.columnForName(Id)
17+
private val nameColumn = table.columnForName(Name)
18+
1619
lifecycle(this).dependsOn(runner)
1720
def runOnce(): Unit = {
1821
val data = basketLoader.loadBasketIds()
1922

23+
//reuse of the builder...
24+
val builder = table.rowBuilder
25+
2026
data.foreach(id => {
21-
table.processUpdate(id, RowWithData(id, Map(
22-
Id -> id,
23-
Name -> id
24-
)), clock.now())
27+
table.processUpdate(id,
28+
builder.setKey(id)
29+
.setString(idColumn, id)
30+
.setString(nameColumn, id)
31+
//as row clears out the data from the builder
32+
.asRow,
33+
clock.now())
2534
})
2635
}
2736
override val lifecycleId: String = "org.finos.vuu.core.module.basket.provider.BasketProvider"

example/rest-api/src/test/scala/org/finos/vuu/example/rest/provider/InstrumentsProviderTest.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.finos.vuu.example.rest.provider
22

33
import org.finos.toolbox.json.JsonUtil
4-
import org.finos.vuu.core.table.{Columns, DataTable, RowWithData}
4+
import org.finos.vuu.core.table.{Columns, DataTable, RowData, RowWithData}
55
import org.finos.toolbox.time.{Clock, TestFriendlyClock}
66
import org.finos.vuu.api.TableDef
77
import org.finos.vuu.core.module.ModuleFactory.stringToString
@@ -29,7 +29,7 @@ class InstrumentsProviderTest extends AnyFeatureSpec with Matchers with MockFact
2929

3030
getInstrumentsProvider(mockBackend).doStart()
3131

32-
(mockTable.processUpdate _).verify(expectedRow.get(KEY_FIELD).toString, expectedRow, *).once
32+
(mockTable.processUpdate(_: String, _: RowData, _ : Long) ).verify(expectedRow.get(KEY_FIELD).toString, expectedRow, *).once
3333
}
3434

3535
Scenario("can correctly make an external call, parse response and update the table WHEN server responds with multiple instruments") {
@@ -41,24 +41,25 @@ class InstrumentsProviderTest extends AnyFeatureSpec with Matchers with MockFact
4141

4242
getInstrumentsProvider(mockBackend).doStart()
4343

44-
expectedRows.foreach(row => (mockTable.processUpdate _).verify(row.get(KEY_FIELD).toString, row, *).once)
44+
expectedRows.foreach(row => (mockTable.processUpdate(_: String, _: RowData, _ : Long) ).verify(row.get(KEY_FIELD).toString, row, *).once)
4545
}
4646

47+
4748
Scenario("skips updating table when response is not parsable") {
4849
val mockClientResponse = "Some body"
4950
val mockBackend = SyncBackendStub.whenAnyRequest.thenRespond(mockClientResponse)
5051

5152
getInstrumentsProvider(mockBackend).doStart()
5253

53-
(mockTable.processUpdate _).verify(*, *, *).never
54+
(mockTable.processUpdate(_: String, _: RowData, _ : Long) ).verify(*, *, *).never
5455
}
5556

5657
Scenario("skips updating table when response errors") {
5758
val mockBackend = SyncBackendStub.whenAnyRequest.thenRespond(throw new Exception("Some error"))
5859

5960
getInstrumentsProvider(mockBackend).doStart()
6061

61-
(mockTable.processUpdate _).verify(*, *, *).never
62+
(mockTable.processUpdate(_: String, _: RowData, _ : Long) ).verify(*, *, *).never
6263
}
6364
}
6465

plugin/virtualized-table-plugin/src/main/scala/org/finos/vuu/plugin/virtualized/table/VirtualizedSessionTable.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import com.typesafe.scalalogging.StrictLogging
44
import org.finos.toolbox.jmx.MetricsProvider
55
import org.finos.toolbox.time.Clock
66
import org.finos.vuu.api.SessionTableDef
7-
import org.finos.vuu.core.table.{ColumnValueProvider, InMemSessionDataTable, RowWithData, TableData, TablePrimaryKeys}
7+
import org.finos.vuu.core.table.{ColumnValueProvider, InMemSessionDataTable, RowData, RowWithData, TableData, TablePrimaryKeys}
88
import org.finos.vuu.net.ClientSessionId
99
import org.finos.vuu.provider.{JoinTableProvider, VirtualizedProvider}
1010

@@ -17,7 +17,7 @@ class VirtualizedSessionTable(clientSessionId: ClientSessionId,
1717
@volatile private var dataSetSize: Int = 0
1818
@volatile private var range = VirtualizedRange(0, 0)
1919

20-
override def toString: String = s"VirtualizedSessionTable(tableDef=${sessionTableDef.name}, name=${name})"
20+
override def toString: String = s"VirtualizedSessionTable(tableDef=${sessionTableDef.name}, name=$name)"
2121

2222
override def primaryKeys: TablePrimaryKeys = super.primaryKeys
2323

@@ -55,7 +55,7 @@ class VirtualizedSessionTable(clientSessionId: ClientSessionId,
5555
logger.error("Trying to set range on non-virtualized data, something has gone bad.")
5656
}
5757
}
58-
override def processUpdate(rowKey: String, rowData: RowWithData, timeStamp: Long): Unit = super.processUpdate(rowKey, rowData, timeStamp)
58+
override def processUpdate(rowKey: String, rowData: RowData, timeStamp: Long): Unit = super.processUpdate(rowKey, rowData, timeStamp)
5959

6060
override def processDelete(rowKey: String): Unit = super.processDelete(rowKey)
6161

plugin/virtualized-table-plugin/src/main/scala/org/finos/vuu/plugin/virtualized/table/VirtualizedSessionTableData.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class VirtualizedSessionTableData(cacheSize: Int)(implicit clock: Clock) extends
1818
}
1919
}
2020

21-
override def update(key: String, update: RowWithData): TableData = {
21+
override def update(key: String, update: RowData): TableData = {
2222
rowCache.put(key, update)
2323
this
2424
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.finos.vuu.core.row
2+
import org.finos.vuu.core.table.{Column, RowData, RowWithData}
3+
4+
import scala.collection.mutable
5+
6+
class InMemMapRowBuilder extends RowBuilder {
7+
8+
private val mutableMap = new mutable.HashMap[String, Any]()
9+
private var key: String = null
10+
override def setLong(column: Column, v: Long): RowBuilder = {
11+
mutableMap.put(column.name, v)
12+
this
13+
}
14+
15+
override def setDouble(column: Column, v: Double): RowBuilder = {
16+
mutableMap.put(column.name, v)
17+
this
18+
}
19+
20+
override def setInt(column: Column, v: Int): RowBuilder = {
21+
mutableMap.put(column.name, v)
22+
this
23+
}
24+
25+
override def setString(column: Column, v: String): RowBuilder = {
26+
mutableMap.put(column.name, v)
27+
this
28+
}
29+
30+
override def setBoolean(column: Column, v: Boolean): RowBuilder = {
31+
mutableMap.put(column.name, v)
32+
this
33+
}
34+
override def setKey(key: String): RowBuilder = {
35+
this.key = key
36+
this
37+
}
38+
override def asRow: RowData = {
39+
if(key == null){
40+
throw new RuntimeException("Key has not been set, this is likely a coding error.")
41+
}
42+
val immMap = mutableMap.toMap
43+
val rowData = RowWithData(key, immMap)
44+
mutableMap.clear()
45+
key = null
46+
rowData
47+
}
48+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.finos.vuu.core.row
2+
3+
import org.finos.vuu.core.table.{Column, RowData}
4+
5+
trait RowBuilder {
6+
def setKey(key: String): RowBuilder
7+
def setLong(column: Column, v: Long): RowBuilder
8+
def setDouble(column: Column, v: Double): RowBuilder
9+
def setInt(column: Column, v: Int): RowBuilder
10+
def setString(column: Column, v: String): RowBuilder
11+
def setBoolean(column: Column, v: Boolean): RowBuilder
12+
/**
13+
* this metyhod effectively resets the builder, emptying its existing contents to begin again.
14+
* @return row with data set
15+
*/
16+
def asRow: RowData
17+
}
18+
19+
object NoRowBuilder extends RowBuilder{
20+
override def setKey(key: String): RowBuilder = ???
21+
override def setLong(column: Column, v: Long): RowBuilder = ???
22+
override def setDouble(column: Column, v: Double): RowBuilder = ???
23+
override def setInt(column: Column, v: Int): RowBuilder = ???
24+
override def setString(column: Column, v: String): RowBuilder = ???
25+
override def setBoolean(column: Column, v: Boolean): RowBuilder = ???
26+
/**
27+
* this metyhod effectively resets the builder, emptying its existing contents to begin again.
28+
*
29+
* @return row with data set
30+
*/
31+
override def asRow: RowData = ???
32+
}

vuu/src/main/scala/org/finos/vuu/core/table/AutoSubscribeTable.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import org.finos.vuu.api.TableDef
55
import org.finos.vuu.provider.JoinTableProvider
66
import io.vertx.core.impl.ConcurrentHashSet
77
import org.finos.toolbox.jmx.MetricsProvider
8+
import org.finos.vuu.core.row.RowBuilder
89

910
class AutoSubscribeTable(tableDef: TableDef, joinProvider: JoinTableProvider)(implicit override val metrics: MetricsProvider) extends InMemDataTable(tableDef, joinProvider) with StrictLogging {
1011

vuu/src/main/scala/org/finos/vuu/core/table/InMemDataTable.scala

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import org.finos.vuu.viewport.{RowProcessor, RowSource, ViewPortColumns}
77
import org.finos.toolbox.collection.array.ImmutableArray
88
import org.finos.toolbox.jmx.MetricsProvider
99
import org.finos.toolbox.text.AsciiUtil
10+
import org.finos.vuu.core.row.{InMemMapRowBuilder, RowBuilder}
1011
import org.finos.vuu.feature.inmem.InMemTablePrimaryKeys
1112

1213
import java.util
@@ -22,6 +23,8 @@ trait DataTable extends KeyedObservable[RowKeyUpdate] with RowSource {
2223

2324
def updateCounter: Long
2425

26+
def newRow(key: String): RowBuilder
27+
def rowBuilder: RowBuilder
2528
def incrementUpdateCounter(): Unit
2629

2730
def indexForColumn(column: Column): Option[IndexedField[_]]
@@ -42,7 +45,11 @@ trait DataTable extends KeyedObservable[RowKeyUpdate] with RowSource {
4245

4346
def getTableDef: TableDef
4447

45-
def processUpdate(rowKey: String, rowUpdate: RowWithData, timeStamp: Long): Unit
48+
def processUpdate(rowUpdate: RowData, timeStamp: Long): Unit = {
49+
processUpdate(rowUpdate.key(), rowUpdate, timeStamp)
50+
}
51+
52+
def processUpdate(rowKey: String, rowUpdate: RowData, timeStamp: Long): Unit
4653

4754
def hasRowChanged(row: RowWithData): Boolean = {
4855
val existingRow = this.pullRow(row.key)
@@ -170,10 +177,10 @@ case class InMemDataTableData(data: ConcurrentHashMap[String, RowData], private
170177

171178
//protected def merge(update: RowUpdate, data: RowData): RowData = MergeFunctions.mergeLeftToRight(update, data)
172179

173-
protected def merge(update: RowWithData, data: RowWithData): RowWithData =
180+
protected def merge(update: RowData, data: RowData): RowData =
174181
MergeFunctions.mergeLeftToRight(update, data)
175182

176-
def update(key: String, update: RowWithData): TableData = {
183+
def update(key: String, update: RowData): TableData = {
177184

178185
val table = data.synchronized {
179186

@@ -220,6 +227,11 @@ class InMemDataTable(val tableDef: TableDef, val joinProvider: JoinTableProvider
220227

221228
private final val columnValueProvider = InMemColumnValueProvider(this)
222229

230+
override def newRow(key: String): RowBuilder = {
231+
new InMemMapRowBuilder().setKey(key)
232+
}
233+
override def rowBuilder: RowBuilder = new InMemMapRowBuilder
234+
223235
private def buildIndexForColumn(c: Column): IndexedField[_] = {
224236
c.dataType match {
225237
case DataType.StringDataType =>
@@ -333,7 +345,7 @@ class InMemDataTable(val tableDef: TableDef, val joinProvider: JoinTableProvider
333345
def columns(): Array[Column] = tableDef.columns
334346
lazy val viewPortColumns: ViewPortColumns = ViewPortColumnCreator.create(this, tableDef.columns.map(_.name).toList)
335347

336-
private def updateIndices(rowkey: String, rowUpdate: RowWithData): Unit = {
348+
private def updateIndices(rowkey: String, rowUpdate: RowData): Unit = {
337349
this.indices.foreach(colTup => {
338350
val column = colTup._1
339351
val index = colTup._2
@@ -375,7 +387,7 @@ class InMemDataTable(val tableDef: TableDef, val joinProvider: JoinTableProvider
375387
})
376388
}
377389

378-
def update(rowkey: String, rowUpdate: RowWithData): Unit = {
390+
def update(rowkey: String, rowUpdate: RowData): Unit = {
379391
data = data.update(rowkey, rowUpdate)
380392
updateIndices(rowkey, rowUpdate)
381393
}
@@ -446,7 +458,7 @@ class InMemDataTable(val tableDef: TableDef, val joinProvider: JoinTableProvider
446458
}
447459
}
448460

449-
def processUpdate(rowKey: String, rowData: RowWithData, timeStamp: Long): Unit = {
461+
def processUpdate(rowKey: String, rowData: RowData, timeStamp: Long): Unit = {
450462

451463
onUpdateMeter.mark()
452464

vuu/src/main/scala/org/finos/vuu/core/table/JoinTable.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import org.finos.vuu.provider.JoinTableProvider
77
import org.finos.vuu.viewport.{RowProcessor, ViewPortColumns}
88
import org.finos.toolbox.collection.array.{ImmutableArray, ImmutableArrays}
99
import org.finos.toolbox.jmx.MetricsProvider
10+
import org.finos.vuu.core.row.{NoRowBuilder, RowBuilder}
1011
import org.finos.vuu.feature.inmem.InMemTablePrimaryKeys
1112

1213
import java.util
@@ -104,7 +105,7 @@ case class JoinDataTableData(tableDef: JoinTableDef, var keysByJoinIndex: Array[
104105
map.toMap
105106
}
106107

107-
def rowUpdateToArray(update: RowWithData): Array[Any] = {
108+
def rowUpdateToArray(update: RowData): Array[Any] = {
108109
//val data = columns.map(update.get(_))
109110

110111
var index = 0
@@ -189,7 +190,7 @@ case class JoinDataTableData(tableDef: JoinTableDef, var keysByJoinIndex: Array[
189190
}
190191
}
191192

192-
def processUpdate(rowKey: String, rowUpdate: RowWithData, joinTable: JoinTable, sourceTables: Map[String, DataTable]): JoinDataTableData = {
193+
def processUpdate(rowKey: String, rowUpdate: RowData, joinTable: JoinTable, sourceTables: Map[String, DataTable]): JoinDataTableData = {
193194

194195
val updateByKeyIndex = rowUpdateToArray(rowUpdate)
195196

@@ -347,7 +348,7 @@ class JoinTable(val tableDef: JoinTableDef, val sourceTables: Map[String, DataTa
347348

348349
override def incrementUpdateCounter(): Unit = updateCounterInternal +=1
349350

350-
override def processUpdate(rowKey: String, rowUpdate: RowWithData, timeStamp: Long): Unit = {
351+
override def processUpdate(rowKey: String, rowUpdate: RowData, timeStamp: Long): Unit = {
351352

352353
onUpdateMeter.mark()
353354

@@ -658,4 +659,7 @@ class JoinTable(val tableDef: JoinTableDef, val sourceTables: Map[String, DataTa
658659
}
659660

660661
override def getColumnValueProvider: ColumnValueProvider = InMemColumnValueProvider(this)
662+
override def newRow(key: String): RowBuilder = ???
663+
664+
override def rowBuilder: RowBuilder = NoRowBuilder
661665
}

0 commit comments

Comments
 (0)