From 572382b2205508672bbf9939582a70d17b707b10 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Mon, 27 Feb 2012 13:56:49 +0100 Subject: [PATCH] Removing playMini as to avoid the cyclic dependency, please look at the play-mini docs for examples --- akka-docs/modules/code/Global.scala | 6 - .../akka/docs/http/PlayMiniApplication.scala | 128 ------------- akka-docs/modules/http.rst | 180 +----------------- project/AkkaBuild.scala | 8 +- 4 files changed, 3 insertions(+), 319 deletions(-) delete mode 100644 akka-docs/modules/code/Global.scala delete mode 100644 akka-docs/modules/code/akka/docs/http/PlayMiniApplication.scala diff --git a/akka-docs/modules/code/Global.scala b/akka-docs/modules/code/Global.scala deleted file mode 100644 index 021e30d5b1..0000000000 --- a/akka-docs/modules/code/Global.scala +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Copyright (C) 2009-2012 Typesafe Inc. - */ -//#global -object Global extends com.typesafe.play.mini.Setup(akka.docs.http.PlayMiniApplication) -//#global \ No newline at end of file diff --git a/akka-docs/modules/code/akka/docs/http/PlayMiniApplication.scala b/akka-docs/modules/code/akka/docs/http/PlayMiniApplication.scala deleted file mode 100644 index 15c0de0ac5..0000000000 --- a/akka-docs/modules/code/akka/docs/http/PlayMiniApplication.scala +++ /dev/null @@ -1,128 +0,0 @@ -/** - * Copyright (C) 2009-2012 Typesafe Inc. - */ -package akka.docs.http - -//#imports -import com.typesafe.play.mini.{ POST, GET, Path, Application } -import play.api.mvc.{ Action, AsyncResult } -import play.api.mvc.Results._ -import play.api.libs.concurrent._ -import play.api.data._ -import play.api.data.Forms._ -import akka.pattern.ask -import akka.util.Timeout -import akka.util.duration._ -import akka.actor.{ ActorSystem, Props, Actor } -import scala.collection.mutable.{ Map ⇒ MutableMap } -//#imports - -//#playMiniDefinition -object PlayMiniApplication extends Application { - //#playMiniDefinition - private val system = ActorSystem("sample") - //#regexURI - private final val StatementPattern = """/account/statement/(\w+)""".r - //#regexURI - private lazy val accountActor = system.actorOf(Props[AccountActor]) - implicit val timeout = Timeout(1000 milliseconds) - - //#route - def route = { - //#routeLogic - //#simpleGET - case GET(Path("/ping")) ⇒ Action { - Ok("Pong @ " + System.currentTimeMillis) - } - //#simpleGET - //#regexGET - case GET(Path(StatementPattern(accountId))) ⇒ Action { - AsyncResult { - //#innerRegexGET - (accountActor ask Status(accountId)).mapTo[Int].asPromise.map { r ⇒ - if (r >= 0) Ok("Account total: " + r) - else BadRequest("Unknown account: " + accountId) - } - //#innerRegexGET - } - } - //#regexGET - //#asyncDepositPOST - case POST(Path("/account/deposit")) ⇒ Action { implicit request ⇒ - //#formAsyncDepositPOST - val (accountId, amount) = commonForm.bindFromRequest.get - //#formAsyncDepositPOST - AsyncResult { - (accountActor ask Deposit(accountId, amount)).mapTo[Int].asPromise.map { r ⇒ Ok("Updated account total: " + r) } - } - } - //#asyncDepositPOST - //#asyncWithdrawPOST - case POST(Path("/account/withdraw")) ⇒ Action { implicit request ⇒ - val (accountId, amount) = commonForm.bindFromRequest.get - AsyncResult { - (accountActor ask Withdraw(accountId, amount)).mapTo[Int].asPromise.map { r ⇒ - if (r >= 0) Ok("Updated account total: " + r) - else BadRequest("Unknown account or insufficient funds. Get your act together.") - } - } - } - //#asyncWithdrawPOST - //#routeLogic - } - //#route - - //#form - val commonForm = Form( - tuple( - "accountId" -> nonEmptyText, - "amount" -> number(min = 1))) - //#form -} - -//#cases -case class Status(accountId: String) -case class Deposit(accountId: String, amount: Int) -case class Withdraw(accountId: String, amount: Int) -//#cases - -//#actor -class AccountActor extends Actor { - var accounts = MutableMap[String, Int]() - - //#receive - def receive = { - //#senderBang - case Status(accountId) ⇒ sender ! accounts.getOrElse(accountId, -1) - //#senderBang - case Deposit(accountId, amount) ⇒ sender ! deposit(accountId, amount) - case Withdraw(accountId, amount) ⇒ sender ! withdraw(accountId, amount) - } - //#receive - - private def deposit(accountId: String, amount: Int): Int = { - accounts.get(accountId) match { - case Some(value) ⇒ - val newValue = value + amount - accounts += accountId -> newValue - newValue - case None ⇒ - accounts += accountId -> amount - amount - } - } - - private def withdraw(accountId: String, amount: Int): Int = { - accounts.get(accountId) match { - case Some(value) ⇒ - if (value < amount) -1 - else { - val newValue = value - amount - accounts += accountId -> newValue - newValue - } - case None ⇒ -1 - } - } - //#actor -} \ No newline at end of file diff --git a/akka-docs/modules/http.rst b/akka-docs/modules/http.rst index e708b0800b..94292f0e15 100644 --- a/akka-docs/modules/http.rst +++ b/akka-docs/modules/http.rst @@ -19,182 +19,4 @@ Getting started First you must make your application aware of play-mini. In SBT you just have to add the following to your _libraryDependencies_:: - libraryDependencies += "com.typesafe" %% "play-mini" % "2.0-RC3-SNAPSHOT" - -Sample Application ------------------- - -To illustrate how easy it is to wire a RESTful service with Akka we will use a sample application. -The aim of the application is to show how to use play-mini and Akka in combination. Do not put too much -attention on the actual business logic itself, which is a extremely simple bank application, as building a bank -application is a little more complex than what's shown in the sample... - -The application should support the following URL commands: - - GET /ping - returns a Pong message with the time of the server (used to see if the application is up and running) - - GET /account/statement/{accountId} - returns the account statement - - POST /account/deposit - deposits money to an account (and creates a new one if it's not already existing) - - POST /account/withdraw - withdraws money from an account - -Error messages will be returned in case of any misuse of the application, e.g. withdrawing more money than an -account has etc. - -Getting started ---------------- - -To build a play-mini application you first have to make your object extend com.typesafe.play.mini.Application: - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: playMiniDefinition - -The next step is to implement the mandatory method ``route``: - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: route - :exclude: routeLogic - -It is inside the ``route`` method that all the magic happens. -In the sections below we will show how to set up play-mini to handle both GET and POST HTTP calls. - -Simple GET ----------- - -We start off by creating the simplest method we can - a "ping" method: - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: simpleGET - -As you can see in the section above play-mini uses Scala's wonderful pattern matching. -In the snippet we instruct play-mini to reply to all HTTP GET calls with the URI "/ping". -The ``Action`` returned comes from Play! and you can find more information about it `here `_. - -.. _Advanced-GET: - -Advanced GET ------------- - -Let's try something more advanced, retrieving parameters from the URI and also make an asynchronous call to an actor: - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: regexGET - -The regular expression looks like this: - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: regexURI - -In the snippets above we extract a URI parameter with the help of a simple regular expression and then we pass this -parameter on to the underlying actor system. As you can see ``AsyncResult`` is being used. This means that the call to -the actor will be performed asynchronously, i.e. no blocking. - -The asynchronous call to the actor is being done with a ``ask``, e.g.:: - - (accountActor ask Status(accountId)) - -The actor that receives the message returns the result by using a standard *sender !* -as can be seen here: - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: senderBang - -When the result is returned to the calling code we use some mapping code in Play to convert a Akka future to a Play future. -This is shown in this code: - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: innerRegexGET - -In this snippet we check the result to decide what type of response we want to send to the calling client. - -Using HTTP POST ---------------- - -Okay, in the sections above we have shown you how to use play-mini for HTTP GET calls. Let's move on to when the user -posts values to the application. - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: asyncDepositPOST - -As you can see the structure is almost the same as for the :ref:`Advanced-GET`. The difference is that we make the -``request`` parameter ``implicit`` and also that the following line of code is used to extract parameters from the POST. - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: formAsyncDepositPOST - -The code snippet used to map the call to parameters looks like this: - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - :include: form - -Apart from the mapping of parameters the call to the actor looks is done the same as in :ref:`Advanced-GET`. - -The Complete Code Sample ------------------------- - -Below is the complete application in all its beauty. - -Global.scala (/src/main/scala/Global.scala): - -.. includecode:: code/Global.scala - -PlayMiniApplication.scala (/src/main/scala/akka/docs/http/PlayMiniApplication.scala): - -.. includecode:: code/akka/docs/http/PlayMiniApplication.scala - -Build.scala (/project/Build.scala): - -.. code-block:: scala - - import sbt._ - import Keys._ - - object PlayMiniApplicationBuild extends Build { - lazy val root = Project(id = "play-mini-application", base = file("."), settings = Project.defaultSettings).settings( - libraryDependencies += "com.typesafe" %% "play-mini" % "2.0-RC3-SNAPSHOT", - mainClass in (Compile, run) := Some("play.core.server.NettyServer")) - } - -Running the Application ------------------------ - -Firstly, start up the application by opening a command terminal and type:: - - > sbt - > run - -Now you should see something similar to this in your terminal window:: - - [info] Running play.core.server.NettyServer - Play server process ID is 2523 - [info] play - Application started (Prod) - [info] play - Listening for HTTP on port 9000... - -In this example we will use the awesome `cURL `_ command to interact with the application. -Fire up a command terminal and try the application out:: - - First we check the status of a couple of accounts: - > curl http://localhost:9000/account/statement/TheDudesAccount - Unknown account: TheDudesAccount - > curl http://localhost:9000/account/statement/MrLebowskisAccount - Unknown account: MrLebowskisAccount - - Now deposit some money to the accounts: - > curl -d "accountId=TheDudesAccount&amount=1000" http://localhost:9000/account/deposit - Updated account total: 1000 - > curl -d "accountId=MrLebowskisAccount&amount=500" http://localhost:9000/account/deposit - Updated account total: 500 - - Next thing is to check the status of the account: - > curl http://localhost:9000/account/statement/TheDudesAccount - Account total: 1000 - > curl http://localhost:9000/account/statement/MrLebowskisAccount - Account total: 500 - - Fair enough, let's try to withdraw some cash shall we: - > curl -d "accountId=TheDudesAccount&amount=999" http://localhost:9000/account/withdraw - Updated account total: 1 - > curl -d "accountId=MrLebowskisAccount&amount=999" http://localhost:9000/account/withdraw - Unknown account or insufficient funds. Get your act together. - > curl -d "accountId=MrLebowskisAccount&amount=500" http://localhost:9000/account/withdraw - Updated account total: 0 - -Yeah, it works! -Now we leave it to the astute reader of this document to take advantage of the power of play-mini and Akka. \ No newline at end of file + libraryDependencies += "com.typesafe" %% "play-mini" % "" \ No newline at end of file diff --git a/project/AkkaBuild.scala b/project/AkkaBuild.scala index e7d3a071c7..e05e0f0b36 100644 --- a/project/AkkaBuild.scala +++ b/project/AkkaBuild.scala @@ -470,7 +470,7 @@ object Dependencies { val tutorials = Seq(Test.scalatest, Test.junit) - val docs = Seq(Test.scalatest, Test.junit, playMini) + val docs = Seq(Test.scalatest, Test.junit) val zeroMQ = Seq(Test.scalatest, Test.junit, protobuf, Dependency.zeroMQ) } @@ -482,8 +482,6 @@ object Dependency { object V { val Camel = "2.8.0" val Jackson = "1.8.0" - val JavaxServlet = "3.0" - val Jersey = "1.3" val Jetty = "7.4.0.v20110414" val Logback = "0.9.28" val Netty = "3.3.0.Final" @@ -494,7 +492,6 @@ object Dependency { val Slf4j = "1.6.4" val Spring = "3.0.5.RELEASE" val Zookeeper = "3.4.0" - val PlayMini = "2.0-RC1-SNAPSHOT" } // Compile @@ -530,8 +527,7 @@ object Dependency { val zkClient = "zkclient" % "zkclient" % "0.3" // ApacheV2 val zookeeper = "org.apache.hadoop.zookeeper" % "zookeeper" % V.Zookeeper // ApacheV2 val zookeeperLock = "org.apache.hadoop.zookeeper" % "zookeeper-recipes-lock" % V.Zookeeper // ApacheV2 - val zeroMQ = "org.zeromq" %% "zeromq-scala-binding" % "0.0.3" // ApacheV2 - val playMini = "com.typesafe" % "play-mini_2.9.1" % V.PlayMini + val zeroMQ = "org.zeromq" %% "zeromq-scala-binding" % "0.0.3" // ApacheV2 // Provided