register
other register

Tuesday, April 30, 2013

Tuning Play Framework Application with JVM settings.

-Xms Sets the initial heap memory size for the JVM
-Xmx Sets the maximum heap memory the JVM allows grow up to.
-XX:+UserParalleGC This instructs the JVM to make better user of multiple processors or cores

For a Play Framework application. Edit the .bash_profile 

export _JAVA_OPTIONS="-Xms768m -Xmx1024m -XX:+UseParallelGC"

Then do: . ~/.bash_profile

When running the application by: play run

You will notice from the console that:

Picked up _JAVA_OPTIONS: -Xms768m -Xmx1024m -XX:+UseParallelGC

Tuesday, July 03, 2012

Unit Test with Play Framework Sync or Async


The code below illustrate how to do response in sync mode using Play Framework.

object Deals extends Controller {
  def read(id: Long) = Action {
      Ok(readFile(new File("public/files/api/deals/deal.id.get.json"))).as("application/json").withHeaders(
      "Access-Control-Allow-Origin" -> "*",
      "Content-Type" -> "application/vnd.yell.deals.deal-v2+json,application/json; charset=utf-8")
  }
}
Unit test the controller action using scala specs2:

import org.specs2.mutable.Specification
class DealsMockSpec extends Specification {

  def jsonString = "{\"name\": \"jet\"}"
  val jsonPayload: JsValue = Json.parse(jsonString)
 
  "read action" in {
    val url = controllers.routes.Deals.read(3).url
    val result = controllers.Deals.read(3)(FakeRequest(GET, url))

    status(result) must equalTo(OK)
    header("Access-Control-Allow-Origin", result) must beSome("*")
    header("Content-Type", result).head must contain("-v")
  }
}
Using Play Framework to do async programming is really simple. Let's modify the above controller/action code with async features:

Object MyController extends Controller {

  def read(id: Long) = Action {
    val promiseOfString : Promise[String] = Akka.future { readFile(new File("public/files/api/deals/deal.id.get.json")) }
    Async {
    promiseOfString.map(content => Ok(content).as("application/json").withHeaders(
    "Access-Control-Allow-Origin" -> "*",
    "Content-Type" -> "application/vnd.yell.deals.deal-v2+json,application/json; charset=utf-8"))
    }
  }
}


Async code complains about "RuntimeException: There is no started application" when running the above unit test code. 
  
We have to tell Play! to using a TestServer so that it can handle Promise[ws.Response] which the WS.url("http://localhost:3333/deals/deal/3" will return.

"read action" in {
    running(TestServer(3333)) {
      val result : ws.Response = (WS.url("http://localhost:3333/api/deals/deal/3")).get.await(500).get
      result.status must equalTo(OK)
      result.header("Content-Type").head must contain ("-v")
      result.header("Access-Control-Allow-Origin").head must contain ("*")
    }
  }

Now run:

$play test 

It will pass. And because it is unit test, the speed is much faster than the functional test which requires the application server fully running. 

Monday, July 02, 2012

What a mock application can do for you?


Recently I developed a mock web application based on a RESTful web service specification.

A mock web application can serve as a black box which responses based on the request (i.e. URI and HTTP method). It is easy to set up to implement the API specification.

Request method: GET
Request URI: /api/person/3

Response status code: 200
Response message:  {"name": "jianfeng"} // JSON

In an agile team, the backend dev can be the blocker in different development stages and the mock application can remove the blocker and let different development process (i.e front end, functional test, performance test) go in parallel with backend development..

Blocker 1 - for front end dev

If an agile team is composed of backend and frontend dev, and the front end dev consumes the apis developed by the backend dev. And then here is the blocker and waiting game for the frontend dev, as the backend api is in developing and can be buggy when released.

In this scenario, a mock application can help the frontend dev to continue with their development by calling the mock application instead of the real api. And when the backend dev finishes the api, then the frontend can switch the calling to it.

Blocker 2 - for functional testers

In an agile team, the functional testers can develop their automated script based on the API specification. But their script can only be verified when the backend dev finish their API development. And the testers might rework on their script by then.

The functional testers can verify their automated script by running it against the mock application, make the switch to the real API when the backend dev finish it.

Blocker 3 - for performance testers

In an agile team the performance tester normally get involved at the later stage - when the backend dev finish their API and the functional testers have tested it.

In this scenario, a mock application can let the performance testers start at an early stage. They don't have to wait for the backend dev to finish their API. Instead they can simply make their performance test calls to the mock application.

Wednesday, June 20, 2012

Validate json files in sub directories

import scala.io.Source._
import scala.util.parsing.json.JSON
import java.io._

object JsonValidator {
  def main(args: Array[String]) {

    for (file <- recursiveListFiles(new File(".")).filter(_.getName.endsWith(".json"))) {
      val json = JSON.parseFull(fromFile(file).getLines mkString)
      if (json.isEmpty)  // if json file is not valid json
        println(file + ": " + json)
    } 
  }

  def recursiveListFiles(f: File): Array[File] = {
    val these = f.listFiles
    these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)
  }
}

Thursday, November 03, 2011

Initialising in Grails Service

Attributes can be initialised from config in grails service by implementing the Spring InitializingBean interface. In the afterPropertiesSet method, set the attributes.

class SomeService implements InitializingBean {
def grailsApplication
private static String TOKEN

void afterPropertiesSet() {
TOKEN = grailsApplication.config.token
println this
}

def someMethod() {
println TOKEN
println this
}
}

In unit and integration test, the afterPropertiesSet method has to be called otherwise the TOKEN won't be set. But noticeably, in unit test, the instances printed out by 'println this' are different, although grails service by default is a singleton implementation; but in integration test, the instance from 'println this' is the same.

In unit test:

@Before
void setUp() {
service.afterPropertiesSet()
}
}

In integration test:

private static service

@BeforeClass
static void fixtureSetUp() {
service.afterPropertiesSet()
}

Saturday, October 22, 2011

Grails Service Singleton

Jeff Brown explained Grails singleton service in Nabble. Below is his description.

"If your service has an instance variable (that is state) and you don't want that state to be shared by multiple concurrent users of the service, then you don't want that service to be a singleton. If a service is a singleton then every user of that service is sharing the same copy of the service. If a service is request scoped then a new instance is created for every http request. If a service is sessions scoped then the service will be kept around and reused for the entire user session (each user session has their own copy). "

Thursday, October 20, 2011

Cannot get property 'config' on null object in Grails Integration Test

Class someService {

def grailsApplication

def someMethod() {

def attribute = grailsApplication.config.someAttribute
return attribute
}
}

When running integration test,

Class someServiceTests {

@Test
void testSomeMethod() {
def service = new SomeService()
def attribute = service.someMethod()
}
}

It will complain that:

"java.lang.NullPointerException: Cannot get property 'config' on null object"

The way around this is, in the integration test, add the following line:

service.grailsApplication = new DefaultGrailsApplication()