-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
first import from https://github.com/MAIF/otoroshi/tree/master/experi…
- Loading branch information
0 parents
commit f291fc8
Showing
23 changed files
with
2,769 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.bsp | ||
.DS_Store | ||
.idea | ||
.metals | ||
.vscode | ||
darwin-** | ||
linux-** | ||
target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import Dependencies.munit | ||
|
||
lazy val scala212 = "2.12.16" | ||
lazy val scala213 = "2.13.11" | ||
lazy val supportedScalaVersions = List(scala212, scala213) | ||
|
||
ThisBuild / scalaVersion := scala212 | ||
ThisBuild / version := "1.0.0" | ||
ThisBuild / organization := "io.otoroshi" | ||
ThisBuild / organizationName := "wasm4s" | ||
|
||
inThisBuild( | ||
List( | ||
description := "Library to run wasm vm in a scala app", | ||
startYear := Some(2023), | ||
organization := "io.otoroshi", | ||
homepage := Some(url("https://github.com/MAIF/wasm4s")), | ||
licenses := List("Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")), | ||
scmInfo := Some( | ||
ScmInfo( | ||
url("https://github.com/MAIF/otoroshi"), | ||
"scm:[email protected]:MAIF/otoroshi.git" | ||
) | ||
), | ||
publishMavenStyle := true, | ||
developers := List( | ||
Developer( | ||
"mathieuancelin", | ||
"Mathieu Ancelin", | ||
"[email protected]", | ||
url("https://github.com/mathieuancelin") | ||
) | ||
) | ||
) | ||
) | ||
|
||
|
||
lazy val playJsonVersion = "2.9.3" | ||
lazy val playWsVersion = "2.8.19" | ||
lazy val akkaVersion = "2.6.20" | ||
lazy val akkaHttpVersion = "10.2.10" | ||
lazy val metricsVersion = "4.2.12" | ||
lazy val excludesJackson = Seq( | ||
ExclusionRule(organization = "com.fasterxml.jackson.core"), | ||
ExclusionRule(organization = "com.fasterxml.jackson.datatype"), | ||
ExclusionRule(organization = "com.fasterxml.jackson.dataformat") | ||
) | ||
|
||
scalacOptions ++= Seq( | ||
"-feature", | ||
"-language:higherKinds", | ||
"-language:implicitConversions", | ||
"-language:existentials", | ||
"-language:postfixOps" | ||
) | ||
|
||
lazy val root = (project in file(".")) | ||
.settings( | ||
name := "wasm4s", | ||
crossScalaVersions := supportedScalaVersions, | ||
//githubOwner := "MAIF", | ||
//githubRepository := "wasm4s", | ||
//githubTokenSource := TokenSource.Environment("GITHUB_PACKAGES_TOKEN"), | ||
libraryDependencies ++= Seq( | ||
munit % Test, | ||
"com.typesafe.play" %% "play-ws" % playWsVersion % "provided", | ||
"com.typesafe.play" %% "play-json" % playJsonVersion % "provided", | ||
"com.typesafe.akka" %% "akka-stream" % akkaVersion % "provided", | ||
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion % "provided", | ||
"com.typesafe.play" %% "play-json-joda" % playJsonVersion % "provided", | ||
"com.auth0" % "java-jwt" % "4.2.0" % "provided" excludeAll (excludesJackson: _*), | ||
"commons-codec" % "commons-codec" % "1.16.0" % "provided", | ||
"net.java.dev.jna" % "jna" % "5.13.0" % "provided", | ||
"com.google.code.gson" % "gson" % "2.10" % "provided", | ||
"io.dropwizard.metrics" % "metrics-json" % metricsVersion % "provided" excludeAll (excludesJackson: _*), // Apache 2.0 | ||
), | ||
) | ||
|
||
assembly / test := {} | ||
assembly / assemblyJarName := s"wasm4s-bundle_${scalaVersion.value.split("\\.").init.mkString(".")}-${version.value}.jar" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
rm ./target/scala-2.12/wasm4s_2.12-*.jar | ||
rm ./target/scala-2.13/wasm4s_2.13-*.jar | ||
rm ./target/scala-2.12/wasm4s-bundle_2.12-*.jar | ||
rm ./target/scala-2.13/wasm4s-bundle_2.13-*.jar | ||
sbt '+package' | ||
sbt '+assembly' |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import sbt._ | ||
|
||
object Dependencies { | ||
lazy val munit = "org.scalameta" %% "munit" % "0.7.29" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sbt.version=1.7.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.1") | ||
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.14") | ||
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.1.1") | ||
// addSbtPlugin("com.codecommit" % "sbt-github-packages" % "0.5.3") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
# wasm4s | ||
|
||
this library provides a runtime to execute wasm function in a pooled vm paradigm | ||
|
||
## how to use it | ||
|
||
first you need to have a class that implements the `WasmConfiguration` trait. This type represent a wasm vm you want to run. Objects that implements | ||
can be stored anywhere you want. This library provides a `BasicWasmConfiguration` implementation, but you can build your own. | ||
|
||
then create an integration context class that will provide access to everything needed | ||
|
||
for instance, here is the otoroshi integration : | ||
|
||
```scala | ||
import io.otoroshi.wasm4s._ | ||
|
||
class OtoroshiWasmIntegrationContext(env: Env) extends WasmIntegrationContext { | ||
|
||
implicit val ec = env.otoroshiExecutionContext | ||
implicit val ev = env | ||
|
||
val logger: Logger = Logger("otoroshi-wasm-integration") | ||
val materializer: Materializer = env.otoroshiMaterializer | ||
val executionContext: ExecutionContext = env.otoroshiExecutionContext | ||
val wasmCacheTtl: Long = env.wasmCacheTtl | ||
val wasmQueueBufferSize: Int = env.wasmQueueBufferSize | ||
val wasmScriptCache: TrieMap[String, CacheableWasmScript] = new TrieMap[String, CacheableWasmScript]() | ||
val wasmExecutor: ExecutionContext = ExecutionContext.fromExecutorService( | ||
Executors.newWorkStealingPool(Math.max(32, (Runtime.getRuntime.availableProcessors * 4) + 1)) | ||
) | ||
|
||
override def url(path: String): WSRequest = env.Ws.url(path) | ||
|
||
override def mtlsUrl(path: String, tlsConfig: TlsConfig): WSRequest = { | ||
val cfg = NgTlsConfig.format.reads(tlsConfig.json).get.legacy | ||
env.MtlsWs.url(path, cfg) | ||
} | ||
|
||
override def wasmManagerSettings: Future[Option[WasmManagerSettings]] = env.datastores.globalConfigDataStore.latest().wasmManagerSettings.vfuture | ||
|
||
override def wasmConfig(path: String): Option[WasmConfiguration] = env.proxyState.wasmPlugin(path).map(_.config) | ||
|
||
override def wasmConfigs(): Seq[WasmConfiguration] = env.proxyState.allWasmPlugins().map(_.config) | ||
|
||
override def hostFunctions(config: WasmConfiguration, pluginId: String): Array[WasmOtoroshiHostFunction[_ <: WasmOtoroshiHostUserData]] = { | ||
HostFunctions.getFunctions(config.asInstanceOf[WasmConfig], pluginId, None) | ||
} | ||
} | ||
``` | ||
|
||
you can create one yourself like : | ||
|
||
```scala | ||
val testWasmConfigs: InMemoryWasmConfigurationStore[WasmConfiguration] = InMemoryWasmConfigurationStore( | ||
"basic" -> BasicWasmConfiguration.fromWasiSource(WasmSource(WasmSourceKind.File, "./src/test/resources/basic.wasm")), | ||
"opa" -> BasicWasmConfiguration.fromOpaSource(WasmSource(WasmSourceKind.File, "./src/test/resources/opa.wasm")), | ||
) | ||
|
||
class FooWasmIntegrationContext(env: Env) extends WasmIntegrationContext { | ||
val system = ActorSystem("foo-wasm") | ||
val materializer: Materializer = Materializer(system) | ||
val executionContext: ExecutionContext = system.dispatcher | ||
val logger: Logger = Logger("foo-wasm") | ||
val wasmCacheTtl: Long = 2000 | ||
val wasmQueueBufferSize: Int = 100 | ||
val wasmManagerSettings: Future[Option[WasmManagerSettings]] = Future.successful(None) | ||
val wasmScriptCache: TrieMap[String, CacheableWasmScript] = new TrieMap[String, CacheableWasmScript]() | ||
val wasmExecutor: ExecutionContext = ExecutionContext.fromExecutorService( | ||
Executors.newWorkStealingPool(Math.max(32, (Runtime.getRuntime.availableProcessors * 4) + 1)) | ||
) | ||
override def url(path: String): WSRequest = ??? // we do not provide http call right now ;) | ||
override def mtlsUrl(path: String, tlsConfig: TlsConfig): WSRequest = ??? // we do not provide http call right now ;) | ||
override def wasmConfig(path: String): Option[WasmConfiguration] = testWasmConfigs.wasmConfiguration(path) | ||
override def wasmConfigs(): Seq[WasmConfiguration] = testWasmConfigs.wasmConfigurations() | ||
override def hostFunctions(config: WasmConfiguration, pluginId: String): Array[WasmOtoroshiHostFunction[_ <: WasmOtoroshiHostUserData]] = Array.empty | ||
} | ||
``` | ||
|
||
then instanciate a wasm integration | ||
|
||
```scala | ||
val wasmIntegration = WasmIntegration(new FooWasmIntegrationContext(env)) | ||
``` | ||
|
||
now you have to trigger jobs that will cache wasm stuff and clean vm. you can either do it manually or let the integration do it. | ||
|
||
```scala | ||
wasmIntegration.start() | ||
Runtime.getRuntime().addShutdownHook(() => { | ||
wasmIntegration.stop() | ||
}) | ||
``` | ||
|
||
now you can get a wasm vm through the wasm integration object and use it | ||
|
||
```scala | ||
wasmIntegration.withPooledVm(basicConfiguration) { vm => | ||
vm.callExtismFunction( | ||
"execute", | ||
Json.obj("message" -> "coucou").stringify | ||
).map { | ||
case Left(error) => println(s"error: ${error.prettify}") | ||
case Right(out) => { | ||
assertEquals(out, "{\"input\":{\"message\":\"coucou\"},\"message\":\"yo\"}") | ||
println(s"output: ${out}") | ||
} | ||
} | ||
} | ||
``` |
Empty file.
Oops, something went wrong.