diff --git a/feature/ignite-feature/pom.xml b/feature/ignite-feature/pom.xml
new file mode 100644
index 000000000..49d6b17d2
--- /dev/null
+++ b/feature/ignite-feature/pom.xml
@@ -0,0 +1,273 @@
+
+
+ 4.0.0
+
+ org.finos.vuu
+ feature
+ 0.9.36-SNAPSHOT
+
+
+
+ ignite-feature
+
+
+
+ org.finos.vuu
+ vuu
+ 0.9.36-SNAPSHOT
+
+
+
+ org.finos.vuu
+ vuu
+ 0.9.36-SNAPSHOT
+ tests
+ test-jar
+ test
+
+
+
+ org.finos.vuu
+ price
+ 0.9.36-SNAPSHOT
+
+
+
+ org.finos.vuu
+ order
+ 0.9.36-SNAPSHOT
+
+
+
+ org.scala-lang
+ scala-library
+ ${scala.version}
+
+
+
+ org.scala-lang
+ scala-reflect
+ ${scala.version}
+
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+
+ org.scalatest
+ scalatest_2.13
+ ${scalatest.version}
+ test
+
+
+ org.scala-lang
+ scala-library
+
+
+ org.scala-lang
+ scala-reflect
+
+
+
+
+
+
+
+
+
+
+ sign-it
+
+
+ sign
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.0.1
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+ --pinentry-mode
+ loopback
+
+
+
+
+
+
+
+
+
+
+ legal-report
+
+
+
+ org.scala-tools
+ maven-scala-plugin
+ ${maven.scala.plugin}
+
+
+ **/*.scala
+
+
+
+
+
+
+
+
+
+ src/main/java
+ src/test/java
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+
+ compile
+
+ jar
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+
+ ${maven.compiler.target}
+
+
+
+ org.ow2.asm
+ asm
+ 6.2
+
+
+
+
+
+
+ org.scala-tools
+ maven-scala-plugin
+ ${maven.scala.plugin}
+
+
+
+ compile
+ testCompile
+
+
+
+
+ src/main/scala
+ src/test/scala
+
+ -Xms64m
+ -Xmx1024m
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.2
+
+
+
+ test-jar
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.7
+
+
+
+
+
+
+ org.scalatest
+ scalatest-maven-plugin
+ 2.0.2
+
+ ${project.build.directory}/surefire-reports
+ .
+ test-reports.txt
+
+
+
+ test
+
+ test
+
+
+
+
+
+
+
+
+
+
+ org.scala-tools
+ maven-scala-plugin
+ ${maven.scala.plugin}
+
+ ${scala.version}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/feature/pom.xml b/feature/pom.xml
new file mode 100644
index 000000000..1f4ce8254
--- /dev/null
+++ b/feature/pom.xml
@@ -0,0 +1,64 @@
+
+
+ 4.0.0
+
+ org.finos.vuu
+ vuu-parent
+ 0.9.36-SNAPSHOT
+
+
+ feature
+ pom
+
+
+ ignite-feature
+
+
+
+
+
+
+
+ sign-it
+
+
+ sign
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.0.1
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+ --pinentry-mode
+ loopback
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/layout-server/pom.xml b/layout-server/pom.xml
index 9ae3cf8e5..c5889bf7d 100644
--- a/layout-server/pom.xml
+++ b/layout-server/pom.xml
@@ -2,12 +2,14 @@
4.0.0
+
org.springframework.boot
spring-boot-starter-parent
2.7.16
+
org.finos.vuu
layout-server
0.0.1-SNAPSHOT
diff --git a/pom.xml b/pom.xml
index 0625fbcf6..e376e2a20 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,9 +82,10 @@
toolbox
vuu
vuu-ui
- layout-server
+
benchmark
example
+ feature
diff --git a/vuu/pom.xml b/vuu/pom.xml
index 847eff9e4..8e15ecb17 100644
--- a/vuu/pom.xml
+++ b/vuu/pom.xml
@@ -24,6 +24,12 @@
0.9.36-SNAPSHOT
+
+
org.apache.lucene
lucene-core
diff --git a/vuu/src/main/scala/org/finos/vuu/api/TableDef.scala b/vuu/src/main/scala/org/finos/vuu/api/TableDef.scala
index c8499db90..2458f1729 100644
--- a/vuu/src/main/scala/org/finos/vuu/api/TableDef.scala
+++ b/vuu/src/main/scala/org/finos/vuu/api/TableDef.scala
@@ -4,6 +4,7 @@ import org.finos.vuu.core.VuuServer
import org.finos.vuu.core.auths.RowPermissionChecker
import org.finos.vuu.core.module.ViewServerModule
import org.finos.vuu.core.table._
+import org.finos.vuu.feature.inmem.VuuInMemPluginLocator
import org.finos.vuu.net.ClientSessionId
import org.finos.vuu.viewport.ViewPort
@@ -105,7 +106,7 @@ case class AvailableViewPortVisualLink(parentVpId: String, link: Link) {
override def toString: String = "(" + parentVpId.split("-").last + ")" + link.fromColumn + " to " + link.toTable + "." + link.toColumn
}
-class JoinSessionTableDef(name: String, baseTable: TableDef, joinColumns: Array[Column], joinFields: Seq[String], joins: JoinTo*) extends JoinTableDef(name, baseTable, joinColumns, joinFields)
+class JoinSessionTableDef(name: String, baseTable: TableDef, joinColumns: Array[Column], joinFields: Seq[String], joins: JoinTo*) extends JoinTableDef(name, baseTable, joinColumns, joinFields) with VuuInMemPluginLocator
class SessionTableDef(name: String,
keyField: String,
@@ -113,7 +114,7 @@ class SessionTableDef(name: String,
joinFields: Seq[String],
autosubscribe: Boolean = false,
links: VisualLinks = VisualLinks(),
- indices: Indices) extends TableDef(name, keyField, columns, joinFields, autosubscribe, links, indices)
+ indices: Indices) extends TableDef(name, keyField, columns, joinFields, autosubscribe, links, indices) with VuuInMemPluginLocator
class TableDef(val name: String,
@@ -122,7 +123,7 @@ class TableDef(val name: String,
val joinFields: Seq[String],
val autosubscribe: Boolean = false,
val links: VisualLinks = VisualLinks(),
- val indices: Indices) {
+ val indices: Indices) extends VuuInMemPluginLocator {
private var module: ViewServerModule = null;
private var permissionFunc: (ViewPort, TableContainer) => RowPermissionChecker = null
@@ -183,7 +184,7 @@ case class JoinSpec(left: String, right: String, joinType: JoinType = InnerJoin)
case class JoinTo(table: TableDef, joinSpec: JoinSpec)
-case class JoinTableDef(override val name: String, baseTable: TableDef, joinColumns: Array[Column], override val joinFields: Seq[String], joins: JoinTo*) extends TableDef(name, baseTable.keyField, joinColumns, joinFields, indices = Indices()) {
+case class JoinTableDef(override val name: String, baseTable: TableDef, joinColumns: Array[Column], override val joinFields: Seq[String], joins: JoinTo*) extends TableDef(name, baseTable.keyField, joinColumns, joinFields, indices = Indices()) with VuuInMemPluginLocator{
lazy val joinTableColumns = getJoinDefinitionColumnsInternal()
lazy val rightTables = joins.map(join => join.table.name).toArray
diff --git a/vuu/src/main/scala/org/finos/vuu/core/VuuServer.scala b/vuu/src/main/scala/org/finos/vuu/core/VuuServer.scala
index c755e63fa..0109fca88 100644
--- a/vuu/src/main/scala/org/finos/vuu/core/VuuServer.scala
+++ b/vuu/src/main/scala/org/finos/vuu/core/VuuServer.scala
@@ -8,12 +8,14 @@ import org.finos.toolbox.time.Clock
import org.finos.vuu.api.{JoinTableDef, TableDef, ViewPortDef}
import org.finos.vuu.core.module.{ModuleContainer, RealizedViewServerModule, StaticServedResource, TableDefContainer, ViewServerModule}
import org.finos.vuu.core.table.{DataTable, TableContainer}
+import org.finos.vuu.feature.inmem.{VuuInMemPlugin, VuuInMemPluginType}
import org.finos.vuu.net._
import org.finos.vuu.net.http.{Http2Server, VuuHttp2Server}
import org.finos.vuu.net.json.{CoreJsonSerializationMixin, JsonVsSerializer, Serializer}
import org.finos.vuu.net.rest.RestService
import org.finos.vuu.net.rpc.{JsonSubTypeRegistry, RpcHandler}
import org.finos.vuu.net.ws.WebSocketServer
+import org.finos.vuu.plugin.{Plugin, PluginRegistry}
import org.finos.vuu.provider.{JoinTableProvider, JoinTableProviderImpl, Provider, ProviderContainer}
import org.finos.vuu.viewport._
@@ -24,44 +26,47 @@ import java.util.concurrent.{Callable, FutureTask}
*/
class VuuServer(config: VuuServerConfig)(implicit lifecycle: LifecycleContainer, timeProvider: Clock, metricsProvider: MetricsProvider) extends LifecycleEnabled with StrictLogging with IVuuServer {
- val serializer: Serializer[String, MessageBody] = JsonVsSerializer
+ final val serializer: Serializer[String, MessageBody] = JsonVsSerializer
+
+ final val pluginRegistry: PluginRegistry = PluginRegistry()
+ pluginRegistry.registerPlugin(new VuuInMemPlugin())
JsonSubTypeRegistry.register(classOf[MessageBody], classOf[CoreJsonSerializationMixin])
JsonSubTypeRegistry.register(classOf[ViewPortAction], classOf[ViewPortActionMixin])
- val authenticator: Authenticator = config.security.authenticator
- val tokenValidator: LoginTokenValidator = config.security.loginTokenValidator
+ final val authenticator: Authenticator = config.security.authenticator
+ final val tokenValidator: LoginTokenValidator = config.security.loginTokenValidator
- val sessionContainer = new ClientSessionContainerImpl()
+ final val sessionContainer = new ClientSessionContainerImpl()
- val joinProvider: JoinTableProvider = JoinTableProviderImpl()
+ final val joinProvider: JoinTableProvider = JoinTableProviderImpl()
- val tableContainer = new TableContainer(joinProvider)
+ final val tableContainer = new TableContainer(joinProvider)
- val providerContainer = new ProviderContainer(joinProvider)
+ final val providerContainer = new ProviderContainer(joinProvider)
lifecycle(this).dependsOn(providerContainer)
- val viewPortContainer = new ViewPortContainer(tableContainer, providerContainer)
+ final val viewPortContainer = new ViewPortContainer(tableContainer, providerContainer)
- val moduleContainer = new ModuleContainer
+ final val moduleContainer = new ModuleContainer
config.modules.foreach(module => registerModule(module))
- val serverApi = new CoreServerApiHandler(viewPortContainer, tableContainer, providerContainer)
+ final val serverApi = new CoreServerApiHandler(viewPortContainer, tableContainer, providerContainer)
- val factory = new ViewServerHandlerFactoryImpl(authenticator, tokenValidator, sessionContainer, serverApi, JsonVsSerializer, moduleContainer)
+ final val factory = new ViewServerHandlerFactoryImpl(authenticator, tokenValidator, sessionContainer, serverApi, JsonVsSerializer, moduleContainer)
//order of creation here is important
- val server = new WebSocketServer(config.wsOptions, factory)
+ final val server = new WebSocketServer(config.wsOptions, factory)
- private val restServices: List[RestService] = moduleContainer.getAll().flatMap(vsm => vsm.restServices)
+ final private val restServices: List[RestService] = moduleContainer.getAll().flatMap(vsm => vsm.restServices)
- val httpServer: Http2Server = VuuHttp2Server(config.httpOptions, restServices)
+ final val httpServer: Http2Server = VuuHttp2Server(config.httpOptions, restServices)
- private val joinProviderRunner = new LifeCycleRunner("joinProviderRunner", () => joinProvider.runOnce())
+ private final val joinProviderRunner = new LifeCycleRunner("joinProviderRunner", () => joinProvider.runOnce())
lifecycle(joinProviderRunner).dependsOn(joinProvider)
- private val handlerRunner = new LifeCycleRunner("sessionRunner", () => sessionContainer.runOnce(), minCycleTime = -1)
+ private final val handlerRunner = new LifeCycleRunner("sessionRunner", () => sessionContainer.runOnce(), minCycleTime = -1)
lifecycle(handlerRunner).dependsOn(joinProviderRunner)
private val viewPortRunner = if(config.threading.viewportThreads == 1){
@@ -93,12 +98,22 @@ class VuuServer(config: VuuServerConfig)(implicit lifecycle: LifecycleContainer,
def createTable(tableDef: TableDef): DataTable = {
logger.info(s"Creating table ${tableDef.name}")
- tableContainer.createTable(tableDef)
+ pluginRegistry.withPlugin(tableDef.pluginType){
+ plugin =>
+ val table = plugin.tableFactory.createTable(tableDef, joinProvider)
+ tableContainer.addTable(table)
+ table
+ }
}
def createJoinTable(joinDef: JoinTableDef): DataTable = {
logger.info(s"Creating joinTable ${joinDef.name}")
- tableContainer.createJoinTable(joinDef)
+ pluginRegistry.withPlugin(joinDef.pluginType){
+ plugin =>
+ val table = plugin.joinTableFactory.createJoinTable(joinDef, tableContainer, joinProvider)
+ tableContainer.addTable(table)
+ table
+ }
}
def createAutoSubscribeTable(tableDef: TableDef): DataTable = {
diff --git a/vuu/src/main/scala/org/finos/vuu/core/VuuServerOptions.scala b/vuu/src/main/scala/org/finos/vuu/core/VuuServerOptions.scala
index 25e0b5444..599c1b286 100644
--- a/vuu/src/main/scala/org/finos/vuu/core/VuuServerOptions.scala
+++ b/vuu/src/main/scala/org/finos/vuu/core/VuuServerOptions.scala
@@ -4,6 +4,7 @@ import org.finos.vuu.core.module.ViewServerModule
import org.finos.vuu.net.auth.AlwaysHappyAuthenticator
import org.finos.vuu.net.http.{VuuHttp2ServerOptions, VuuSecurityOptions}
import org.finos.vuu.net.{AlwaysHappyLoginValidator, Authenticator, LoginTokenValidator}
+import org.finos.vuu.plugin.Plugin
@@ -70,5 +71,6 @@ case class VuuServerConfig(httpOptions: VuuHttp2ServerOptions = VuuHttp2ServerOp
def withModule(module: ViewServerModule): VuuServerConfig = {
this.copy(modules = modules ++ List(module))
}
+ def withPlugin(plugin: Plugin): VuuServerConfig = ???
}
diff --git a/vuu/src/main/scala/org/finos/vuu/core/table/TableContainer.scala b/vuu/src/main/scala/org/finos/vuu/core/table/TableContainer.scala
index 4b21d8552..1f902cf77 100644
--- a/vuu/src/main/scala/org/finos/vuu/core/table/TableContainer.scala
+++ b/vuu/src/main/scala/org/finos/vuu/core/table/TableContainer.scala
@@ -92,6 +92,10 @@ class TableContainer(joinTableProvider: JoinTableProvider)(implicit val metrics:
tables.get(name)
}
+ def addTable(table: DataTable): Unit = {
+ tables.put(table.getTableDef.name, table)
+ }
+
def createAutoSubscribeTable(tableDef: TableDef): DataTable = {
val table = new AutoSubscribeTable(tableDef, joinTableProvider)
@@ -132,7 +136,6 @@ class TableContainer(joinTableProvider: JoinTableProvider)(implicit val metrics:
val joinTableMap = table.joins.map(join => join.table.name -> tables.get(join.table.name)).toMap //tables.get(table.right.name)
val baseTableMap = Map[String, DataTable](table.baseTable.name -> baseTable)
-
val sourceTables = joinTableMap ++ baseTableMap
val joinTable = new JoinTable(table, sourceTables, joinTableProvider)
diff --git a/vuu/src/main/scala/org/finos/vuu/core/tree/TreeSessionTableImpl.scala b/vuu/src/main/scala/org/finos/vuu/core/tree/TreeSessionTableImpl.scala
index 720212dc4..642369703 100644
--- a/vuu/src/main/scala/org/finos/vuu/core/tree/TreeSessionTableImpl.scala
+++ b/vuu/src/main/scala/org/finos/vuu/core/tree/TreeSessionTableImpl.scala
@@ -7,6 +7,7 @@ import org.finos.toolbox.text.AsciiUtil
import org.finos.toolbox.time.Clock
import org.finos.vuu.api.{GroupByColumns, GroupByTableDef, TableDef}
import org.finos.vuu.core.table._
+import org.finos.vuu.feature.{EmptyViewPortKeys, ViewPortKeys}
import org.finos.vuu.net.ClientSessionId
import org.finos.vuu.provider.JoinTableProvider
import org.finos.vuu.viewport._
@@ -52,7 +53,7 @@ class TreeSessionTableImpl(val source: RowSource, val session: ClientSessionId,
private val wrappedObservers: ConcurrentMap[String, WrappedKeyObserver[RowKeyUpdate]] = new ConcurrentHashMap[String, WrappedKeyObserver[RowKeyUpdate]]()
@volatile
- private var keys = ImmutableArray.empty[String]
+ private var keys: ImmutableArray[String] = ImmutableArray.empty[String]
@volatile
private var tree: Tree = EmptyTree
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/EmptyViewPortKeys.scala b/vuu/src/main/scala/org/finos/vuu/feature/EmptyViewPortKeys.scala
new file mode 100644
index 000000000..c784d5c2e
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/EmptyViewPortKeys.scala
@@ -0,0 +1,12 @@
+package org.finos.vuu.feature
+import org.finos.toolbox.collection.array.ImmutableArray
+import org.finos.vuu.feature.inmem.InMemViewPortKeys
+
+object EmptyViewPortKeys extends ViewPortKeys {
+ override def create(immutableArray: ImmutableArray[String]): ViewPortKeys = InMemViewPortKeys(immutableArray)
+ override def slice(from: Int, to: Int): Array[String] = Array()
+ override def get(index: Int): String = null
+ override def sliceToKeys(from: Int, to: Int): ViewPortKeys = EmptyViewPortKeys
+ override def toArray(): Array[String] = Array()
+ override def length: Int = 0
+ }
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/Features.scala b/vuu/src/main/scala/org/finos/vuu/feature/Features.scala
new file mode 100644
index 000000000..f0da1d3ce
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/Features.scala
@@ -0,0 +1,12 @@
+package org.finos.vuu.feature
+
+trait Feature{}
+object TableFeature extends Feature
+object JoinTableFeature extends Feature
+object SessionTableFeature extends Feature
+object TreeSessionTableFeature extends Feature
+object ViewPortFeature extends Feature
+object ViewPortKeysFeature extends Feature
+object SortFeature extends Feature
+object FilterFeature extends Feature
+
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/FilterAndSortFactory.scala b/vuu/src/main/scala/org/finos/vuu/feature/FilterAndSortFactory.scala
new file mode 100644
index 000000000..2f802a063
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/FilterAndSortFactory.scala
@@ -0,0 +1,8 @@
+package org.finos.vuu.feature
+
+import org.finos.vuu.core.filter.Filter
+import org.finos.vuu.net.FilterSpec
+
+trait FilterAndSortFactory {
+ def create(filterSpec: FilterSpec): Filter
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/FilterFactory.scala b/vuu/src/main/scala/org/finos/vuu/feature/FilterFactory.scala
new file mode 100644
index 000000000..323da8516
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/FilterFactory.scala
@@ -0,0 +1,8 @@
+package org.finos.vuu.feature
+
+import org.finos.vuu.core.filter.Filter
+import org.finos.vuu.net.FilterSpec
+
+trait FilterFactory {
+ def create(spec: FilterSpec): Filter
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/JoinTableFactory.scala b/vuu/src/main/scala/org/finos/vuu/feature/JoinTableFactory.scala
new file mode 100644
index 000000000..f681c7aef
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/JoinTableFactory.scala
@@ -0,0 +1,9 @@
+package org.finos.vuu.feature
+
+import org.finos.vuu.api.JoinTableDef
+import org.finos.vuu.core.table.{DataTable, TableContainer}
+import org.finos.vuu.provider.JoinTableProvider
+
+trait JoinTableFactory {
+ def createJoinTable(table: JoinTableDef, tableContainer: TableContainer, joinTableProvider: JoinTableProvider): DataTable
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/PluginLocator.scala b/vuu/src/main/scala/org/finos/vuu/feature/PluginLocator.scala
new file mode 100644
index 000000000..ec7f23b04
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/PluginLocator.scala
@@ -0,0 +1,7 @@
+package org.finos.vuu.feature
+
+import org.finos.vuu.plugin.PluginType
+
+trait PluginLocator {
+ def pluginType: PluginType
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/SessionTableFactory.scala b/vuu/src/main/scala/org/finos/vuu/feature/SessionTableFactory.scala
new file mode 100644
index 000000000..72114d8d3
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/SessionTableFactory.scala
@@ -0,0 +1,8 @@
+package org.finos.vuu.feature
+
+import org.finos.vuu.api.{SessionTableDef, TableDef}
+import org.finos.vuu.core.table.{DataTable, SessionTable}
+
+trait SessionTableFactory {
+ def createTable(tableDef: SessionTableDef): SessionTable
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/SortFactory.scala b/vuu/src/main/scala/org/finos/vuu/feature/SortFactory.scala
new file mode 100644
index 000000000..0923adb01
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/SortFactory.scala
@@ -0,0 +1,8 @@
+package org.finos.vuu.feature
+
+import org.finos.vuu.core.sort.Sort
+import org.finos.vuu.net.SortSpec
+
+trait SortFactory {
+ def create(sortSpec: SortSpec): Sort
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/TableFactory.scala b/vuu/src/main/scala/org/finos/vuu/feature/TableFactory.scala
new file mode 100644
index 000000000..ca651c4b6
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/TableFactory.scala
@@ -0,0 +1,10 @@
+package org.finos.vuu.feature
+
+import org.finos.toolbox.jmx.MetricsProvider
+import org.finos.vuu.api.TableDef
+import org.finos.vuu.core.table.DataTable
+import org.finos.vuu.provider.JoinTableProvider
+
+trait TableFactory {
+ def createTable(tableDef: TableDef, joinTableProvider: JoinTableProvider): DataTable
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/TreeSessionTableFactory.scala b/vuu/src/main/scala/org/finos/vuu/feature/TreeSessionTableFactory.scala
new file mode 100644
index 000000000..b5c3cb830
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/TreeSessionTableFactory.scala
@@ -0,0 +1,5 @@
+package org.finos.vuu.feature
+
+trait TreeSessionTableFactory {
+
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/ViewPortFactory.scala b/vuu/src/main/scala/org/finos/vuu/feature/ViewPortFactory.scala
new file mode 100644
index 000000000..1277fbbf1
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/ViewPortFactory.scala
@@ -0,0 +1,5 @@
+package org.finos.vuu.feature
+
+trait ViewPortFactory {
+
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/ViewPortKeys.scala b/vuu/src/main/scala/org/finos/vuu/feature/ViewPortKeys.scala
new file mode 100644
index 000000000..6ffe836d4
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/ViewPortKeys.scala
@@ -0,0 +1,12 @@
+package org.finos.vuu.feature
+
+import org.finos.toolbox.collection.array.ImmutableArray
+
+trait ViewPortKeys {
+ def create(immutableArray: ImmutableArray[String]): ViewPortKeys
+ def get(index: Int): String
+ def slice(from: Int, to: Int): Array[String]
+ def sliceToKeys(from: Int, to: Int): ViewPortKeys
+ def length: Int
+ def toArray(): Array[String]
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/ViewPortKeysCreator.scala b/vuu/src/main/scala/org/finos/vuu/feature/ViewPortKeysCreator.scala
new file mode 100644
index 000000000..d9b4bb0c0
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/ViewPortKeysCreator.scala
@@ -0,0 +1,13 @@
+package org.finos.vuu.feature
+
+import org.finos.vuu.core.filter.Filter
+import org.finos.vuu.core.sort.Sort
+import org.finos.vuu.core.table.DataTable
+
+/**
+ * The Viewport Keys Creator takes in a source table, a sort and a filter
+ * and generates ViewPortKeys object.
+ */
+trait ViewPortKeysCreator {
+ def createKeys(table: DataTable, sort: Sort, filter: Filter): ViewPortKeys
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/inmem/InMemViewPortKeys.scala b/vuu/src/main/scala/org/finos/vuu/feature/inmem/InMemViewPortKeys.scala
new file mode 100644
index 000000000..642b55b88
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/inmem/InMemViewPortKeys.scala
@@ -0,0 +1,13 @@
+package org.finos.vuu.feature.inmem
+
+import org.finos.toolbox.collection.array.ImmutableArray
+import org.finos.vuu.feature.ViewPortKeys
+
+case class InMemViewPortKeys(keys: ImmutableArray[String]) extends ViewPortKeys{
+ override def create(immutableArray: ImmutableArray[String]): ViewPortKeys = InMemViewPortKeys(immutableArray)
+ override def get(index: Int): String = keys(index)
+ override def slice(from: Int, to: Int): Array[String] = keys.slice(from, to).toArray
+ override def sliceToKeys(from: Int, to: Int): ViewPortKeys = InMemViewPortKeys(ImmutableArray.from(keys.slice(from, to).toArray))
+ override def length: Int = keys.length
+ override def toArray(): Array[String] = keys.toArray
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/inmem/VuuInMemPlugin.scala b/vuu/src/main/scala/org/finos/vuu/feature/inmem/VuuInMemPlugin.scala
new file mode 100644
index 000000000..c9b1fde6f
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/inmem/VuuInMemPlugin.scala
@@ -0,0 +1,46 @@
+package org.finos.vuu.feature.inmem
+
+import org.finos.toolbox.jmx.MetricsProvider
+import org.finos.vuu.api.{JoinTableDef, TableDef}
+import org.finos.vuu.core.table.{DataTable, JoinTable, SimpleDataTable, TableContainer}
+import org.finos.vuu.feature._
+import org.finos.vuu.plugin.{DefaultPlugin, PluginType}
+import org.finos.vuu.provider.JoinTableProvider
+
+object VuuInMemPluginType extends PluginType
+
+class VuuInMemPlugin extends DefaultPlugin {
+
+ registerFeature(TableFeature)
+ registerFeature(JoinTableFeature)
+ registerFeature(SessionTableFeature)
+ registerFeature(TreeSessionTableFeature)
+ registerFeature(ViewPortKeysFeature)
+ registerFeature(SortFeature)
+ registerFeature(FilterFeature)
+ registerFeature(ViewPortFeature)
+
+ override def pluginType: PluginType = VuuInMemPluginType
+ override def joinTableFactory(implicit metrics: MetricsProvider): JoinTableFactory = (table: JoinTableDef, tableContainer: TableContainer, joinTableProvider: JoinTableProvider) => {
+ val baseTable = tableContainer.getTable(table.baseTable.name)
+ val joinTableMap = table.joins.map(join => join.table.name -> tableContainer.getTable(join.table.name)).toMap //tables.get(table.right.name)
+ val baseTableMap = Map[String, DataTable](table.baseTable.name -> baseTable)
+
+ val sourceTables = joinTableMap ++ baseTableMap
+
+ val joinTable = new JoinTable(table, sourceTables, joinTableProvider)
+
+ tableContainer.addTable(joinTable)
+ joinTableProvider.addJoinTable(joinTable)
+
+ joinTable
+ }
+ override def sessionTableFactory: SessionTableFactory = ???
+ override def viewPortKeysCreator: ViewPortKeysCreator = ???
+ override def viewPortFactory: ViewPortFactory = ???
+ override def filterFactory: FilterFactory = ???
+ override def sortFactory: SortFactory = ???
+ override def tableFactory(implicit metrics: MetricsProvider): TableFactory = (tableDef: TableDef, joinTableProvider: JoinTableProvider) => {
+ new SimpleDataTable(tableDef, joinTableProvider)
+ }
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/feature/inmem/VuuInMemPluginLocator.scala b/vuu/src/main/scala/org/finos/vuu/feature/inmem/VuuInMemPluginLocator.scala
new file mode 100644
index 000000000..4d5404e82
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/feature/inmem/VuuInMemPluginLocator.scala
@@ -0,0 +1,10 @@
+package org.finos.vuu.feature.inmem
+
+import org.finos.vuu.feature.PluginLocator
+import org.finos.vuu.plugin.PluginType
+
+
+
+trait VuuInMemPluginLocator extends PluginLocator {
+ override def pluginType: PluginType = VuuInMemPluginType
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/plugin/DefaultPlugin.scala b/vuu/src/main/scala/org/finos/vuu/plugin/DefaultPlugin.scala
new file mode 100644
index 000000000..98d6e2d6a
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/plugin/DefaultPlugin.scala
@@ -0,0 +1,20 @@
+package org.finos.vuu.plugin
+
+import io.vertx.core.impl.ConcurrentHashSet
+import org.finos.vuu.feature.Feature
+
+trait DefaultPlugin extends Plugin {
+
+ private val features: ConcurrentHashSet[Feature] = new ConcurrentHashSet[Feature]()
+
+ override def hasFeature(feature: Feature): Boolean = {
+ features.contains(feature)
+ }
+
+ override def registerFeature(feature: Feature): Unit = {
+ features.contains(feature) match {
+ case true => throw new Exception(s"Feature $feature is already registered for this plugin")
+ case false => features.add(feature)
+ }
+ }
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/plugin/Plugin.scala b/vuu/src/main/scala/org/finos/vuu/plugin/Plugin.scala
new file mode 100644
index 000000000..a570f7399
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/plugin/Plugin.scala
@@ -0,0 +1,17 @@
+package org.finos.vuu.plugin
+
+import org.finos.toolbox.jmx.MetricsProvider
+import org.finos.vuu.feature.{Feature, FilterFactory, JoinTableFactory, SessionTableFactory, SortFactory, TableFactory, ViewPortFactory, ViewPortKeysCreator}
+
+trait Plugin {
+ def hasFeature(feature: Feature): Boolean
+ def registerFeature(feature: Feature): Unit
+ def tableFactory(implicit metrics: MetricsProvider): TableFactory
+ def pluginType: PluginType
+ def joinTableFactory(implicit metrics: MetricsProvider): JoinTableFactory
+ def sessionTableFactory: SessionTableFactory
+ def viewPortKeysCreator: ViewPortKeysCreator
+ def viewPortFactory: ViewPortFactory
+ def filterFactory: FilterFactory
+ def sortFactory: SortFactory
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/plugin/PluginRegistry.scala b/vuu/src/main/scala/org/finos/vuu/plugin/PluginRegistry.scala
new file mode 100644
index 000000000..958bbe2a7
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/plugin/PluginRegistry.scala
@@ -0,0 +1,27 @@
+package org.finos.vuu.plugin
+
+import com.typesafe.scalalogging.StrictLogging
+
+import java.util.concurrent.ConcurrentHashMap
+
+object PluginRegistry{
+ def apply(): PluginRegistry = new DefaultPluginRegistry()
+}
+
+class DefaultPluginRegistry extends PluginRegistry with StrictLogging{
+ private val registry: ConcurrentHashMap[PluginType, Plugin] = new ConcurrentHashMap[PluginType, Plugin]()
+ override def getPlugin(pluginType: PluginType): Plugin = registry.get(pluginType)
+ override def registerPlugin(plugin: Plugin): Unit = registry.put(plugin.pluginType, plugin)
+ override def withPlugin[RET](pluginType: PluginType)(block: Plugin => RET): RET = {
+ val plugin = getPlugin(pluginType)
+ block.apply(plugin)
+ }
+}
+
+trait PluginRegistry {
+ def getPlugin(pluginType: PluginType): Plugin
+ def registerPlugin(plugin: Plugin): Unit
+
+ def withPlugin[RET](pluginType: PluginType)(block: (Plugin) => RET): RET
+
+}
diff --git a/vuu/src/main/scala/org/finos/vuu/plugin/PluginType.scala b/vuu/src/main/scala/org/finos/vuu/plugin/PluginType.scala
new file mode 100644
index 000000000..6531b30c8
--- /dev/null
+++ b/vuu/src/main/scala/org/finos/vuu/plugin/PluginType.scala
@@ -0,0 +1,3 @@
+package org.finos.vuu.plugin
+
+trait PluginType {}
diff --git a/vuu/src/main/scala/org/finos/vuu/viewport/ViewPort.scala b/vuu/src/main/scala/org/finos/vuu/viewport/ViewPort.scala
index 8ad99a99b..c77cfc58a 100644
--- a/vuu/src/main/scala/org/finos/vuu/viewport/ViewPort.scala
+++ b/vuu/src/main/scala/org/finos/vuu/viewport/ViewPort.scala
@@ -8,6 +8,7 @@ import org.finos.vuu.core.auths.RowPermissionChecker
import org.finos.vuu.core.sort._
import org.finos.vuu.core.table.{Column, KeyObserver, RowKeyUpdate}
import org.finos.vuu.core.tree.TreeSessionTableImpl
+import org.finos.vuu.feature.{EmptyViewPortKeys, ViewPortKeys}
import org.finos.vuu.net.{ClientSessionId, FilterSpec}
import org.finos.vuu.util.PublishQueue
import org.finos.vuu.viewport.tree.TreeNodeState
@@ -94,13 +95,13 @@ trait ViewPort {
def getRange: ViewPortRange
- def setKeys(keys: ImmutableArray[String]): Unit
+ def setKeys(keys: ViewPortKeys): Unit
- def setKeysAndNotify(key: String, keys: ImmutableArray[String]): Unit
+ def setKeysAndNotify(key: String, keys: ViewPortKeys): Unit
- def getKeys: ImmutableArray[String]
+ def getKeys: ViewPortKeys
- def getKeysInRange: ImmutableArray[String]
+ def getKeysInRange: ViewPortKeys
def getVisualLink: Option[ViewPortVisualLink]
@@ -125,8 +126,6 @@ trait ViewPort {
def getTreeNodeStateStore: TreeNodeState
def getStructure: ViewPortStructuralFields
-
-
def getStructuralHashCode(): Int
def getTableUpdateCount(): Long
@@ -225,7 +224,7 @@ class ViewPortImpl(val id: String,
override def setSelection(rowIndices: Array[Int]): Unit = {
viewPortLock.synchronized {
val oldSelection = selection.map(kv => (kv._1, this.rowKeyToIndex.get(kv._1)))
- selection = rowIndices.filter(this.keys(_) != null).map(idx => (this.keys(idx), idx)).toMap
+ selection = rowIndices.filter(this.keys.get(_) != null).map(idx => (this.keys.get(idx), idx)).toMap
for ((key, idx) <- selection ++ oldSelection) {
publishHighPriorityUpdate(key, idx)
}
@@ -251,7 +250,7 @@ class ViewPortImpl(val id: String,
def removeSubscriptionsForRange(range: ViewPortRange): Unit = {
(range.from until (range.to - 1)).foreach(i => {
- val key = if (keys.length > i) keys(i) else null
+ val key = if (keys.length > i) keys.get(i) else null
if (key != null) {
unsubscribeForKey(key)
}
@@ -260,7 +259,7 @@ class ViewPortImpl(val id: String,
def addSubscriptionsForRange(range: ViewPortRange): Unit = {
(range.from until (range.to - 1)).foreach(i => {
- val key = if (keys.length > i) keys(i) else null
+ val key = if (keys.length > i) keys.get(i) else null
if (key != null) {
subscribeForKey(key, i)
}
@@ -272,12 +271,12 @@ class ViewPortImpl(val id: String,
def sendUpdatesOnChange(currentRange: ViewPortRange): Unit = {
- val currentKeys = keys.toArray
+ //val currentKeys = keys.toArray
val from = currentRange.from
val to = currentRange.to
- val inrangeKeys = currentKeys.slice(from, to)
+ val inrangeKeys = keys.slice(from, to)
logger.info(s"Sending updates on ${inrangeKeys.length} inrangeKeys")
@@ -299,7 +298,7 @@ class ViewPortImpl(val id: String,
override def filterAndSort: FilterAndSort = structuralFields.get().filtAndSort
@volatile
- private var keys: ImmutableArray[String] = ImmutableArray.from[String](new Array[String](0))
+ private var keys: ViewPortKeys = EmptyViewPortKeys
@volatile
private var selection: Map[String, Int] = Map()
@@ -328,46 +327,48 @@ class ViewPortImpl(val id: String,
override def ForTest_getRowKeyToRowIndex: ConcurrentHashMap[String, Int] = rowKeyToIndex
- override def getKeys: ImmutableArray[String] = keys
+ override def getKeys: ViewPortKeys = keys
override def delete(): Unit = {
- this.setKeys(ImmutableArray.empty[String])
+ this.setKeys(EmptyViewPortKeys)
}
@volatile var keyBuildCounter: Long = 0
override def keyBuildCount: Long = keyBuildCounter
- override def getKeysInRange: ImmutableArray[String] = {
- val currentKeys = keys.toArray
+ override def getKeysInRange: ViewPortKeys = {
+ //val currentKeys = keys.toArray
val activeRange = range.get()
val from = activeRange.from
val to = activeRange.to
- val inrangeKeys = currentKeys.slice(from, to)
+ val inrangeKeys = keys.sliceToKeys(from, to)
+
+ inrangeKeys
- ImmutableArray.from(inrangeKeys)
+ //ImmutableArray.from(inrangeKeys)
}
- def setKeysPre(newKeys: ImmutableArray[String]): Unit = {
+ def setKeysPre(newKeys: ViewPortKeys): Unit = {
//send ViewPort
removeNoLongerSubscribedKeys(newKeys)
}
- def setKeysInternal(newKeys: ImmutableArray[String]): Unit = {
+ def setKeysInternal(newKeys: ViewPortKeys): Unit = {
keys = newKeys
}
- def setKeysPost(sendSizeUpdate: Boolean, newKeys: ImmutableArray[String]): Unit = {
+ def setKeysPost(sendSizeUpdate: Boolean, newKeys: ViewPortKeys): Unit = {
if (sendSizeUpdate) {
outboundQ.pushHighPriority(ViewPortUpdate(this.requestId, this, null, RowKeyUpdate("SIZE", null), -1, SizeUpdateType, newKeys.length, timeProvider.now()))
}
subscribeToNewKeys(newKeys)
}
- override def setKeysAndNotify(key: String, newKeys: ImmutableArray[String]): Unit = {
+ override def setKeysAndNotify(key: String, newKeys: ViewPortKeys): Unit = {
val sendSizeUpdate = newKeys.length != keys.length
setKeysPre(newKeys)
setKeysInternal(newKeys)
@@ -375,7 +376,7 @@ class ViewPortImpl(val id: String,
setKeysPost(sendSizeUpdate, newKeys)
}
- override def setKeys(newKeys: ImmutableArray[String]): Unit = {
+ override def setKeys(newKeys: ViewPortKeys): Unit = {
val sendSizeUpdate = (newKeys.length != keys.length ) || newKeys.length == 0
setKeysPre(newKeys)
setKeysInternal(newKeys)
@@ -401,7 +402,7 @@ class ViewPortImpl(val id: String,
protected def hasChangedIndex(oldIndex: Int, newIndex: Int): Boolean = oldIndex != newIndex
- protected def subscribeToNewKeys(newKeys: ImmutableArray[String]): Unit = {
+ protected def subscribeToNewKeys(newKeys: ViewPortKeys): Unit = {
var index = 0
@@ -411,7 +412,7 @@ class ViewPortImpl(val id: String,
while (index < newKeys.length) {
- val key = newKeys(index)
+ val key = newKeys.get(index)
val oldIndex = rowKeyToIndex.put(key, index)
@@ -442,7 +443,7 @@ class ViewPortImpl(val id: String,
}
- protected def removeNoLongerSubscribedKeys(newKeys: ImmutableArray[String]): Unit = {
+ protected def removeNoLongerSubscribedKeys(newKeys: ViewPortKeys): Unit = {
val newKeySet = new util.HashSet[String]()
var i = 0
@@ -450,7 +451,7 @@ class ViewPortImpl(val id: String,
//TODO: CJS this is not correct, we should only subscribe to keys within the VP range
//this will check every key and remove it
while (i < newKeys.length) {
- newKeySet.add(newKeys(i))
+ newKeySet.add(newKeys.get(i))
i += 1
}
diff --git a/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortContainer.scala b/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortContainer.scala
index 3b0ce1604..71f872f4b 100644
--- a/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortContainer.scala
+++ b/vuu/src/main/scala/org/finos/vuu/viewport/ViewPortContainer.scala
@@ -14,6 +14,7 @@ import org.finos.vuu.core.filter.{Filter, FilterSpecParser, NoFilter}
import org.finos.vuu.core.sort._
import org.finos.vuu.core.table.{DataTable, SessionTable, TableContainer}
import org.finos.vuu.core.tree.TreeSessionTableImpl
+import org.finos.vuu.feature.EmptyViewPortKeys
import org.finos.vuu.net.rpc.EditRpcHandler
import org.finos.vuu.net.{ClientSessionId, FilterSpec, RequestContext, SortSpec}
import org.finos.vuu.provider.{Provider, ProviderContainer}
@@ -443,7 +444,7 @@ class ViewPortContainer(val tableContainer: TableContainer, val providerContaine
val sessionTable = tableContainer.createTreeSessionTable(sourceTable, clientSession)
val keys = ImmutableArray.empty[String]; //tree.toKeys()
- viewPort.setKeys(keys)
+ viewPort.setKeys(EmptyViewPortKeys)
sessionTable.setTree(EmptyTree, keys)
val structure = viewport.ViewPortStructuralFields(table = sessionTable,
@@ -493,7 +494,7 @@ class ViewPortContainer(val tableContainer: TableContainer, val providerContaine
val keys = ImmutableArray.empty[String]
- viewPort.setKeys(keys)
+ viewPort.setKeys(EmptyViewPortKeys)
sessionTable.setTree(EmptyTree, keys)
logger.info("[VP] complete setKeys() " + keys.length + "new group by table:" + sessionTable.name)
@@ -510,7 +511,7 @@ class ViewPortContainer(val tableContainer: TableContainer, val providerContaine
//its important that the sequence of these operations is preserved, i.e. we should only remove the table after
//the
- viewPort.setKeys(keys)
+ viewPort.setKeys(EmptyViewPortKeys)
viewPort.changeStructure(structure)
tableContainer.removeGroupBySessionTable(groupByTable)
groupByTable.delete()
@@ -741,7 +742,7 @@ class ViewPortContainer(val tableContainer: TableContainer, val providerContaine
(millis, _) => { updateHistogram(viewPort, treeSetTreeHistograms, "tree.settree.", millis)}
)
timeItThen[Unit](
- {viewPort.setKeys(keys)},
+ {viewPort.setKeys(viewPort.getKeys.create(keys))},
(millis, _) => {updateHistogram(viewPort, treeSetKeysHistograms, "tree.setkeys.", millis)}
)
timeItThen[Unit](
@@ -773,7 +774,7 @@ class ViewPortContainer(val tableContainer: TableContainer, val providerContaine
{action.table.setTree(tree, keys)},
(millis, _) => {updateHistogram(viewPort, treeSetTreeHistograms, "tree.settree.", millis)}
)
- timeItThen[Unit]({viewPort.setKeys(keys)},
+ timeItThen[Unit]({viewPort.setKeys(viewPort.getKeys.create(keys))},
(millis, _) => {updateHistogram(viewPort, treeSetKeysHistograms, "tree.setkeys.", millis)}
)
timeItThen[Unit](
@@ -796,7 +797,7 @@ class ViewPortContainer(val tableContainer: TableContainer, val providerContaine
(millis, _) => {updateHistogram(viewPort, treeSetTreeHistograms, "tree.settree.", millis)}
)
timeItThen[Unit](
- {viewPort.setKeys(keys)},
+ {viewPort.setKeys(viewPort.getKeys.create(keys))},
(millis, _) => {updateHistogram(viewPort, treeSetKeysHistograms, "tree.setkeys.", millis)}
)
timeItThen[Unit](
@@ -847,7 +848,7 @@ class ViewPortContainer(val tableContainer: TableContainer, val providerContaine
val (millis, _) = TimeIt.timeIt {
val sorted = filterAndSort.filterAndSort(viewPort.table, keys, viewPort.getColumns, viewPort.permissionChecker())
- viewPort.setKeys(sorted)
+ viewPort.setKeys(viewPort.getKeys.create(sorted))
}
viewPortHistograms.computeIfAbsent(viewPort.id, s => metrics.histogram(toJmxName("vp.flat.cycle." + s))).update(millis)
diff --git a/vuu/src/test/scala/org/finos/vuu/core/table/join/JoinTableTest.scala b/vuu/src/test/scala/org/finos/vuu/core/table/join/JoinTableTest.scala
index 737a0dc13..4da30eabf 100644
--- a/vuu/src/test/scala/org/finos/vuu/core/table/join/JoinTableTest.scala
+++ b/vuu/src/test/scala/org/finos/vuu/core/table/join/JoinTableTest.scala
@@ -208,15 +208,15 @@ class JoinTableTest extends AnyFeatureSpec with Matchers with ViewPortSetup {
val joinDataKeys = orderPrices.asInstanceOf[JoinTable].joinData.getKeyValuesByTable("NYC-0001")
joinDataKeys shouldBe null
- orderPricesViewport.getKeys.iterator.contains("NYC-0001") should equal(true)
+ orderPricesViewport.getKeys.toArray().iterator.contains("NYC-0001") should equal(true)
vpContainer.runOnce()
- orderPricesViewport.getKeys.iterator.contains("NYC-0001") should equal(false)
+ orderPricesViewport.getKeys.toArray().iterator.contains("NYC-0001") should equal(false)
pricesProvider.tick("VOD.L", Map("ric" -> "VOD.L", "bid" -> 230))
runContainersOnce(vpContainer, joinProvider)
- orderPricesViewport.getKeys.iterator.contains("NYC-0001") should equal(false)
+ orderPricesViewport.getKeys.toArray().iterator.contains("NYC-0001") should equal(false)
val array = orderPrices.pullRowAsArray("NYC-0001", ViewPortColumnCreator.create(orderPrices, orderPrices.getTableDef.columns.map(_.name).toList))
diff --git a/vuu/src/test/scala/org/finos/vuu/plugin/PluginFeatureTest.scala b/vuu/src/test/scala/org/finos/vuu/plugin/PluginFeatureTest.scala
new file mode 100644
index 000000000..69e163487
--- /dev/null
+++ b/vuu/src/test/scala/org/finos/vuu/plugin/PluginFeatureTest.scala
@@ -0,0 +1,21 @@
+package org.finos.vuu.plugin
+
+import org.finos.vuu.feature.{SessionTableFactory, SessionTableFeature, TableFeature}
+import org.scalatest.featurespec.AnyFeatureSpec
+import org.scalatest.matchers.should.Matchers
+
+class PluginFeatureTest extends AnyFeatureSpec with Matchers{
+
+ Feature("Check plugin api"){
+
+ Scenario("Check we can create a plugin"){
+
+ val plugin = TestPlugin()
+
+ plugin.hasFeature(SessionTableFeature) should be (true)
+
+ plugin.tableFactory.createTable()
+
+ }
+ }
+}
diff --git a/vuu/src/test/scala/org/finos/vuu/plugin/TestPlugin.scala b/vuu/src/test/scala/org/finos/vuu/plugin/TestPlugin.scala
new file mode 100644
index 000000000..bf83b8469
--- /dev/null
+++ b/vuu/src/test/scala/org/finos/vuu/plugin/TestPlugin.scala
@@ -0,0 +1,16 @@
+package org.finos.vuu.plugin
+import org.finos.vuu.api.TableDef
+import org.finos.vuu.core.table.DataTable
+import org.finos.vuu.feature.{Feature, TableFactory}
+
+object TestPlugin{
+ def apply(): Plugin = {
+ new TestPlugin()
+ }
+}
+
+class TestPlugin extends Plugin with TableFactory {
+ override def hasFeature(feature: Feature): Boolean = ???
+ override def registerFeature(feature: Feature): Unit = ???
+ override def createTable(tableDef: TableDef): DataTable = ???
+}
diff --git a/vuu/src/test/scala/org/finos/vuu/test/TestVuuServer.scala b/vuu/src/test/scala/org/finos/vuu/test/TestVuuServer.scala
index 23bb1779a..aa49ded85 100644
--- a/vuu/src/test/scala/org/finos/vuu/test/TestVuuServer.scala
+++ b/vuu/src/test/scala/org/finos/vuu/test/TestVuuServer.scala
@@ -5,6 +5,7 @@ import org.finos.vuu.api.ViewPortDef
import org.finos.vuu.core.auths.RowPermissionChecker
import org.finos.vuu.core.sort.{FilterAndSort, Sort}
import org.finos.vuu.core.table.{DataTable, TableContainer}
+import org.finos.vuu.feature.ViewPortKeys
import org.finos.vuu.net.{ClientSessionId, FilterSpec, RequestContext}
import org.finos.vuu.provider.{MockProvider, Provider, ProviderContainer}
import org.finos.vuu.util.PublishQueue
@@ -40,13 +41,13 @@ class TestViewPort(val viewPort: ViewPort) extends ViewPort{
override def getRange: ViewPortRange = viewPort.getRange
- override def setKeys(keys: ImmutableArray[String]): Unit = viewPort.setKeys(keys)
+ override def setKeys(keys: ViewPortKeys): Unit = viewPort.setKeys(keys)
- override def setKeysAndNotify(key: String, keys: ImmutableArray[String]): Unit = viewPort.setKeysAndNotify(key, keys)
+ override def setKeysAndNotify(key: String, keys: ViewPortKeys): Unit = viewPort.setKeysAndNotify(key, keys)
- override def getKeys: ImmutableArray[String] = viewPort.getKeys
+ override def getKeys: ViewPortKeys = viewPort.getKeys
- override def getKeysInRange: ImmutableArray[String] = viewPort.getKeysInRange
+ override def getKeysInRange: ViewPortKeys = viewPort.getKeysInRange
override def getVisualLink: Option[ViewPortVisualLink] = viewPort.getVisualLink