Skip to content

Instantly share code, notes, and snippets.

@aappddeevv
Last active October 11, 2017 08:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aappddeevv/a8beb9398c3d834e6c25e82d545890c4 to your computer and use it in GitHub Desktop.
Save aappddeevv/a8beb9398c3d834e6c25e82d545890c4 to your computer and use it in GitHub Desktop.
akka, http, server

A relatively simple akka server with a few bells and whistes.

package example

import scala.language._
import akka.actor._
import akka.http.scaladsl
import scaladsl._
import scaladsl.server
import scaladsl.model._
import server._
import server.Directives._
import akka.stream
import stream._
import stream.scaladsl._
import scaladsl.model.StatusCodes._
import com.typesafe.config.ConfigFactory
import scala.io.StdIn
import com.beust.jcommander._
import com.typesafe.scalalogging.LazyLogging
import scala.xml.XML
import XML._
import akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._

object Args {
  @Parameter(names = Array("-h", "--help"), help = true)
  var help: Boolean = false
}

object Server extends LazyLogging {

  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()
  implicit val ec = system.dispatcher

  val route =
    logRequestResult("example-server") {
      pathEndOrSingleSlash {
        get {
          complete(<h1>you have reached the example server</h1>)
        }
      } ~ path("echo") {
        get {
          extractRequest { req =>
            complete(req.toString)
          }
        }
      } ~ post {
        complete("POST succeeded")
      }
    }

  def main(args: Array[String]): Unit = {

    val j = new JCommander(Args, args.toArray: _*)
    if (Args.help) {
      val sb = new java.lang.StringBuilder()
      j.setProgramName("crmauth")
      j.usage(sb) // only way to get pre-formatted usage info
      sb.append("An application.conf can be use to specify some parameters.")
      println(sb.toString)
      system.terminate()
      return
    }

    val config = ConfigFactory.load()
    val ip = config.getString("http.host")
    val port = config.getInt("http.port")
    val server = ip + ":" + port

    val binding = Http().bindAndHandle(route, ip, port)
    binding onFailure {
      case ex: Exception =>
        logger.error(s"Error binding $server", ex)
        system.terminate()
        return
    }

    println(s"Started server on $server.\nPress ENTER to stop.")
    StdIn.readLine()

    binding flatMap { _.unbind() } onComplete { _ => system.terminate() }
  }
}

And the build.sbt to go along with it:

name := "example-server"
organization := "example"
version := "0.1.0"
scalaVersion := "2.11.8"

scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8")

resolvers += Resolver.url("file://" + Path.userHome.absolutePath + "/.ivy/local")
resolvers += Resolver.sonatypeRepo("releases")
resolvers += "Local Maven Repository" at "file://"+Path.userHome.absolutePath+"/.m2/repository"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-actor" % "latest.release"
    ,"com.typesafe.akka" %% "akka-contrib" % "latest.release"
    ,"com.typesafe.akka" %% "akka-http-core" % "latest.release"
    ,"com.typesafe.akka" %% "akka-slf4j" % "latest.release"
    ,"com.typesafe.akka" %% "akka-stream" % "latest.release"
    ,"com.typesafe.akka" %% "akka-http-experimental" % "latest.release"
    ,"com.typesafe.akka" %% "akka-http-jackson-experimental" % "latest.release"
    ,"com.typesafe.akka" %% "akka-http-spray-json-experimental" % "latest.release"
    ,"com.typesafe.akka" %% "akka-http-xml-experimental" % "latest.release"
    ,"com.typesafe" % "config" % "latest.release"
    ,"org.scala-lang.modules" %% "scala-xml" % "latest.release"
    ,"com.beust" % "jcommander" % "latest.release"
    ,"ch.qos.logback" % "logback-classic" % "latest.release"
    ,"ch.qos.logback" % "logback-core" % "latest.release"
    ,"net.databinder.dispatch" %% "dispatch-core" % "latest.release"
    ,"com.typesafe.scala-logging" %% "scala-logging" % "latest.release"
    ,"org.scala-lang.modules" %% "scala-async" % "latest.release"
)

EclipseKeys.createSrc := EclipseCreateSrc.Default + EclipseCreateSrc.Resource

EclipseKeys.withSource := true

packSettings

packMain := Map("example-server" -> "example.Server")

and my plugins:

addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.8.0")
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment