Reputation: 8043
I have a simple finagle service as follows:
import com.twitter.finagle.{Http,Service}
import com.twitter.util.{Await, Future}
import java.net.InetSocketAddress
import org.jboss.netty.handler.codec.http._
import org.jboss.netty.buffer.ChannelBuffers.copiedBuffer
import org.jboss.netty.util.CharsetUtil
import net.liftweb.json._
import com.twitter.finagle.http.{Request,Response,RichHttp}
import com.twitter.finagle.builder.ServerBuilder
case class Add(num1:Int, num2:Int)
case class Result(result:Int)
trait Transformer[R1,T,U,R2] {
def extractPayload(r:R1):T
def responsePayload(u:U):R2
}
object Transformer{
implicit object AddPayloadTransformer
extends Transformer[HttpRequest,Add,Result,HttpResponse]{
implicit val formats = DefaultFormats
def extractPayload(r:HttpRequest):Add = {
val body = r.getContent
val length = body.readableBytes()
val bytes = new Array[Byte](length)
body.getBytes(body.readerIndex(),bytes,0,length)
val bodyStr = new String(bytes)
parse(bodyStr).extract[Add]
}
def responsePayload(u:Result):HttpResponse = {
val result = u.result
val response = Response(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK)
response.setContentTypeJson()
response.setContentString(
s"""
{
"result": $result
}
""")
response.httpResponse
}
}
}
object AdditionServer extends App with Transformer[HttpRequest,Add,Result,HttpResponse]{
private def add(add:Add):Result = Result(add.num1 + add.num2)
private def additionHandler(req:HttpRequest): HttpResponse = {
val addPayload = extractPayload(req)
val result = add(addPayload)
responsePayload(result)
}
val service = new Service[HttpRequest,HttpResponse] {
def apply(req: HttpRequest): Future[HttpResponse] =
{
Future.value(additionHandler(req))
}
}
val server = Http.serve(":8080", service)
Await.ready(server)
println("Started service")
}
When I try to compile it, I get the following exception:
AdditionService.scala:49: object creation impossible, since:
[error] it has 2 unimplemented members.
[error] /** As seen from object AdditionServer, the missing signatures are as follows.
[error] * For convenience, these are usable as stub implementations.
[error] */
[error] def extractPayload(r: org.jboss.netty.handler.codec.http.HttpRequest): Add = ???
[error] def responsePayload(u: Result): org.jboss.netty.handler.codec.http.HttpResponse = ???
[error] object AdditionServer extends App with Transformer[HttpRequest,Add,Result,HttpResponse]{
[error] ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
To my knowledge I am implementing the traits with their proper signature.
Can somebody point out what might be going wrong here.
Thanks
Upvotes: 1
Views: 157
Reputation: 27692
AdditionServer
is the object which is extending Transformer
. In your code, this object is not defining neither extractPayload
nor responsePayload
thus the compilation error you get.
You should move your methods definitions from the trait companion object to AdditionServer
object AdditionServer extends App with
Transformer[HttpRequest,Add,Result,HttpResponse] {
import Transformer._
def extractPayload(r:HttpRequest):Add = {
val body = r.getContent
val length = body.readableBytes()
val bytes = new Array[Byte](length)
body.getBytes(body.readerIndex(),bytes,0,length)
val bodyStr = new String(bytes)
parse(bodyStr).extract[Add]
}
def responsePayload(u:Result):HttpResponse = {
val result = u.result
val response = Response(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK)
response.setContentTypeJson()
response.setContentString(
s"""
{
"result": $result
}
""")
response.httpResponse
}
}
If you'd rather keep your methods defined at the companion object you can refer to them from AdditionServer
:
object Transformer{
implicit object AddPayloadTransformer
extends Transformer[HttpRequest,Add,Result,HttpResponse]{
implicit val formats = DefaultFormats
def extractPayload(r:HttpRequest):Add = {
val body = r.getContent
val length = body.readableBytes()
val bytes = new Array[Byte](length)
body.getBytes(body.readerIndex(),bytes,0,length)
val bodyStr = new String(bytes)
parse(bodyStr).extract[Add]
}
def responsePayload(u:Result):HttpResponse = {
val result = u.result
val response = Response(HttpVersion.HTTP_1_1,
HttpResponseStatus.OK)
response.setContentTypeJson()
response.setContentString(
s"""
{
"result": $result
}
""")
response.httpResponse
}
}
}
object AdditionServer extends App with
Transformer[HttpRequest,Add,Result,HttpResponse]{
def extractPayload(r:HttpRequest):Add = Transformer.extractPayload(r)
def responsePayload(u:Result):HttpResponse = Transformer.responsePayload(u)
...
...
Upvotes: 2