Revision d818f53c src/main/scala/gr/grnet/aquarium/actor/service/rest/RESTActor.scala
b/src/main/scala/gr/grnet/aquarium/actor/service/rest/RESTActor.scala | ||
---|---|---|
40 | 40 |
import cc.spray.can.HttpMethods.GET |
41 | 41 |
import cc.spray.can._ |
42 | 42 |
import gr.grnet.aquarium.util.Loggable |
43 |
import net.liftweb.json.JsonAST.JValue |
|
44 |
import net.liftweb.json.{JsonAST, Printer} |
|
45 | 43 |
import gr.grnet.aquarium.Configurator |
46 | 44 |
import akka.actor.Actor |
47 | 45 |
import gr.grnet.aquarium.actor.{RESTRole, RoleableActor, RouterRole} |
48 | 46 |
import RESTPaths.{UserBalancePath, UserStatePath, AdminPingAll} |
49 | 47 |
import com.ckkloverdos.maybe.{NoVal, Just} |
50 |
import message.service.router._ |
|
51 | 48 |
import gr.grnet.aquarium.util.date.TimeHelpers |
52 | 49 |
import org.joda.time.format.ISODateTimeFormat |
50 |
import gr.grnet.aquarium.actor.message.admin.PingAllRequest |
|
51 |
import gr.grnet.aquarium.actor.message.{RouterResponseMessage, GetUserStateRequest, RouterRequestMessage, ActorMessage, GetUserBalanceRequest} |
|
53 | 52 |
|
54 | 53 |
/** |
55 | 54 |
* Spray-based REST service. This is the outer-world's interface to Aquarium functionality. |
... | ... | |
61 | 60 |
|
62 | 61 |
self.id = _id |
63 | 62 |
|
64 |
private def jsonResponse200(body: JValue, pretty: Boolean = false): HttpResponse = { |
|
65 |
val stringBody = Printer.pretty(JsonAST.render(body)) |
|
66 |
stringResponse200(stringBody, "application/json") |
|
67 |
} |
|
68 |
|
|
69 | 63 |
private def stringResponse(status: Int, stringBody: String, contentType: String = "application/json"): HttpResponse = { |
70 | 64 |
HttpResponse( |
71 | 65 |
status, |
... | ... | |
106 | 100 |
//+ Main business logic REST URIs are matched here |
107 | 101 |
val millis = TimeHelpers.nowMillis() |
108 | 102 |
uri match { |
109 |
case UserBalancePath(userId) ⇒
|
|
110 |
callDispatcher(RequestUserBalance(userId, millis), responder)
|
|
103 |
case UserBalancePath(userID) ⇒
|
|
104 |
callRouter(GetUserBalanceRequest(userID, millis), responder)
|
|
111 | 105 |
|
112 | 106 |
case UserStatePath(userId) ⇒ |
113 |
callDispatcher(UserRequestGetState(userId, millis), responder)
|
|
107 |
callRouter(GetUserStateRequest(userId, millis), responder)
|
|
114 | 108 |
|
115 | 109 |
case AdminPingAll() ⇒ |
116 | 110 |
val mc = Configurator.MasterConfigurator |
... | ... | |
118 | 112 |
case Just(adminCookie) ⇒ |
119 | 113 |
headers.find(_.name.toLowerCase == Configurator.HTTP.RESTAdminHeaderNameLowerCase) match { |
120 | 114 |
case Some(cookieHeader) if(cookieHeader.value == adminCookie) ⇒ |
121 |
callDispatcher(AdminRequestPingAll(), responder)
|
|
115 |
callRouter(PingAllRequest(), responder)
|
|
122 | 116 |
|
123 | 117 |
case Some(cookieHeader) ⇒ |
124 | 118 |
logger.warn("Admin request with bad cookie '{}' from {}", cookieHeader.value, remoteAddress) |
... | ... | |
148 | 142 |
|
149 | 143 |
|
150 | 144 |
private[this] |
151 |
def callDispatcher(message: RouterMessage, responder: RequestResponder): Unit = {
|
|
145 |
def callRouter(message: RouterRequestMessage, responder: RequestResponder): Unit = {
|
|
152 | 146 |
val configurator = Configurator.MasterConfigurator |
153 | 147 |
val actorProvider = configurator.actorProvider |
154 | 148 |
val router = actorProvider.actorForRole(RouterRole) |
... | ... | |
166 | 160 |
|
167 | 161 |
case Some(Right(actualResponse)) ⇒ |
168 | 162 |
actualResponse match { |
169 |
case dispatcherResponse: RouterResponseMessage if (!dispatcherResponse.isError) ⇒ |
|
170 |
//logger.debug("Received response: %s".format(dispatcherResponse)) |
|
171 |
//logger.debug("Received response (JSON): %s".format(dispatcherResponse.toJson)) |
|
172 |
//logger.debug("Received response:body %s".format(dispatcherResponse.responseBody)) |
|
173 |
//logger.debug("Received response:body (JSON): %s".format(dispatcherResponse.responseBodyToJson)) |
|
174 |
responder.complete( |
|
175 |
HttpResponse( |
|
176 |
status = 200, |
|
177 |
body = dispatcherResponse.responseBodyToJson.getBytes("UTF-8"), |
|
178 |
headers = HttpHeader("Content-type", "application/json;charset=utf-8") :: Nil)) |
|
179 |
|
|
180 |
case dispatcherResponse: RouterResponseMessage ⇒ |
|
181 |
logger.error("Error serving %s: Dispatcher response is: %s".format(message, actualResponse)) |
|
182 |
responder.complete(stringResponse(500, "Internal Server Error", "text/plain")) |
|
163 |
case routerResponse: RouterResponseMessage[_] ⇒ |
|
164 |
routerResponse.response match { |
|
165 |
case Left(error) ⇒ |
|
166 |
logger.error("Error %s serving %s: Response is: %s".format(error, message, actualResponse)) |
|
167 |
responder.complete(stringResponse(500, "Internal Server Error", "text/plain")) |
|
168 |
|
|
169 |
case Right(response) ⇒ |
|
170 |
responder.complete( |
|
171 |
HttpResponse( |
|
172 |
status = 200, |
|
173 |
body = routerResponse.responseToJsonString.getBytes("UTF-8"), |
|
174 |
headers = HttpHeader("Content-type", "application/json;charset=utf-8") :: Nil)) |
|
175 |
} |
|
183 | 176 |
|
184 | 177 |
case _ ⇒ |
185 |
logger.error("Error serving %s: Dispatcher response is: %s".format(message, actualResponse))
|
|
178 |
logger.error("Error serving %s: Response is: %s".format(message, actualResponse))
|
|
186 | 179 |
responder.complete(stringResponse(500, "Internal Server Error", "text/plain")) |
187 | 180 |
} |
188 | 181 |
} |
Also available in: Unified diff