Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS Scripting Support #39

Merged
merged 26 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9663aa7
Rhino-based js sandbox
danslapman Dec 6, 2022
2cbc376
Circe <-> Rhino conversions
danslapman Dec 7, 2022
3f9a303
Remove instruction count limit
danslapman Dec 8, 2022
7b22cf7
Use GraalVM instead of rhino
danslapman Dec 8, 2022
ddc71d5
Re-implement builtin pseudofunctions
danslapman Dec 9, 2022
5d09f51
Allow port 8228 for local development
danslapman Dec 11, 2022
eb35a0b
Replace pseudofunction mechanism with JS sandboxing
danslapman Dec 11, 2022
0facc2f
Re-format code
danslapman Jan 20, 2023
ef5b26d
Update graal-js
danslapman Nov 27, 2023
8519847
Update polyglot-js, native-image now builds!
danslapman Feb 9, 2024
d325339
Disable memory limit
danslapman Feb 9, 2024
42feddf
Fix path to compose-test
danslapman Feb 10, 2024
a49f03d
Fix readStr
danslapman Feb 10, 2024
d376bf2
Update pattern format in test
danslapman Feb 10, 2024
db9ded3
Add proper reflection configuration for java classes available to JS …
danslapman Feb 15, 2024
5720577
Support evaluating and returning Json in GraalJsSandbox
danslapman Feb 17, 2024
e819f54
Additional test for literals
danslapman Feb 21, 2024
dff24e4
Eval JS in XML
danslapman Feb 21, 2024
6a93cfa
Remove unused regexes
danslapman Feb 21, 2024
2b820a3
Remove FunRx
danslapman Feb 21, 2024
f126685
Support Js evaluation in substitutions
danslapman Feb 21, 2024
ada3ca8
Tests for string transformations
danslapman Feb 22, 2024
d89397d
Optics for header templating
danslapman Feb 22, 2024
f045ad2
Simpler optic implementation
danslapman Mar 10, 2024
9fa3332
Support templates in response headers
danslapman Mar 10, 2024
7cdf46c
Update readme
danslapman Mar 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions backend/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ val mockingbird = (project in file("mockingbird"))
"com.github.os72" % "protobuf-dynamic" % "1.0.1",
"com.github.geirolz" %% "advxml-core" % "2.5.1",
"com.github.geirolz" %% "advxml-xpath" % "2.5.1",
"io.estatico" %% "newtype" % "0.4.4"
"io.estatico" %% "newtype" % "0.4.4",
"org.mozilla" % "rhino" % "1.7.14",
"org.graalvm.polyglot" % "js" % "23.1.2",
"org.slf4j" % "slf4j-api" % "1.7.30" % Provided
),
Compile / unmanagedResourceDirectories += file("../frontend/dist")
)
Expand Down Expand Up @@ -140,7 +143,6 @@ lazy val `mockingbird-native` = (project in file("mockingbird-native"))
Compile / packageDoc / mappings := Seq(),
GraalVMNativeImage / mainClass := Some("ru.tinkoff.tcb.mockingbird.Mockingbird"),
GraalVMNativeImage / graalVMNativeImageOptions ++= Seq(
"-J-Xmx6144m", // Required to fit native-image runtime heap in Standard GitHub-hosted runners
"-H:+StaticExecutableWithDynamicLibC",
"--gc=G1"
).filter(_ => dockerize.value),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package object circe {
}

object JsonNull {
def unapply(arg: Json): Option[Unit] = arg.asNull
def unapply(arg: Json): Boolean = arg.isNull
}

object JsonDocument {
Expand Down Expand Up @@ -53,8 +53,8 @@ package object circe {
if (baseArr.length >= patchArr.length)
Json.fromValues((baseArr zip patchArr).map(mrgPair.tupled))
else Json.fromValues(baseArr.zipAll(patchArr, Json.Null, patchArr.last).map(mrgPair.tupled))
case (p, JsonNull(())) if arraySubvalues => p
case (_, p) => p
case (p, JsonNull()) if arraySubvalues => p
case (_, p) => p
}

implicit class JsonOps(private val json: Json) extends AnyVal {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class HttpStubWithState[HttpResponseR] extends ExampleSet[HttpResponseR] {
| }
| },
| "seed": {
| "timestamp": "%{now(yyyy-MM-dd'T'HH:mm:ss.nn'Z')}"
| "timestamp": "%{now(\"yyyy-MM-dd'T'HH:mm:ss.nn'Z'\")}"
| }
|}""".stripMargin.some,
headers = Seq("Content-Type" -> "application/json"),
Expand Down Expand Up @@ -152,7 +152,7 @@ class HttpStubWithState[HttpResponseR] extends ExampleSet[HttpResponseR] {
| "_data.id": {"==": "${id}"}
| },
| "seed": {
| "timestamp": "%{now(yyyy-MM-dd'T'HH:mm:ss.nn'Z')}"
| "timestamp": "%{now(\"yyyy-MM-dd'T'HH:mm:ss.nn'Z'\")}"
| }
|}""".stripMargin.some,
headers = Seq("Content-Type" -> "application/json"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ trait BaseSuite extends AsyncScalaTestSuite with TestContainerForAll {

override val containerDef: DockerComposeContainer.Def =
DockerComposeContainer.Def(
new File("./compose-test.yml"),
new File("../compose-test.yml"),
exposedServices = Seq(
ExposedService("mockingbird", 9000, 1),
ExposedService("mockingbird", 8228, 1, Wait.forLogMessage(".*\"App started\".*", 1)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import ru.tinkoff.tcb.mockingbird.stream.EphemeralCleaner
import ru.tinkoff.tcb.mockingbird.stream.EventSpawner
import ru.tinkoff.tcb.mockingbird.stream.SDFetcher
import ru.tinkoff.tcb.utils.metrics.makeRegistry
import ru.tinkoff.tcb.utils.resource.readStr
import ru.tinkoff.tcb.utils.sandboxing.GraalJsSandbox

object Mockingbird extends scala.App {
type FL = WLD & ServerConfig & PublicHttp & EventSpawner & ResourceManager & EphemeralCleaner & GrpcRequestHandler
Expand Down Expand Up @@ -138,6 +140,9 @@ object Mockingbird extends scala.App {
scopedBackend <- HttpClientZioBackend.scopedUsingClient(httpClient)
} yield scopedBackend
},
(ZLayer.service[ServerConfig].project(_.sandbox) ++ ZLayer.fromZIO(
ZIO.attempt(readStr("prelude.js")).map(Option(_))
)) >>> GraalJsSandbox.live,
mongoLayer,
aesEncoder,
collection(_.stub) >>> HttpStubDAOImpl.live,
Expand Down Expand Up @@ -179,11 +184,14 @@ object Mockingbird extends scala.App {
.provide(
ZLayer.succeed(requestContext),
Tracing.live,
MockingbirdConfiguration.server,
MockingbirdConfiguration.mongo,
MockingbirdConfiguration.tracing,
mongoLayer,
collection(_.state) >>> PersistentStateDAOImpl.live,
collection(_.grpcStub) >>> GrpcStubDAOImpl.live,
(ZLayer.service[ServerConfig].project(_.sandbox) ++ ZLayer
.fromZIO(ZIO.attempt(readStr("prelude.js")).map(Option(_)))) >>> GraalJsSandbox.live,
GrpcStubResolverImpl.live,
GrpcRequestHandlerImpl.live
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@
"name":"java.lang.Boolean",
"methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }]
},
{
"name":"java.lang.Class",
"methods":[{"name":"getClassLoader","parameterTypes":[] }]
},
{
"name":"java.lang.ClassLoader",
"methods":[{"name":"getPlatformClassLoader","parameterTypes":[] }, {"name":"loadClass","parameterTypes":["java.lang.String"] }]
Expand Down Expand Up @@ -167,6 +171,9 @@
"name":"java.nio.channels.ClosedChannelException",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"jdk.internal.loader.ClassLoaders$AppClassLoader"
},
{
"name":"jdk.internal.loader.ClassLoaders$PlatformClassLoader"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@
{
"name":"io.grpc.census.InternalCensusTracingAccessor"
},
{
"name":"io.grpc.okhttp.OkHttpServerProvider"
},
{
"name":"io.micrometer.core.instrument.DistributionSummary$Builder",
"queryAllPublicMethods":true
Expand Down Expand Up @@ -553,11 +556,19 @@
},
{
"name":"java.lang.Boolean",
"fields":[{"name":"TYPE"}]
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.Byte",
"fields":[{"name":"TYPE"}]
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.Character",
Expand All @@ -572,25 +583,49 @@
},
{
"name":"java.lang.Double",
"fields":[{"name":"TYPE"}]
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.Exception"
},
{
"name":"java.lang.Float",
"fields":[{"name":"TYPE"}]
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.IllegalArgumentException"
},
{
"name":"java.lang.Integer",
"fields":[{"name":"TYPE"}]
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.Long",
"fields":[{"name":"TYPE"}]
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.Math",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.Module",
Expand All @@ -614,11 +649,19 @@
},
{
"name":"java.lang.Short",
"fields":[{"name":"TYPE"}]
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.String",
"fields":[{"name":"TYPE"}]
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.lang.Thread",
Expand Down Expand Up @@ -663,10 +706,20 @@
"methods":[{"name":"getInputArguments","parameterTypes":[] }, {"name":"getName","parameterTypes":[] }]
},
{
"name":"java.math.BigDecimal"
"name":"java.math.BigDecimal",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.math.BigInteger"
"name":"java.math.BigInteger",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.net.InetAddress",
Expand Down Expand Up @@ -762,12 +815,68 @@
{
"name":"java.time.Instant"
},
{
"name":"java.time.LocalDate",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.time.LocalDateTime",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.time.format.DateTimeFormatter",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.util.Date"
},
{
"name":"java.util.List",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.util.Map",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.util.PropertyPermission"
},
{
"name":"java.util.Random",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.util.Set",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"queryAllDeclaredMethods": true,
"queryAllPublicMethods" : true
},
{
"name":"java.util.concurrent.ForkJoinTask",
"fields":[{"name":"aux"}, {"name":"status"}]
Expand Down Expand Up @@ -812,6 +921,14 @@
"name":"jdk.internal.misc.Unsafe",
"methods":[{"name":"getUnsafe","parameterTypes":[] }]
},
{
"name":"org.graalvm.polyglot.io.IOHelper",
"fields":[{"name":"ACCESS"}]
},
{
"name":"org.graalvm.polyglot.management.Management",
"fields":[{"name":"ACCESS"}]
},
{
"name":"org.slf4j.Logger"
},
Expand Down Expand Up @@ -972,6 +1089,10 @@
"name":"sun.security.rsa.RSASignature$SHA256withRSA",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.ssl.KeyManagerFactoryImpl$SunX509",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name":"sun.security.ssl.SSLContextImpl",
"fields":[{"name":"trustManager"}]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@
"pattern":"\\Qcats/data/Chain$.class\\E"
}, {
"pattern":"\\Qcats/effect/concurrent/Ref$SyncRef.class\\E"
}, {
"pattern":"\\Qcats/instances/ListInstances$$anon$1.class\\E"
}, {
"pattern":"\\Qcats/instances/VectorInstances$$anon$1.class\\E"
}, {
"pattern":"\\Qcats/syntax/ApplicativeErrorOps$.class\\E"
}, {
"pattern":"\\Qcom/oracle/truffle/js/lang/JavaScriptLanguage.class\\E"
}, {
"pattern":"\\Qcom/oracle/truffle/regex/RegexLanguage.class\\E"
}, {
"pattern":"\\Qeu/timepit/fs2cron/package$.class\\E"
}, {
Expand Down
3 changes: 2 additions & 1 deletion backend/mockingbird/src/main/resources/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ ru.tinkoff.tcb {
port = 8228
allowedOrigins = [
"http://localhost",
"http://localhost:3000"
"http://localhost:3000",
"http://localhost:8228"
]
}

Expand Down
Loading