Created
November 3, 2017 17:06
-
-
Save fommil/744bcda4376373eac83243d19cf0fc83 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
package com.example | |
import cats._, data._, effect._ | |
import doobie.hikari.imports._ | |
import doobie.imports._ | |
import fs2.interop.cats._ | |
import fs2.util.{ Catchable, Suspendable } | |
import Fragments._ | |
final case class AuroraConfig( | |
host: String, | |
port: Int, | |
database: String, | |
user: String, | |
pass: String) | |
object DoobieAurora { | |
import DoobieBackcompat._ | |
def hikari(config: AuroraConfig): IO[HikariTransactor[IO]] = { | |
import config._ | |
for { | |
tx <- HikariTransactor[IO]( | |
"org.mariadb.jdbc.Driver", | |
s"jdbc:mariadb://$host:$port/$database?charset=utf8mb4", | |
user, | |
pass | |
) | |
_ <- tx.configure(hx => hx.setMaximumPoolSize(10)) | |
} yield tx | |
} | |
def physical(config: AuroraConfig): Transactor[IO] = { | |
import config._ | |
DriverManagerTransactor[IO]( | |
"org.mariadb.jdbc.Driver", | |
s"jdbc:mariadb://$host:$port/$database?charset=utf8mb4", | |
user, | |
pass | |
) | |
} | |
} | |
// supports cats.effect.IO in doobie 0.4 | |
object DoobieBackcompat { | |
implicit val catsEffect: Suspendable[IO] with Catchable[IO] = | |
new Suspendable[IO] with Catchable[IO] { | |
override def pure[A](a: A): IO[A] = IO.pure(a) | |
override def flatMap[A, B](a: IO[A])(f: A => IO[B]): IO[B] = a flatMap f | |
override def delay[A](a: => A) = IO(a) | |
override def suspend[A](fa: => IO[A]) = IO.suspend(fa) | |
override def fail[A](err: Throwable) = IO.raiseError(err) | |
override def attempt[A](t: IO[A]) = t.attempt | |
} | |
} |
This file contains hidden or 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
package com.example | |
import java.nio.charset.StandardCharsets | |
import java.util.Collections | |
import scala.collection.JavaConverters.iterableAsScalaIterableConverter | |
import cats.data.NonEmptyList | |
import cats.effect.IO | |
import com.amazonaws.services.kinesis.clientlibrary.types.UserRecord | |
import com.amazonaws.services.lambda.runtime.Context | |
import com.amazonaws.services.lambda.runtime.events.KinesisEvent | |
import doobie.util.transactor.Transactor | |
/** | |
* AWS Lambda applications should extend from this interface and | |
* implement the abstract method. | |
* | |
* This code cannot be tested locally, so when making changes be sure | |
* to perform extensive manual testing. | |
*/ | |
trait AwsLambda { | |
final def handler(event: KinesisEvent, context: Context): Unit = { | |
val logger = context.getLogger() | |
val records = event | |
.getRecords() | |
.asScala | |
.toList | |
.flatMap { record => | |
UserRecord | |
.deaggregate(Collections.singletonList(record.getKinesis)) | |
.asScala | |
.map(r => new String(r.getData.array(), StandardCharsets.UTF_8)) | |
} | |
lazy val aurora = AuroraConfig( | |
sys.env("AURORA_HOST"), | |
sys.env("AURORA_PORT").toInt, | |
sys.env("AURORA_DATABASE"), | |
sys.env("AURORA_USER"), | |
sys.env("AURORA_PASSWORD") | |
) | |
NonEmptyList.fromList(records).foreach { nel => | |
val log = new LambdaLogging(logger) | |
val tx = DoobieAurora.physical(aurora) | |
λ(nel)(log, tx).unsafeRunSync() | |
} | |
} | |
def λ( | |
records: NonEmptyList[String] | |
)(implicit L: Logging[IO], | |
T: Transactor[IO] | |
): IO[Unit] | |
} |
This file contains hidden or 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
... | |
val mylambda = project | |
.enablePlugins(SbtProguard) | |
.settings( | |
// https://www.guardsquare.com/en/proguard/manual/introduction | |
// https://www.guardsquare.com/en/proguard/manual/examples | |
javaOptions in (Proguard, proguard) := Seq("-Xmx5g"), | |
proguardOptions in Proguard ++= Seq( | |
"-dontnote", | |
"-dontwarn", | |
"-ignorewarnings", | |
"-dontoptimize", | |
"-dontobfuscate", | |
// our entry method | |
"""-keep class com.example.MyApp { | |
void handler(com.amazonaws.services.lambda.runtime.events.KinesisEvent, | |
com.amazonaws.services.lambda.runtime.Context); | |
}""", | |
// reflectively loaded database driver | |
"""-keep class org.mariadb.jdbc.Driver""", | |
// it is not enough to request implementations of KinesisEvent / | |
// Context, we must import their entire public API. | |
"""-keep public class com.amazonaws.services.lambda.runtime.** { public *; }""", | |
// AWS reflectively loads DateTime | |
"""-keep class org.joda.time.DateTime""", | |
// bugs in proguard's scala support... this is costing ~15MB | |
"""-keep class scala.** { *; }""" | |
), | |
libraryDependencies ++= Seq( | |
// plus doobie and maybe some other AWS stuff here... | |
"com.amazonaws" % "amazon-kinesis-client" % "1.8.7", | |
"com.amazonaws" % "aws-lambda-java-core" % "1.1.0", | |
"com.amazonaws" % "aws-lambda-java-events" % "2.0.1" | |
), | |
TaskKey[Unit]("lambdaPublish", "") := { | |
import scala.sys.process._ | |
val jar = (proguard in Proguard).value.head | |
val name = jar.getName | |
s"aws --profile=adtech s3 cp $jar s3://your-name-here/$name".! | |
IO.copyFile(jar, file(jar.getName)) | |
} | |
) | |
... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment