From c7d901cc17cba356048cb6109678bedba6be8027 Mon Sep 17 00:00:00 2001 From: Jerome Samson Date: Thu, 24 Feb 2022 23:11:00 +0000 Subject: [PATCH] Add README and rename ZLambdaApp to ZLambda (#82) --- README.md | 44 +++++++++++++++++++ .../zio/lambda/example/SimpleHandler.scala | 11 +++-- .../{ZLambdaApp.scala => ZLambda.scala} | 31 +------------ .../zio/lambda/internal/LambdaLoader.scala | 6 +-- .../lambda/internal/LambdaLoaderLive.scala | 8 ++-- .../zio/lambda/internal/LoopProcessor.scala | 9 ++-- .../zio/lambda/internal/RuntimeApiLive.scala | 2 + .../zio/lambda/internal/TestZLambda.scala | 6 +-- project/plugins.sbt | 2 +- 9 files changed, 67 insertions(+), 52 deletions(-) rename lambda/src/main/scala/zio/lambda/{ZLambdaApp.scala => ZLambda.scala} (53%) diff --git a/README.md b/README.md index 41f97fb..660e5ae 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,47 @@ [Badge-Discord]: https://img.shields.io/discord/629491597070827530?logo=discord "chat on discord" [Link-Discord]: https://discord.gg/a37AwDkyvC "Discord" + +# Overview + +A ZIO-based AWS Custom Runtime compatible with GraalVM Native Image. + +# Installation + + +```scala +libraryDependencies += "dev.zio" %% "zio-lambda" % "1.0.0-RC1" +``` + +### Optional dependencies +```scala +libraryDependencies += "dev.zio" %% "zio-lambda-event" % "1.0.0-RC1" + +libraryDependencies += "dev.zio" %% "zio-lambda-response" % "1.0.0-RC1" +``` + +# Usage + +Create your Lambda function by extending ZLambda + +```scala +import zio.Console._ +import zio._ +import zio.lambda._ + +object SimpleHandler extends ZLambda[KinesisEvent, String] { + + override def apply(event: KinesisEvent, context: Context): RIO[ZEnv, String] = + for { + _ <- printLine(event.message) + } yield "Handler ran successfully" +} +``` +zio-lambda depends on [**zio-json**](https://github.com/zio/zio-json) for decoding any event you send to it and enconding any response you send back to the Lambda service. +You can either create your own data types or use the ones that are included in **zio-lambda-event** and **zio-lambda-response**. + +The last step is to define the way your function will be invoked. There are two ways: + +* Upload zio-lambda as a [Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) (Each release will contain a zip file ready to be used as a lambda layer) and your function. + +* Include zio-lambda in your function's deployment package in the form of an executable file named **bootstrap** by using [GraalVM Native Image](https://www.graalvm.org/22.0/reference-manual/native-image/) \ No newline at end of file diff --git a/lambda-example/src/main/scala/zio/lambda/example/SimpleHandler.scala b/lambda-example/src/main/scala/zio/lambda/example/SimpleHandler.scala index a08f96b..ba65a58 100644 --- a/lambda-example/src/main/scala/zio/lambda/example/SimpleHandler.scala +++ b/lambda-example/src/main/scala/zio/lambda/example/SimpleHandler.scala @@ -1,15 +1,14 @@ package zio.lambda.example -import zio._ import zio.Console._ -import zio.lambda.Context -import zio.lambda.ZLambdaApp +import zio._ +import zio.lambda._ -object SimpleHandler extends ZLambdaApp[CustomEvent, CustomResponse] { +object SimpleHandler extends ZLambda[CustomEvent, String] { - override def apply(event: CustomEvent, context: Context): RIO[ZEnv, CustomResponse] = + override def apply(event: CustomEvent, context: Context): RIO[ZEnv, String] = for { _ <- printLine(event.message) - } yield CustomResponse("Handler ran successfully") + } yield "Handler ran successfully" } diff --git a/lambda/src/main/scala/zio/lambda/ZLambdaApp.scala b/lambda/src/main/scala/zio/lambda/ZLambda.scala similarity index 53% rename from lambda/src/main/scala/zio/lambda/ZLambdaApp.scala rename to lambda/src/main/scala/zio/lambda/ZLambda.scala index b8488cb..8621310 100644 --- a/lambda/src/main/scala/zio/lambda/ZLambdaApp.scala +++ b/lambda/src/main/scala/zio/lambda/ZLambda.scala @@ -6,36 +6,7 @@ import zio.lambda.internal.LambdaEnvironment import zio.lambda.internal.LoopProcessor import zio.lambda.internal.RuntimeApiLive -/** - * Class to be extended by the Lambda function. - * - * Implementation example: - * - * {{{ - * object MyLambda extends ZLambda[MyPayload, MyResponse] { - * def handle(request: MyPayload): ZIO[ZEnv, Throwable, MyResponse] = ??? - * } - * - * final case class MyPayload(value: String) - * - * object MyPayload { - * import zio.json.JsonDecoder - * import zio.json.DeriveJsonDecoder - * - * implicit val jsonDecoder: JsonDecoder[MyPayload] = DeriveJsonDecoder.gen - * } - * - * final case class MyResponse(value: String) - * - * object MyResponse { - * import zio.json.JsonEncoder - * import zio.json.DeriveJsonEncoder - * - * implicit val jsonEncoder: JsonEncoder[MyResponse] = DeriveJsonEncoder.gen - * } - * }}} - */ -abstract class ZLambdaApp[E, A]( +abstract class ZLambda[E, A]( implicit val lambdaEventDecoder: JsonDecoder[E], implicit val lambdaResponseEncoder: JsonEncoder[A] ) extends ZIOAppDefault { self => diff --git a/lambda/src/main/scala/zio/lambda/internal/LambdaLoader.scala b/lambda/src/main/scala/zio/lambda/internal/LambdaLoader.scala index 9da87bc..59fbee0 100644 --- a/lambda/src/main/scala/zio/lambda/internal/LambdaLoader.scala +++ b/lambda/src/main/scala/zio/lambda/internal/LambdaLoader.scala @@ -1,13 +1,13 @@ package zio.lambda.internal import zio._ -import zio.lambda.ZLambdaApp +import zio.lambda.ZLambda trait LambdaLoader { - def loadLambda: UIO[Either[Throwable, ZLambdaApp[_, _]]] + def loadLambda: UIO[Either[Throwable, ZLambda[_, _]]] } object LambdaLoader { - def loadLambda: URIO[LambdaLoader, Either[Throwable, ZLambdaApp[_, _]]] = + def loadLambda: URIO[LambdaLoader, Either[Throwable, ZLambda[_, _]]] = ZIO.serviceWithZIO(_.loadLambda) } diff --git a/lambda/src/main/scala/zio/lambda/internal/LambdaLoaderLive.scala b/lambda/src/main/scala/zio/lambda/internal/LambdaLoaderLive.scala index ecc3ac7..f7a943b 100644 --- a/lambda/src/main/scala/zio/lambda/internal/LambdaLoaderLive.scala +++ b/lambda/src/main/scala/zio/lambda/internal/LambdaLoaderLive.scala @@ -1,16 +1,16 @@ package zio.lambda.internal import zio._ -import zio.lambda.ZLambdaApp +import zio.lambda.ZLambda final case class LambdaLoaderLive( customClassLoader: CustomClassLoader, environment: LambdaEnvironment ) extends LambdaLoader { - override lazy val loadLambda: UIO[Either[Throwable, ZLambdaApp[_, _]]] = + override lazy val loadLambda: UIO[Either[Throwable, ZLambda[_, _]]] = customClassLoader.getClassLoader - .flatMap[Any, Throwable, ZLambdaApp[_, _]](classLoader => + .flatMap[Any, Throwable, ZLambda[_, _]](classLoader => ZIO .attempt( Class @@ -21,7 +21,7 @@ final case class LambdaLoaderLive( ) .getDeclaredField("MODULE$") .get(null) - .asInstanceOf[ZLambdaApp[_, _]] + .asInstanceOf[ZLambda[_, _]] ) .refineOrDie { case ex: ClassNotFoundException => ex } ) diff --git a/lambda/src/main/scala/zio/lambda/internal/LoopProcessor.scala b/lambda/src/main/scala/zio/lambda/internal/LoopProcessor.scala index 1d645e3..0a0ea3f 100644 --- a/lambda/src/main/scala/zio/lambda/internal/LoopProcessor.scala +++ b/lambda/src/main/scala/zio/lambda/internal/LoopProcessor.scala @@ -2,16 +2,16 @@ package zio.lambda.internal import zio._ import zio.lambda.Context -import zio.lambda.ZLambdaApp +import zio.lambda.ZLambda trait LoopProcessor { - def loop(eitherZLambda: Either[Throwable, ZLambdaApp[_, _]]): RIO[ZEnv, Unit] + def loop(eitherZLambda: Either[Throwable, ZLambda[_, _]]): RIO[ZEnv, Unit] } object LoopProcessor { final case class Live(runtimeApi: RuntimeApi, environment: LambdaEnvironment) extends LoopProcessor { - def loop(eitherZLambda: Either[Throwable, ZLambdaApp[_, _]]): RIO[ZEnv, Unit] = + def loop(eitherZLambda: Either[Throwable, ZLambda[_, _]]): RIO[ZEnv, Unit] = eitherZLambda match { case Right(zLambda) => runtimeApi.getNextInvocation @@ -29,7 +29,6 @@ object LoopProcessor { ) ) ) - .tapError(throwable => ZIO.attempt(println(s"Error=$throwable"))) .forever case Left(throwable) => @@ -47,7 +46,7 @@ object LoopProcessor { } def loop( - eitherZLambda: Either[Throwable, ZLambdaApp[_, _]] + eitherZLambda: Either[Throwable, ZLambda[_, _]] ): RIO[LoopProcessor with ZEnv, Unit] = ZIO.serviceWithZIO[LoopProcessor](_.loop(eitherZLambda)) diff --git a/lambda/src/main/scala/zio/lambda/internal/RuntimeApiLive.scala b/lambda/src/main/scala/zio/lambda/internal/RuntimeApiLive.scala index fd44279..8ba0336 100644 --- a/lambda/src/main/scala/zio/lambda/internal/RuntimeApiLive.scala +++ b/lambda/src/main/scala/zio/lambda/internal/RuntimeApiLive.scala @@ -31,6 +31,8 @@ final case class RuntimeApiLive(environment: LambdaEnvironment) extends RuntimeA ZIO.attempt { val con = nextInvocationUrl.openConnection().asInstanceOf[HttpURLConnection] con.setRequestMethod("GET") + con.setConnectTimeout(0) + con.setReadTimeout(0) val responseBody = readResponse(con.getInputStream()) InvocationRequest.fromHttpResponse(con.getHeaderFields(), responseBody) } diff --git a/lambda/src/test/scala/zio/lambda/internal/TestZLambda.scala b/lambda/src/test/scala/zio/lambda/internal/TestZLambda.scala index 77026a5..7d7123e 100644 --- a/lambda/src/test/scala/zio/lambda/internal/TestZLambda.scala +++ b/lambda/src/test/scala/zio/lambda/internal/TestZLambda.scala @@ -2,7 +2,7 @@ package zio.lambda.internal import zio._ import zio.json._ -import zio.lambda.ZLambdaApp +import zio.lambda.ZLambda import zio.lambda.Context final case class CustomPayload(value: String) @@ -16,12 +16,12 @@ object CustomResponse { implicit val encoder: JsonEncoder[CustomResponse] = DeriveJsonEncoder.gen[CustomResponse] } -object SuccessZLambda extends ZLambdaApp[CustomPayload, CustomResponse] { +object SuccessZLambda extends ZLambda[CustomPayload, CustomResponse] { override def apply(event: CustomPayload, context: Context): RIO[ZEnv, CustomResponse] = ZIO.succeed(CustomResponse(event.value)) } -object ErrorZLambda extends ZLambdaApp[CustomPayload, CustomResponse] { +object ErrorZLambda extends ZLambda[CustomPayload, CustomResponse] { override def apply(event: CustomPayload, context: Context): RIO[ZEnv, CustomResponse] = ZIO.fail(new Throwable("ZLambda error")) } diff --git a/project/plugins.sbt b/project/plugins.sbt index 7c54c4e..fab3fd4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,7 +3,7 @@ addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.9.3") addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.0") -addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1032048a") +addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.13") addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.3") addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")