Skip to content

Instantly share code, notes, and snippets.

@omnisis
Last active March 8, 2017 08:41
Show Gist options
  • Save omnisis/b7ce354565ebb9f3c527c40135925e77 to your computer and use it in GitHub Desktop.
Save omnisis/b7ce354565ebb9f3c527c40135925e77 to your computer and use it in GitHub Desktop.
Scala Akka Boilerplate
package examples.utils
object AnsiColors {
val ANSI_RESET = "\u001B[0m"
val ANSI_BLACK = "\u001B[30m"
val ANSI_RED = "\u001B[31m"
val ANSI_GREEN = "\u001B[32m"
val ANSI_YELLOW = "\u001B[33m"
val ANSI_BLUE = "\u001B[34m"
val ANSI_PURPLE = "\u001B[35m"
val ANSI_CYAN = "\u001B[36m"
val ANSI_WHITE = "\u001B[37m"
}
import MyBuild._
import AssemblyKeys._
name := "scala-akka"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
"io.spray" %% "spray-json" % "1.3.3",
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-slf4j" % akkaVersion,
"com.typesafe.scala-logging" %% "scala-logging" % "3.5.0",
"ch.qos.logback" % "logback-classic" % "1.1.2",
"com.lihaoyi" %% "sourcecode" % "0.1.3"
)
assemblySettings
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%green(%date{ISO8601}) [%25.25(%X{sourceThread})] %highlight(%-5level) %-30.30logger{30} -- %msg%n</pattern>
</encoder>
</appender>
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="STDOUT" />
</appender>
<root level="debug">
<appender-ref ref="ASYNC"/>
</root>
</configuration>
package examples.server
import java.sql.Timestamp
import java.util.Date
import akka.actor.ActorSystem
import akka.event.Logging
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import akka.stream.scaladsl._
import akka.util.ByteString
import examples.models.Tweet
import examples.utils.Colors
import spray.json._
import scala.concurrent.Future
import scala.io.StdIn
import scala.util.Random
/**
* API Stub
*/
object TweetApi {
import scala.concurrent.ExecutionContext.Implicits.global
def fetchTweets(): Future[List[Tweet]] = {
Future {
List[Tweet](
Tweet("@twitteruser", "hello world", new Timestamp(new Date().getTime))
)
}
}
}
/**
* Mixin for pulling in necessary JSON support
*/
trait MyJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
object MyJsonProtocol extends DefaultJsonProtocol {
implicit object TimestampFormat extends RootJsonFormat[Timestamp] {
def write(ts: Timestamp) = JsNumber(ts.getTime)
def read(value: JsValue) = value match {
case JsNumber(n) => new Timestamp(n.bigDecimal.longValue())
case _ => deserializationError("long timestamp expected")
}
}
}
import MyJsonProtocol._
implicit val tweet: RootJsonFormat[Tweet] = jsonFormat3(Tweet.apply)
}
trait Utils {
def nowAsTimestamp(): Timestamp = new Timestamp(new Date().getTime)
def intStream(): Source[Int, _] = Source.fromIterator(() => Iterator.continually(Random.nextInt()))
}
object Main extends Object
with MyJsonSupport
with Utils
with LoggingSupport {
import Colors._
println(s"${ANSI_CYAN}:::::${ANSI_RESET} Now Running ${ANSI_BLUE}MB${ANSI_RESET}${ANSI_RED}Flask${ANSI_RESET} ${ANSI_CYAN}:::::${ANSI_RESET}")
val jsonType = ContentTypes.`application/json`
implicit val system = ActorSystem("default")
implicit val materializer = ActorMaterializer()
val log = Logging(system, this)
def main(args: Array[String]): Unit = {
// needed for binding map/flatMap
implicit val executionContext = system.dispatcher
val route =
path("hello") {
get {
complete(HttpEntity(jsonType, """{"message": "Hello World!"}"""))
}
} ~
path("tweet") {
get {
//val TweetApi.fet
complete(Tweet("foo", "this is a tweet", nowAsTimestamp()))
}
} ~
path("tweets") {
get {
val tweets = TweetApi.fetchTweets()
onSuccess(tweets) {
case Nil => complete(StatusCodes.NoContent)
case x :: xs => complete(x :: xs)
}
}
} ~
path("ints") {
get {
complete(HttpEntity(
ContentTypes.`text/plain(UTF-8)`,
intStream().map(n => ByteString(s"$n\n"))
))
}
} ~
path("bad") {
get {
failWith(new RuntimeException("Shit's busted"))
}
}
val bindingFuture = Http().bindAndHandle(route, "localhost", 7777)
log.info(s"Server online @ http://localhost:7777/\nPress RETURN to stop...")
StdIn.readLine()
bindingFuture
.flatMap(_.unbind())
.onComplete(_ => system.terminate())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment