How can I use ANORM in play console? - scala

I'd like to use ANORM to connect to db in play console, just simply test some stuff. But there's some errors when I create a DataSource
val ds=DB.getDataSource()
java.lang.RuntimeException: There is no started application

You can start an application from within the play console:
[My application] $ console
scala> import play.core.StaticApplication
import play.core.StaticApplication
scala> new StaticApplication(new java.io.File("."))
[info] play - Application started (Prod)
res0: play.core.StaticApplication = play.core.StaticApplication#...

Related

How to run sample Scala vertx project

I started new project using sbt new vert-x3/vertx-scala.g8 command. In sbt console entered following command :
vertx.deployVerticle(nameForVerticle[HttpVerticle])
The following error is reported:
vertx.deployVerticle(nameForVerticle[HttpVerticle])
<console>:12: error: not found: value vertx
vertx.deployVerticle(nameForVerticle[HttpVerticle])
^
<console>:12: error: not found: value nameForVerticle
vertx.deployVerticle(nameForVerticle[HttpVerticle])
^
<console>:12: error: not found: type HttpVerticle
Followed the steps specified on this page: https://github.com/vert-x3/vertx-sbt-starter
How to get sample project running?
I think g8 template is a little bit broken. I made it work using below tricks:
Use latest SBT version 1.2.8 in file: project/build.properties
When you run console, import HttpVerticle class manually. In my case, I have test.HttpVerticle as class name. Because I used package name as 'test', when I was running SBT new command to initialise the project
scala> import test.HttpVerticle
scala> vertx.deployVerticle(nameForVerticle[HttpVerticle])
// This stuff is going to printed in a second:
scala> Thread Thread[vert.x-eventloop-thread-0,5,run-main-group-0] has been blocked for 2377 ms, time limit is 2000
Thread Thread[vert.x-eventloop-thread-0,5,run-main-group-0] has been blocked for 3378 ms, time limit is 2000
Thread Thread[vert.x-eventloop-thread-0,5,run-main-group-0] has been blocked for 4384 ms, time limit is 2000
And then try to trigger the server:
curl http://localhost:8666/hello
It should reply with "world".
Again, as for class name. If you didn't use any package name when running sbt new initialisation process, then try just import class like this: import HttpVerticle

Play mocking web service behind a proxy

I'm using the Play framework 2.5. I created a new project and tried testing web service.
For the moment I just copied the example at https://www.playframework.com/documentation/2.5.x/ScalaTestingWebServiceClients#testing-a-github-client .
On my machine I'm using a proxy, and when running GitHubClientSpec
testOnly GitHubClientSpec
I get an error from the proxy as response.
What I also tried from the scala console is the piece of code :
import play.core.server._
import play.api.routing.sird._
import play.api.mvc._
val server = NettyServer.fromRouter(ServerConfig(
port = Some(19000),
address = "127.0.0.1"
)) {
case GET(p"/hello") => Action {
Results.Ok(s"Hello")
}
}
And curl http://localhost:19000/hello, returned "Hello".
So this works fine, but when running testOnly GitHubClientSpec it is not.
How to prevent Play from using the proxy ?

Play2 & ReactiveMongo testing issue: db connection right after test fails

I am implementing a file storage service, which is taking a file and saving it into gridFS with special metadata. Of course, I want to be sure everything's working in integration -- files are really stored in database and then retrieved from it.
I use Play Framework 2.1.3 Scala and ReactiveMongo 0.9.
My test cases looks like the following:
"show empty uploaded size on init" in {
running(FakeApplication()) {
Await.result(FileStorage.getFilesSize(profileId), duration) must beNone
}
}
I have tried to wrap every case with running, or all cases, or even Thread.sleep. But database is always up after test fails.
[error] There is no started application
[error] play.api.Play$$anonfun$current$1.apply(Play.scala:51)
[error] play.api.Play$$anonfun$current$1.apply(Play.scala:51)
[error] play.api.Play$.current(Play.scala:51)
[error] content.FileStorage$.db$lzycompute(FileStorage.scala:32)
...
[info] Total for specification FileStorageSpec
[info] Finished in 21 ms
[info] 5 examples, 1 failure, 4 errors
[info]
[info] application - ReactiveMongoPlugin starting...
[info] application - ReactiveMongoPlugin successfully started with db 'test'! Servers:
[localhost:27017]
[info] play - Starting application default Akka system.
[info] play - Shutdown application default Akka system.
What am I doing wrong? How do you test ReactiveMongo applications?
In the FileStorage object you have these lines:
lazy val db = ReactiveMongoPlugin.db
val gridFS = GridFS(db, "file")
val collection = db.collection[JSONCollection]("file.files")
collection.indexesManager.ensure(Index(Seq("metadata.profileId" -> IndexType.Ascending)))
When the object is instantiated, the above lines of code are executed. Since you have no control of object instantiation you can not be sure when that happens.
It will probably help to change the lines into this:
def db = ReactiveMongoPlugin.db
def gridFS = GridFS(db, "file")
def collection = {
val collection = db.collection[JSONCollection]("file.files")
collection.indexesManager.ensure(Index(Seq("metadata.profileId" -> IndexType.Ascending)))
collection
}

How to do error logging when Play 2.1 crashes on startup

I have a Play 2.1 application which does not start when I have the wrong database url. The problem is, the error message isn't that great.
[error] c.j.b.h.AbstractConnectionHook - Failed to obtain initial connection Sleeping for 0ms and trying again. A ttempts left: 0. Exception: null
Oops, cannot start the server.
Configuration error: Configuration error[Cannot connect to database [default]]
at play.api.Configuration$.play$api$Configuration$$configError(Configuration.scala:74)
at play.api.Configuration.reportError(Configuration.scala:552)
at play.api.db.BoneCPPlugin$$anonfun$onStart$1.apply(DB.scala:248)
at play.api.db.BoneCPPlugin$$anonfun$onStart$1.apply(DB.scala:239)
....
I'd like the server to dump the database url it's trying to use in this case. Does Play 2.1 provide any hooks to execute code when there is an exception during startup?
In Play Framework 2, you can override certain phases of the lifecycle by extending GlobalSettings. Specifically, onLoadConfig get called before the config is parsed and the DB connection is established.
Here's a (hacky) example of intercepting errors. You can create a fake instance of Application, then pass it the Configuration object. Then you can use it to create an instance of BoneCPPlugin and try creating a connection. In case when the DB is not reachable, you'll be able to intercept that in the catch block.
import java.io.File
import play.api._
import play.api.db.BoneCPPlugin
import scala.util.control.NonFatal
object Global extends GlobalSettings {
override def onLoadConfig(config: Configuration, path: File, classloader: ClassLoader, mode: Mode.Mode) = {
val app = new DefaultApplication(path, classloader, None, mode){
override lazy val configuration = config
}
try {
new BoneCPPlugin(app).onStart()
} catch {
case e: PlayException =>
// handle
case _ => // other types of errors that we don't care about here
}
super.onLoadConfig(config, path, classloader, mode)
}
}

How do I run multiple functional specs with TestServer in Play 2.0.1?

I am having problems running multiple functional specs (using specs2), specifically tests that start a TestServer, open an HTMLUNIT browser, and navigate to a page to check an element. The page in question loads the elements that we test on an ajax request. The wait for the element to be present times out with the error message below.
Code snippet:
trait CommonSteps extends BaseSpecfication {
val testServer: TestServer = TestServer(3333)
val testServerBaseURL: String = "http://localhost:3333/"
override def map(fs: => Fragments) =
Step(testServer.start()) ^ super.map(fs) ^ Step(testServer.stop())
}
class FunctionalTest1 extends Specification with CommonSteps { def is =
...
... extends When[...] {
val browser: TestBrowser = TestBrowser.of(HTMLUNIT)
browser.goTo(testServerBaseURL + "/some_path")
browser
}
... extends Then[...] {
browser.await.until("element that is loaded on ajax request").isPresent()
...
}
}
We get the error:
Caused by: java.sql.SQLException: Attempting to obtain a connection from a pool that has already been shutdown.
Stack trace of location where pool was shutdown follows:
java.lang.Thread.getStackTrace(Thread.java:1479)
com.jolbox.bonecp.BoneCP.captureStackTrace(BoneCP.java:543)
com.jolbox.bonecp.BoneCP.shutdown(BoneCP.java:159)
com.jolbox.bonecp.BoneCPDataSource.close(BoneCPDataSource.java:123)
play.api.db.BoneCPApi.shutdownPool(DB.scala:387)
play.api.db.BoneCPPlugin$$anonfun$onStop$1.apply(DB.scala:252)
play.api.db.BoneCPPlugin$$anonfun$onStop$1.apply(DB.scala:250)
scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
scala.collection.immutable.List.foreach(List.scala:45)
play.api.db.BoneCPPlugin.onStop(DB.scala:250)
play.api.Play$$anonfun$stop$1$$anonfun$apply$1.apply(Play.scala:75)
play.api.Play$$anonfun$stop$1$$anonfun$apply$1.apply(Play.scala:74)
scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
scala.collection.immutable.List.foreach(List.scala:45)
play.api.Play$$anonfun$stop$1.apply(Play.scala:74)
play.api.Play$$anonfun$stop$1.apply(Play.scala:74)
scala.Option.map(Option.scala:133)
play.api.Play$.stop(Play.scala:73)
play.core.server.NettyServer.stop(NettyServer.scala:73)
While the test works when run in isolation, we get the error when running two or more of them together.
It seems to be related to this issue, though my example is a Scala Play app. Can anyone confirm that this issue is fixed in a newer version of Play? Or, is there a workaround to avoid this error in Play 2.0.1.
This issue will be fixed in Play 2.0.2, which is currently in RC state. It is safe to upgrade from 2.0.1 to 2.0.2, as everything is backwards compatible.
Thanks to #guillaume-bort for providing this information.