Scala Compilation Error on Vert.x - scala

I'm not a Scala Expert. I just want to run a simple example Verticle on Vert.x.
class ScalaServer extends Verticle {
override def start() {
vertx.setPeriodic(1000, { timerId: Long =>
vertx.eventBus.publish("news-feed", "News from Scala")
})
}
}
But when I run this code on Vert.x the compiler complains with the following message:
error: type mismatch;
found : scala.Long => org.vertx.java.core.eventbus.EventBus
required: org.vertx.java.core.Handler[java.lang.Long]
vertx.setPeriodic(1000, { timerId: Long =>
^
Maybe there is someone out there who sees the error right away.

found : scala.Long => org.vertx.java.core.eventbus.EventBus
required: org.vertx.java.core.Handler[java.lang.Long]
Try follow:
class ScalaServer extends Verticle {
override def start() {
vertx.setPeriodic(1000, new Handler[java.lang.Long]() {
def handle(timerID: java.lang.Long) = {
vertx.eventBus.publish("news-feed", "News from Scala")
}
});
}
}

Related

found : akka.http.scaladsl.server.StandardRoute [error] required: scala.util.Try

I am new to Scala and to akka i am trying to publish endpoint. Following compilation error is occurring.
found: akka.http.scaladsl.server.StandardRoute
[error] required: scala.util.Try[Option[com.activegrid.entities.AuthSettings]] => (akka.http.scaladsl.server.RequestContext => scala.concurrent.Future[akka.http.scaladsl.server.RouteResult])
Case class
case class AuthSettings(authType:String,authLevel:String,scope:String);
Enpoint
pathPrefix("config") {
path("settings"/"auth") {
post {
entity(as[AuthSettings]) { authSettings =>
val save: Future[AuthSettings] = persistance.persistAuthSettings(authSettings)
onComplete(save) {
complete("To insert app settings")
}
}
}
}
persistAuthSettings definition
def persistAuthSettings(authSettings: AuthSettings) : Future[AuthSettings] = Future {
//Neo4j Operations
authSettings;
}
What is going wrong in my code?
onComplete extracts the value from the future, and requires a function which operates on this value:
onComplete(save) { appSettings =>
complete("To insert app settings")
}

Scala Future strange compile error

Code below is a simplified version of the real code. We "inherited" the domain model case object FutTest and case class FutTest, which we can't modify. The actual domain models are served from a Database, so I believe the Future approach is valid, but it causes problems which I don't understand.
import org.scalatest.FunSpec
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
case object FutTest {
def create(sz: Int) = { FutTest(sz) }
}
case class FutTest(size: Int)
class FutureTest extends FunSpec {
def one(v: Int): Future[FutTest] = {
Future { FutTest.create(v) }
}
def two(t: FutTest) = {
Future { FutTest.create(t.size) }
}
def compileError1: Future[FutTest] = {
one(10).map(f => two(f))
}
def compileError2: Future[FutTest] = {
for { o <- one(10) } yield (two(o))
}
}
The error messages:
[INFO] Using incremental compilation
[INFO] Compiling 7 Scala sources and 5 .. target/test-classes...
[ERROR] domain.FutureTest.scala:25: type mismatch;
found : scala.concurrent.Future[domain.FutTest]
required: domain.FutTest
[ERROR] one(10).map(f => two(f))
[ERROR] ^
[ERROR] domain/FutureTest.scala:29: type mismatch;
found : scala.concurrent.Future[domain.FutTest]
required: domain.FutTest
[ERROR] for { o <- one(10) } yield (two(o))
I tried the above code with plain Int instead of FutTest and all is fine. Why is the compiler complaining and how can we solve this without touching the existing domain.
flatMap is what you want.
one(10).flatMap(f => two(f))
or
one(10).flatMap(two)
Using for comprehension,
for { o <- one(10); t <- two(o) } yield t
One() returns a Future and two() also returns a Future so you need to flatMap instead of map. When you map to two(), your result is Future[Future[FutTest]] and needs to be flattened.
Doing
one(10).flatMap(f => two(f))
should do the trick.

Mockito with Dependency Injection

I'm using Play Framework 2.5 and trying to test one of my DAO class based on the example here.
But my class under test has dependency injection and I wonder how to mock it.
I tried to do something but it seems a bit clumsy, and I would like help to improve it.
Here is my code :
class MyController #Inject()(val mydao: MyDAOClass) extends Controller {
def getData = Action { request =>
mydao.fetchData
}
}
class MyDAOClass #Inject()(ws: WSClient) {
def urls(): List[String] = { List("url1", "url2") }
// fetch data on different servers and should merge it.
def fetchData(): Future[List[String]] = {
val futures: List[Future[WSResponse]] = urls map { url =>
ws.url(url + "/some/data").withRequestTimeout(10000.millis).get()
}
futures map { future =>
future onComplete {
case Success(resp) => println(resp.json)
case Failure(t) => println("An error has occured: " + t.printStackTrace)
}
}
Future(List())
}
}
Here is my test code :
trait DAOTrait {
def urls: List[String]
}
class MyDAOClass extends PlaySpec with MockitoSugar {
"MyDAOClass" should {
"get a list of data" in {
Server.withRouter() {
case GET(p"/url1/some/data") => Action {
Results.Ok(Json.arr(Json.obj("name" -> "data1")))
}
} { implicit port =>
val mockMyDAOClass = mock[DAOTrait]
when(mockMyDAOClass.urls) thenReturn List("url1")
implicit val materializer = Play.current.materializer
WsTestClient.withClient { client =>
val mydao = new MyDAOClass(client) {
override def urls = mockMyDAOClass.urls
}
val result = Await.result(
mydao.fetchData(), 10.seconds)
result mustEqual List("data1")
}
}
}
}
}
The code is not finished in MyDAOClass, but it is enough to start implementing tests.
1) How to mock class that have dependency injection ?
2) When testing this code I have the following exception in MyDAOClass case Failure(t)
java.net.ConnectException: http://localhost:40183
at org.asynchttpclient.netty.channel.NettyConnectListener.onFailure(NettyConnectListener.java:137)
at org.asynchttpclient.netty.request.NettyChannelConnector$1.onFailure(NettyChannelConnector.java:106)
at org.asynchttpclient.netty.SimpleChannelFutureListener.operationComplete(SimpleChannelFutureListener.java:28)
at org.asynchttpclient.netty.SimpleChannelFutureListener.operationComplete(SimpleChannelFutureListener.java:20)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:683)
at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:604)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:564)
at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:425)
at io.netty.channel.nio.AbstractNioChannel.doClose(AbstractNioChannel.java:462)
at io.netty.channel.socket.nio.NioSocketChannel.doClose(NioSocketChannel.java:236)
at io.netty.channel.AbstractChannel$AbstractUnsafe.doClose0(AbstractChannel.java:611)
at io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:590)
at io.netty.channel.AbstractChannel$AbstractUnsafe.close(AbstractChannel.java:534)
at io.netty.channel.nio.NioEventLoop.closeAll(NioEventLoop.java:576)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:361)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.nio.channels.ClosedChannelException
but it should return Result.Ok instead.
3) Any advice welcome.

Can't access generic function type in a inner PartialFunction

I am currently writing a generic function to execute Dispatch async requests, but I can't access generic type in Dispatch handler:
private def execQuery[MessageType](query : Req, errorMsg : String)
{
Http(query OK as.String).either
.onSuccess
{
case Left(error) => println(errorMsg)
case Right(json) => println( new MessageType(json) ) // error here
}
}
I have an error on new MessageType : "Cannot resolve symbol MessageType" in "new MessageType(json)".
Can you help me ?
Thank you in advance
Victor
EDIT : I have found an other interesting way here http://www.brentsowers.com/2011/11/writing-generic-functions-that-take.html. You have to use the manifest feature :
class DynamicTestClass() {
def output() {
println("Hello from a dynamically sent class")
}
}
def testFunc[T : Manifest]() : T = {
manifest[T].erasure.newInstance().asInstanceOf[T]
}
val dynamicTestClassInstance = testFunc[DynamicTestClass]()
dynamicTestClassInstance.output()
It seems to work !
You can't do
def mustMakeA[A](b:String):A = new A(b)
in scala.
A few practical reason. How is scalac supposed to know if A has public constructors and its argument?
However you can use a smarter design, for example, a type class that "knows" how to construct the parameter:
class Message(val value:String)
trait Constructor[A] {
def cons(b:String)
}
implicit class MessageHasConstructor(m:Message) extends Constructor[Message] {
def cons(b:String) = new Message(b)
}
Et voilĂ , now we rewrite our mustMakeA as:
def mustMakeA[A:Constructor](b:String):A = implicitly[Constructor[A]].cons(b)
mustMakeA[Message]("Example") // would give us a `new Message("Example")`
Btw, I didn't test the code, so it might require some tweaking.

Type mismatch when using Scala Trait in Play?

Using the Play! Framework 1.2.4. I've got a nifty trait that checks an API key and HTTPS, but if I want to access the account associated with that key and reference it in my controller, it throws a type mismatch; found : java.lang.Object required: Long
So here's my API controller (incomplete):
object API extends Controller with Squeryl with SecureAPI {
import views.API._
def job(param:String) = {
val Job = models.Job
param match {
case "new" => Job.createFromParams(params,thisAccount) //thisAccount comes from the trait
case "update" =>
case "get" =>
case "list" =>
}
}
}
and the secure trait:
trait SecureAPI {
self:Controller =>
#Before
def checkSecurity(key:String) = {
if(!self.request.secure.booleanValue) {
Redirect("https://" + request.host + request.url);
} else {
models.Account.getByKey(key) match {
case Some(account) => {
renderArgs += "account" -> account.id
Continue
}
case _ => Forbidden("Key is not authorized.")
}
}
}
def thisAccount = renderArgs("account").get
}
How would I properly access thisAccount? Thanks
Your problem is simply that renderArgs is only declared to return an Object from its get call (which is fair enough because it could be just about anything).
Consequently the inferred type of your thisAccount method will be () => Object.
You'll need to cast the returned type into a Long, something like (though perhaps with some error-checking):
def thisAccount = renderArgs("account").get.asInstanceOf[Long]