Skip to content

Commit 992c22e

Browse files
committed
zio WIP
1 parent 6a3743f commit 992c22e

File tree

16 files changed

+667
-1
lines changed

16 files changed

+667
-1
lines changed

pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<parent>
55
<groupId>io.quarkiverse</groupId>
66
<artifactId>quarkiverse-parent</artifactId>
7-
<version>15</version>
7+
<version>16</version>
88
</parent>
99
<groupId>io.quarkiverse.scala</groupId>
1010
<artifactId>quarkus-scala3-parent</artifactId>
@@ -14,6 +14,7 @@
1414
<modules>
1515
<module>deployment</module>
1616
<module>runtime</module>
17+
<module>zio</module>
1718
</modules>
1819
<scm>
1920
<connection>:git:[email protected]:quarkiverse/quarkus-scala3.git</connection>

zio/deployment/pom.xml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<parent>
6+
<groupId>io.quarkiverse.scala</groupId>
7+
<artifactId>quarkus-scala3-zio-parent</artifactId>
8+
<version>999-SNAPSHOT</version>
9+
</parent>
10+
<artifactId>quarkus-scala3-zio-deployment</artifactId>
11+
<name>Quarkus Scala3 Zio - Deployment</name>
12+
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>io.quarkus</groupId>
17+
<artifactId>quarkus-arc-deployment</artifactId>
18+
</dependency>
19+
<dependency>
20+
<groupId>io.quarkiverse.scala</groupId>
21+
<artifactId>quarkus-scala3-zio</artifactId>
22+
<version>${project.version}</version>
23+
</dependency>
24+
<dependency>
25+
<groupId>io.quarkus</groupId>
26+
<artifactId>quarkus-junit5-internal</artifactId>
27+
<scope>test</scope>
28+
</dependency>
29+
30+
<dependency>
31+
<groupId>io.quarkus</groupId>
32+
<artifactId>quarkus-rest-spi-deployment</artifactId>
33+
</dependency>
34+
<dependency>
35+
<groupId>io.quarkus.resteasy.reactive</groupId>
36+
<artifactId>resteasy-reactive-processor</artifactId>
37+
</dependency>
38+
<dependency>
39+
<groupId>io.quarkus</groupId>
40+
<artifactId>quarkus-rest-server-spi-deployment</artifactId>
41+
</dependency>
42+
43+
<dependency>
44+
<groupId>org.scala-lang</groupId>
45+
<artifactId>scala3-library_3</artifactId>
46+
<scope>compile</scope>
47+
</dependency>
48+
49+
<dependency>
50+
<groupId>dev.zio</groupId>
51+
<artifactId>zio_3</artifactId>
52+
</dependency>
53+
54+
</dependencies>
55+
56+
<build>
57+
<sourceDirectory>src/main/scala</sourceDirectory>
58+
<testSourceDirectory>src/test/scala</testSourceDirectory>
59+
<plugins>
60+
<plugin>
61+
<artifactId>maven-compiler-plugin</artifactId>
62+
<configuration>
63+
<annotationProcessorPaths>
64+
<path>
65+
<groupId>io.quarkus</groupId>
66+
<artifactId>quarkus-extension-processor</artifactId>
67+
<version>${quarkus.version}</version>
68+
</path>
69+
</annotationProcessorPaths>
70+
</configuration>
71+
</plugin>
72+
<plugin>
73+
<groupId>net.alchim31.maven</groupId>
74+
<artifactId>scala-maven-plugin</artifactId>
75+
</plugin>
76+
</plugins>
77+
</build>
78+
</project>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package io.quarkiverse.scala.scala3.zio.deployment
2+
3+
import org.jboss.resteasy.reactive.server.core.ResteasyReactiveRequestContext
4+
import org.jboss.resteasy.reactive.server.spi.ServerRestHandler
5+
import zio.ZIO
6+
7+
import java.lang.reflect.ParameterizedType
8+
import scala.jdk.CollectionConverters.*
9+
import scala.util.Failure
10+
import scala.util.Success
11+
12+
class Scala3ZIOResponseHandler() extends ServerRestHandler {
13+
14+
override def handle(requestContext: ResteasyReactiveRequestContext): Unit = {
15+
val result = requestContext.getResult
16+
17+
type R = Any
18+
type E = Throwable
19+
type A = Any
20+
/*
21+
// TODO at the moment, we're just stupidly assume, the effect has no environment
22+
// and the error type is a throwable. We need to figure out a way on how to access
23+
// the type arguments of the ZIO effect in a more structured way.
24+
// At the moment, a Environment of e.g. String with Int will be read as java.lang.Object,
25+
// so we loose the type information which could be used for dependency injection
26+
println("in handle of Scala3ZIOResponseHandler")
27+
28+
val p = requestContext.getGenericReturnType.asInstanceOf[ParameterizedType]
29+
val typeArgs = p.getActualTypeArguments.toSeq
30+
val (environment, errorType, successType) = (typeArgs(0), typeArgs(1), typeArgs(2))
31+
32+
println(s"environment: $environment")
33+
println(s"errorType: $errorType")
34+
println(s"successType: $successType")
35+
*/
36+
result match
37+
case r: ZIO[R, E, A] =>
38+
requestContext.suspend()
39+
val f = zio.Unsafe.unsafe(u => zio.Runtime.default.unsafe.runToFuture(r)(zio.Trace.empty, u))
40+
f.onComplete {
41+
case Success(value) =>
42+
requestContext.setResult(value)
43+
requestContext.resume()
44+
case Failure(exception) =>
45+
requestContext.handleException(exception, true)
46+
requestContext.resume()
47+
}(scala.concurrent.ExecutionContext.global)
48+
49+
case _ => ()
50+
}
51+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package io.quarkiverse.scala.scala3.zio.deployment
2+
3+
import org.jboss.jandex.AnnotationInstance
4+
import org.jboss.jandex.ClassInfo
5+
import org.jboss.jandex.DotName
6+
import org.jboss.jandex.MethodInfo
7+
import org.jboss.jandex.Type
8+
import org.jboss.resteasy.reactive.server.core.parameters.ParameterExtractor
9+
import org.jboss.resteasy.reactive.server.model.FixedHandlerChainCustomizer
10+
import org.jboss.resteasy.reactive.server.model.HandlerChainCustomizer
11+
import org.jboss.resteasy.reactive.server.processor.scanning.MethodScanner
12+
import zio.RIO
13+
14+
import java.util
15+
import java.util.List as JList
16+
import java.util.Collections as JCollections
17+
18+
class Scala3ZIOReturnTypeMethodScanner extends MethodScanner {
19+
val ZIO: DotName = DotName.createSimple("zio.ZIO")
20+
// val TASK: DotName = DotName.createSimple("zio.Task")
21+
// val UIO: DotName = DotName.createSimple("zio.UIO")
22+
// val RIO: DotName = DotName.createSimple("zio.RIO")
23+
24+
25+
26+
27+
override def scan(method: MethodInfo,
28+
actualEndpointClass: ClassInfo,
29+
methodContext: util.Map[String, AnyRef]
30+
): JList[HandlerChainCustomizer] = {
31+
println("in Scala3ZIOReturnTypeMethodScanner scan")
32+
if(isMethodSignatureAsync(method)) {
33+
JCollections.singletonList(
34+
new FixedHandlerChainCustomizer(
35+
new Scala3ZIOResponseHandler(),
36+
HandlerChainCustomizer.Phase.AFTER_METHOD_INVOKE
37+
)
38+
)
39+
} else {
40+
JCollections.emptyList()
41+
}
42+
}
43+
44+
45+
46+
override def isMethodSignatureAsync(info: MethodInfo): Boolean = {
47+
val name = info.returnType().name()
48+
val isCorrect = name == ZIO
49+
println(s"return type is $name, isCorrect: $isCorrect")
50+
isCorrect
51+
// name match {
52+
// case ZIO | TASK | UIO => true
53+
// case _ => false
54+
// }
55+
}
56+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.quarkiverse.scala.scala3.zio.deployment;
2+
3+
import io.quarkus.deployment.annotations.BuildStep;
4+
import io.quarkus.deployment.builditem.FeatureBuildItem;
5+
import io.quarkus.resteasy.reactive.server.spi.MethodScannerBuildItem;
6+
7+
public class Scala3ZioJavaProcessor {
8+
9+
@BuildStep
10+
public FeatureBuildItem feature() {
11+
return new FeatureBuildItem("scala3-zio");
12+
}
13+
14+
@BuildStep
15+
public MethodScannerBuildItem registerZIORestReturnTypes() {
16+
return new MethodScannerBuildItem(new Scala3ZIOReturnTypeMethodScanner());
17+
}
18+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.quarkiverse.scala.scala3.zio.test;
2+
3+
import org.jboss.shrinkwrap.api.ShrinkWrap;
4+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.extension.RegisterExtension;
8+
9+
import io.quarkus.test.QuarkusDevModeTest;
10+
11+
class Scala3ZioDevModeTest {
12+
13+
// Start hot reload (DevMode) test with your extension loaded
14+
@RegisterExtension
15+
val devModeTest: QuarkusDevModeTest = new QuarkusDevModeTest()
16+
.setArchiveProducer(() => ShrinkWrap.create(classOf[JavaArchive]))
17+
18+
@Test
19+
def writeYourOwnDevModeTest(): Unit = {
20+
// Write your dev mode tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-hot-reload for more information
21+
Assertions.assertTrue(true, "Add dev mode assertions to " + getClass().getName());
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.quarkiverse.scala.scala3.zio.test;
2+
3+
import org.jboss.shrinkwrap.api.ShrinkWrap;
4+
import org.jboss.shrinkwrap.api.spec.JavaArchive;
5+
import org.junit.jupiter.api.Assertions;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.api.extension.RegisterExtension;
8+
9+
import io.quarkus.test.QuarkusUnitTest;
10+
11+
class Scala3ZioTest {
12+
13+
// Start unit test with your extension loaded
14+
@RegisterExtension
15+
def unitTest: QuarkusUnitTest = new QuarkusUnitTest()
16+
.setArchiveProducer(() => ShrinkWrap.create(classOf[JavaArchive]))
17+
18+
@Test
19+
def writeYourOwnUnitTest(): Unit = {
20+
// Write your unit tests here - see the testing extension guide https://quarkus.io/guides/writing-extensions#testing-extensions for more information
21+
Assertions.assertTrue(true, "Add some assertions to " + getClass().getName());
22+
}
23+
}

0 commit comments

Comments
 (0)