Spray(13)REST API Project - Integrate with Spray Client
王渊
2023-12-01
Spray(13)REST API Project - Integrate with Spray Client
10. Integrate with Spray Client
10.1. Add the dependencies
in the build.sbt
"io.spray" % "spray-client" % "1.1-M7",
10.2. Initiate the Actor when Our system start
import akka.actor.Actor
import akka.actor.ActorSystem
import akka.actor.Props
import akka.actor.actorRef2Scala
import spray.can.server.HttpServer
import spray.io.IOExtension
import spray.io.SingletonHandler
import com.typesafe.config.ConfigFactory
import spray.routing.directives.PathMatcher
import shapeless._
import spray.routing.HttpServiceActor
import spray.can.client.DefaultHttpClient
import spray.client.HttpConduit
implicit val system = ActorSystem("on-spray-can")
val config = ConfigFactory.load()
//initiate the spray client actor
val httpClient = DefaultHttpClient(system)
val analyticsServerAddress: String = config.getString("analytics.server.address")
val analyticsServerPort: Int = config.getInt("analytics.server.port")
//actor which holds the connection pool to analytics remote server
val analyticsConduit = system.actorOf(
props = Props(new HttpConduit(httpClient, analyticsServerAddress, analyticsServerPort)),
name = "sillycat_conduit"
)
So we will name the spray client as "sillycat_conduit".
When we wants to use this actor.
Get the actorRefFActory in the BaseService
val sillycatRESTTemplate: SillycatRESTTemplate = SillycatRESTTemplate.apply(actorRefFactory)
And in the Template Class, I will get the actorRefFactory like this>
import akka.actor.{ Props, Actor }
import spray.routing._
import spray.routing.directives._
import spray.util.LoggingContext
import spray.http.StatusCodes._
import spray.httpx.SprayJsonSupport._
import shapeless._
import akka.actor._
import spray.routing.authentication._
import spray.client.HttpConduit
import spray.http.HttpRequest
import spray.http.HttpMethods
import scala.util.{ Success, Failure }
import akka.actor.{ Props, ActorSystem }
import spray.can.client.DefaultHttpClient
import spray.client.HttpConduit
import spray.httpx.SprayJsonSupport
import spray.http._
import spray.util._
import scala.concurrent.Future
import scala.concurrent.Await
import scala.concurrent.duration._
import org.joda.time.Period
import scala.slick.session.Database.threadLocalSession
import spray.json._
import scala.Predef._
class SillycatRESTTemplate(actorRefFactory: ActorRefFactory) {
val sillycat_conduit = actorRefFactory.actorFor("/user/sillycat_conduit") //actor name
val default_timeout = 30 second
…snip...
val pipeline = HttpConduit.sendReceive(analytics_conduit)
//post the data, prettyRequest is the JSON format data
val responseFuture = pipeline(HttpRequest(method = HttpMethods.POST, entity = prettyRequest, uri = "/dashboard/sillycat"))
//block result
val result = Await.result(responseFuture, default_timeout)
//I need to use block result here, because I need to put the response to client right now
val result_str = result.entity.toOption.get.asString
return result_str
}
11. Validation
I can add the validation everywhere if I want
require(List(7, 30, 90).contains(periodDays), "PeriodDays should be in List(7,30,90), but system gets periodDays = " + periodDays)
require(!stores.isEmpty, "There is no stores related to this tag, Tag = " + tag)
Because there is this kind of default handler there
implicit def myExceptionHandler(implicit log: LoggingContext) =
ExceptionHandler.fromPF {
case e: java.lang.IllegalArgumentException => ctx =>
log.warning("Request {} could not be handled normally", ctx.request)
ctx.complete(BadRequest, e.getMessage)
}
Actually when I dive into the source codes of scala, I saw the require is defined like this>
@inline final def require(requirement: Boolean, message: => Any) {
if (!requirement)
throw new IllegalArgumentException("requirement failed: "+ message)
}
12. How to Work with Actor
come soon...
13. Plain SQL for click
come soon…
Tips
1. How to delete branch in github
delete local branch
>git branch -d :branchName
delete remote branch
>git push origin :branchName
or
>git push origin --delete :branchName
But since I delete the remote branch from the GUI of github, I got these error message:
Carls-MacBook-Pro:winner-seller-server carl$ git push origin --delete another_auth
error: unable to delete 'another_auth': remote ref does not exist
error: failed to push some refs to 'https://github.com/luohuazju/magic.git'
But actually, when I check the all branch on my local, I saw the remote branch
>git branch -a
* master
remotes/origin/another_auth
remotes/origin/master
Solution:
Then only thing I need to do is to prune my local
>git remote prune origin
prune remotes any branch that does not exist in the remote origin anymore.
2. Permission denied while sbt command
[warn] exception occurred while writing properties file /Users/carl/.ivy2/cache/commons-codec/commons-codec/ivydata-1.4.properties: /Users/carl/.ivy2/cache/commons-codec/commons-codec/ivydata-1.4.properties (Permission denied)
Solution:
I do not know why, some of the directory are root under the .ivy. I am going to change them.
>sudo chown -R carl .ivy2/cache
References:
Spray 1 ~ 9
http://sillycat.iteye.com/blog/1766558
http://sillycat.iteye.com/blog/1766568
http://sillycat.iteye.com/blog/1857105
http://sillycat.iteye.com/blog/1858282
http://sillycat.iteye.com/blog/1858298
http://sillycat.iteye.com/blog/1859025
spray(10)
http://sillycat.iteye.com/blog/1872476
spray(11 12)
http://sillycat.iteye.com/blog/1882919
http://sillycat.iteye.com/blog/1882963