Wednesday, September 18, 2013

Play2 @CloudBees

Play2 @CloudBees


CloudBees & Play2 Java?


CloudBees gives you kickstart, if you are a Scala fellow. They build you app with everything included, deploy it, and you just need to get it down to your own sandbox to develop it further. 

For Play2 Java they don't offer same option. Java can be taken in use without problems, anyway, since you just need to add needed dependencies for libraries you use and start coding.

http://www.playframework.com/documentation/2.2.x/Deploying-to-CloudBees

Recipe


Register free account 

Create Play2 app at Clickstart

Test your app

Find url to repository

Clone app

Make changes


Edit templates
  • any file goes, but on scala html templates you see changes right away
  • example, file: app/views/index.scala.html, change text: "What's your name"

Push changes
  • git add -A
  • git commit -m 'change'
  • git push origin master

Test your app again

Further steps


CloudBees goes on Play2 in full Scala mode - also: example app created by ClickStart doesn't have Java option. Fine for many, but I wanted still to work with Java, and so do many of us - old legacy java coders don't convert to Scala overnight, and neither do managers.

I felt CloudBees bit confusing. There's couple of deploying options for changes, couple of ways developing your initial seed app, and it was not cleat to me what is preferred way. I tried plugins and git deployments, and managed to push post my changes to git and deploy new version of app  to CloudBees, but I didn't feel it intuitive to control deployments.

Tuesday, September 17, 2013

Play2 @Heroku

Play2 @Heroku 

It's professional to keep your app running smoothly 

We all want to share some high time after being so many times left alone and down with self deployed brittle single server solutions. No matter if it was ok for customers to have unreliable and unscalable solution, it didn't ever felt good to me.

Play2 is excellent fit for shared computing resources as it's 100% asynchronous and stateless. Heroku is just one platform for your Play2 app, but as it's simple to use and has native support I recommend you to take a look.


Howto


Herokus Play2 support works seamlessly if your application is at root of your repository. To ensure this you may need move it there. More of it later.


Ingredients


  • Play2
  • Git
  • Heroku Toolbelt
You propably have Play2 and Git installed, so just go here to get Toolbelt https://toolbelt.heroku.com/


Baking


Go to your github account or create one

Create github repository 
  • heroku-play2
  • PlayFramework as gitignore
Clone repository to local disk 
Go to local repository
  • cd heroku-play2
Create new app
  • play new heroku-play2
    • accept name of app (enter)
    • Create a simple Java application (2)

Gotzha

  • Move newly created app to from ./heroku-play2 to .

Modify your app (optional)
  • go to /heroku-play2/app/views
  • edit index.scala.html
Login to your Heroku account
  • Heroku login
    • If you don't have heroku account now is time to create it
    • otherwise give your credentials
Deploy your app to Heroku
  • git push heroku master
Open your app from heroku
  • heroku open


Further steps


If you have ever deployed traditional however simple app to any java container, or to any shared deployment environment, you probably felt difference.

Sure: there's more to come, as you have development environments, QA, and need to continuously deliver to production, but you are not alone here either.

If you want to see where you might end up with real world complexity, read https://devcenter.heroku.com/articles/multiple-environments

Monday, September 16, 2013

Play2 charts

Play2 charts

Play2 data visualizations


Play2's nature of pure asynchronous web framework instead of all-you-ever-need "wundertute" makes it clear that developer is one who decides what and how to visualize - there's no built in default toolset present.

I decided to 
  • Use javascript library to visualize my data
  • Compare 2 datasets to each other using Radar Chart

Javascript libraries


There's plethora of different libs. Open source, free, you name it. One size doesn't fit all, and it's up to your needs what you're about to choose.

You want to go commercial way: Maybe Highchart? See what they offer: http://www.highcharts.com/demo/

You prefer open source, and can extend given implementation by yourself if needed: Maybe D3? Fancy, indeed! https://github.com/mbostock/d3/wiki/Gallery

Radar Chart

Radar Chart isn't exactly the most common chart, so Highchart & D3 didn't have it included - but wait... There's radar chart extensions to d3, and extensions extension http://nbremer.blogspot.nl/2013/09/making-d3-radar-chart-look-bit-better.html

I decided to go for simple basic implementation. It seemed to me complete adequate to present 2 datasets, one having reference data and one containing data from main entity shown at view. What user will see is single page which holds data of entity and radar chart showing selection of actual data and pre-defined boundaries.

Good old GoF MVC


Play2 is built around MVC-pattern. I decided to get data from store (yaml file) at controller, build there simple model of java structure from lists and maps and pass it to view. This is exactly what you do if your application is simple.
If your needs are more rigid you might want to get data at view thru separate Url. Url may point to Play2 based Json service or some external data source, in which case you'd probably need to develop some data transformations. 

Or do you want to build realtime websocket based live views? Play2 is your partner here. For very fancy asynchronous live views example see http://aredko.blogspot.de/2013/05/real-time-charts-with-play-framework.html

My Model


Model is Yaml file containing 2 datasets, which are read to 2 java classes, i.e. MetricSet which contains multiple Metric objects is populated. Dataset1 can be thought to be reference data, which shows boundaries to which data from dataset2 is to be compared. 

private static List<MetricSet> expected = null;
static {
try {
if (expected == null) {
Map<String, List<MetricSet>> all = (Map<String, List<MetricSet>>) Yaml
.load("default-metrics.yml");
expected = all.get("expectations");
Logger.info("Defaults added");

}
} catch (Exception e) {
Logger.error("Defaults couldn't be added " + e.getMessage(), e);
}
}

My Controller


On controller model which is pre-loaded to static member variable is converted to structures which correspond d3 radarcharts data structures. Getting from My Model to List<List<Map<String, Object>>> is trivial.

public static Result show(long evaluationId) {

..

List<List<Map<String, Object>>> radarMetrics = new ArrayList<List<Map<String, Object>>>();
for (MetricSet metricSet : expected) {
List<Map<String, Object>> ds = new ArrayList<Map<String, Object>>();
for (Metric metric : metricSet.metrics ) {
Map<String, Object> item = new HashMap<String, Object>();
item.put("axis", metric.name);
item.put("value", metric.value);
ds.add(item);
}
radarMetrics.add(ds);
}

return ok(views.html.evaluations.show.render(evaluation, radarMetrics));
}

View


View gets data structures thru metrics parameter, which is of type List[List[Map[String, Object]]] as expressed with Scala. Note that view contains import of Google Gson. View has javascript that transforms metrics parameter to Json with Gson, adds some configuration, and renders radar chart.

@(evaluation: models.jpa.Evaluation)(metrics:List[List[Map[String, Object]]])

@* JSON marshalling *@
@import com.google.gson.Gson

@main("Evaluation") {

<script type='text/javascript' src='@routes.WebJarAssets.at(WebJarAssets.locate("d3.js"))'></script>

<script type='text/javascript' src='http://graves.cl/radar-chart-d3/src/radar-chart.js'></script>
   
<div id="chart" style='float:left'></div>

<script type='text/javascript'>//<![CDATA[ 

// get data
var data = @{Html(new Gson().toJson(metrics))};

// build config
var cfg = {
  w: 500,
  h: 500,
  maxValue: 100,
  levels: 10,
}

// render
RadarChart.draw("#chart", data, cfg);    

//]]>  

</script>

Sources


Further steps


Current design creates radar chart targeted copy of model inside controller as part of transformation, which means data duplication, but also makes controller responsible of tasks which belong to view.

It's possible to modularize given example by providing view helper which knows how to create radar chart compatible data structures from model classes. Provided helper should encapsulate data structure transformations, which are currently on controller, and delegate transformation responsibility to view instead of controller. 

There's manyfold of gains keeping it clear that views are in charge of presentation. When model classes can be transformed to Json data structures using single component inside view you can reuse logic easily in case you need radar chart in multiple pages, but also reacting on changes of javascript library or replacing used library with some other gets lot easier. 

Tuesday, September 03, 2013

Play2 javascript library dependencies

Play2 javascript library dependencies

Dependency management problem

It's common practice in java domain to rely on dependency management infrastructures like Apache Maven. As one starts to develop html app's with various javascript libraries it's necessary to manually copy files and adjust paths, which is error prone. In maven you would do this by changing single line, but now instead of changing version number on one file quite a lot simple manual operations are needed.

Asset management on Play2

Javascript libraries are used on html pages, which means they are carried to client over http as requested by browser. On server side resides mapping from http Url to location of requested resource on servers disk.

Play2 serves static assets from Public directory using Assets controller. This mechanism is defined at conf/routes file.


# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)

Webjars is library which makes it possible to serve static content from jars which are acquired thru Apache IVY dependency management.

When your container, web framework, or application needs to serve static assets from Jar files webJar needs to be a dependency of your application.

Defining Play2 dependencies

Please select which webjars-play fits to Play2 version in use, then add to project/build.scala needed dependencies for webjars.

  val appDependencies = Seq(
    "org.webjars" %% "webjars-play" % "2.1.0-3",

and for components you use
  • "org.webjars" % "jquery" % "2.0.3",
  • "org.webjars" % "bootstrap" % "3.0.0",

Serving static content from jars

To serve static content from jars one needs to add route to files. Here's example you can use

conf/routes

# Map static resources from the jar packages to the /webjars URL path
GET     /webjars/*file controllers.WebJarAssets.at(file)

Fetching static content from webjars

As all references to libraries used are already collected to single template file we just need to use /webjars Url instead of /public when getting required libs.

Main template view is at app/views/main.scala.html, and here one need to comment out static content and enable webjars content.

        @* no more direct static jquery from /public *@
        @* <script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script> *@
        
        @* resources thru /webjars *@        
        <link rel='stylesheet' href='@routes.WebJarAssets.at(WebJarAssets.locate("css/bootstrap.min.css"))'>
<script type='text/javascript' src='@routes.WebJarAssets.at(WebJarAssets.locate("jquery.min.js"))'></script>

Test changes

Main template is getting content element as optional variable.

@(title: String)(content: Html)

You can now wrap content inside Twitter bootstraps container using class container.

    <div class="container">
           @content
     </div>


Summary

Dependency management for javascript makes it easier to work together in teams when it's possible from build definitions to see which versions of javascript libraries are in use and they can be changed once for all developers thru shared dependency management mechanism. 

Example of Webjars usage where listed steps have been committed can be seen here

https://github.com/nikkijuk/smooks-play2-xml-to-jpa

Thursday, August 22, 2013

Simple Xml-to-Jpa data service with Smooks, Play2 for java and Ebeans JPA engine

Simple Xml-to-Jpa data service with Smooks, Play2 for java and Ebeans JPA engine

When experimenting how to develop simple end-to-end xml-to-jpa service
  • SOAP UI can be used to emulate client application. 
  • Smooks Xml-to-java example can be used to define xml payload, transform rules and java domain classes. 
  • Play2 template application can be customized to embed xml-to-java example with modifications for JPA persistence.
It is also possible to run Smooks example first from command line. Smooks xml-to-java example is here http://www.smooks.org/mediawiki/index.php?title=V1.5:xml-to-java

Why to use xml-transformations i.e. Smooks?


Applications interface definitions (XSD) and database definitions (Schema) evolve with time, and thus they should be separated. Application need transformation logic to convert information between company's internal structures (domain model) and external structures (public interfaces).


Why to use Ebean JPA engine?


Application's database structure (Schema) correlates with domain model and can be expressed using JPA entities or database dependent ddl (Database definition language). DDL files are typically set of SQL sentences with create table and create index definitions. JPA model is simple java class structure with specialized annotations. Play2 for Java contains Ebean, which uses JPA annotations, but saves you from using JPA container and creating your own DDL files as Database DDL's are automatically generated by Ebean and database is created on the fly.


Why not to use Jaxb?


XSD is interface definition of XML services, and can be used in Java apps thru Jaxb classes or by directly interpreting XML tree using SAX or DOM api's. With Smooks JAXB is not necessary when reading XML into object model. Smooks is using Xpath based selectors and Visitor logic with SAX event, and has efficient low-memory footprint engine which helps to translate xml tags to actions. So, why to use Jaxb if it is not needed?

XML services concept


Any client can send using http post xml messages containing "order" elements to play2 controller which is connected to "/order" url. 

On server side "order" elements are transformed to domain classes. Transformation rules are stored on smooks-config xml file. Ebean and H2 are persisting information.

Setting up environment


You need to install client and server parts
As Play2 is full stack environment it already contains Netty IO and Ebean JPA.
JBoss Smooks Transformation engine in turn is delivered thru Apache IVY as dependency http://www.smooks.org

Creating and testing sample Play2 app


Create your app
  • Go to root of your development directory
  • give command "play new xml-to-jpa" 

Start play shell
  • go to project directory xml-to-jpa 
  • give command "play" 
Test application
  • start app with "~run" 
  • go to "localhost:9000" 
To make code-compile-debug cycle smooth "~" is important addition to run, since it enables PHP alike dynamic development on java platform. Fancy, and works well.

More details of template play2 application at http://www.playframework.com/documentation/2.1.x/Home

Setting up IDE


Generate IDE configuration
  • start shell "play" 
  • generate configuration "eclipse with-source=true"
Create eclipse project
  • Open Eclipse 
  • Let Eclipse to create new workspace 
  • Export / General / Java Project from existing sources 
If you prefer some other IDE please see http://www.playframework.com/documentation/2.1.x/IDE

Enabling H2 and Ebean


Enable Database support
  • Open conf/application.conf 
  • uncomment lines under "database configuration" to enable H2 support 
  • uncomment lines under "ebean configuration" to enable JPA engine 
Change location of JPA model
  • change "ebean.default" to point "example.models.*" as on Smooks example 


Extending app with JPA model


See how Smooks POJO domain model looks
Create needed JPA classes
  • Use example.model as package for classes 
  • Create classes Header, CustomerOrder and OrderItem 
  • note: we must use CustomerOrder instead of Order as Order is reserved word in SQL 
Add JPA and Ebean definitions
Define find helper variable to main class of model
  • Add static Finder as find variable to CustomerOrder 
  • Note: Usage of Finder isn't mandatory, but it makes complex query operations single liners. 
Here's body of CustomerOrder class with JPA annotations & needed fields.
@Entitypublic class CustomerOrder extends Model {
@Id
public Long id;

/**
* Cascades saves, which means dependent object will be saved as main object is saved.
*/
@OneToOne (cascade = CascadeType.ALL, fetch=FetchType.EAGER)
public Header header;
/** Saves on collections are cascaded.  
* Fetches are eager, which might result some extra access to db.
*/
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customerOrder", fetch=FetchType.EAGER)
public List<OrderItem> orderItems = new ArrayList<OrderItem> ();

/**
* find static member variable to help searches
*/
public static Finder<Long, CustomerOrder> find = new Finder<Long, CustomerOrder>(
Long.class, CustomerOrder.class);
}
If you wonder what exactly Model class and Finder do, please peek here http://www.playframework.com/documentation/2.1.1/JavaEbean

It’s important to note that if you want to have real JPA it can be plugged in, but it’s there not as per default http://www.playframework.com/documentation/2.1.1/JavaJPA


Review your entites


Document domain model
Domain model with completed JPA classes looks like this




Create database instance


Bootstrap database creation
  • make sure application is compiled and running at port 9000 
  • go to localhost:9000 
  • Wait that play2 asks “Database 'default' needs evolution!” 
  • Check generated database ddl and accept it 

CustomerOrder database ddl should look like
create table customer_order (
  id bigint not null,
  header_id bigint,
constraint pk_customer_order primary key (id));
You can access H2 database out of process to see empty database http://www.h2database.com/html/quickstart.html


Extending app with transformations


Add Smooks dependencies to SBT build
  • Open file project/Build.scala 
  • Add libs to appDependencies 
    • "org.milyn" % "milyn-smooks-core" % "1.5.1", 
    • "org.milyn" % "milyn-smooks-javabean" % "1.5.1", 
  • add repository to settings method of play project 
  • update dependencies by compiling and starting project “play clean eclipse ~run“ 
  • refresh project in eclipse with File / Refresh 

Prepare tranformation rules
Add transformation logic

Note: HTML report drains memory. HTML report is vital tool for checking your mappings / selectors, but should be used only with limited amount of data. Use it only for development and never with xml streams of megabytes.

Note: Instance of Smooks is thread safe and should be static as it's initialization per request basis is expensive. Here is is kept inside method scope to minimize changes.


Extending app with xml service


Define entry point
  • Define http post route from /order to implementation method saveXml() at Application class in file conf/routes as "POST /order controllers.Application.saveXml()" 
Define controller implementation
For more background on flow of execution see discussion from previous post
http://nikkijuk.blogspot.de/2013/08/simple-java-xml-web-services.html


Web user interface concept


Play2 enables you to implement variation of MVC (model-view-controller) pattern.



As with xml service there's 
  • Route to define endpoint for clients
  • Controller for logic
  • Domain classes for model  
But in addition to xml service we also have view template , which is used to render output to client.


Provide web user interface


Define view template
  • Add simple template which renders order list 
  • Define incoming parameter orders as list of CustomerOrder classes 
  • Add iteration over list of orders 
Below is simple template -- if it doesn’t look all too familiar it’s because it’s written in Scala, more here http://www.playframework.com/documentation/2.1.1/JavaTemplates
@(orders: List[example.model.CustomerOrder])
@main("List of orders") {
<h1>List of orders</h1>
<ul>
@for(order <- orders){
      <li>@order.id @order.header.date @order.header.customerNumber @order.header.customerName </li>
}
</ul>
}

Define controller method
  • Add method connecting route to template 
  • Add logic to find all orders 
  • Add logic to render template 
To make it readable I have kept method body on 2 lines.
public static Result list() {
  List<CustomerOrder> orders = CustomerOrder.find.findList();
  return ok(list.render(orders));
}
Define entry point
  • Add get request to route "GET /orders controllers.Application.list()" 

See list of orders


Prepare initial test data


Define test data

Load test data
static {
  try {
    if (Ebean.find(CustomerOrder.class).findRowCount() == 0) {
    // load yaml data
    Map<String, List<Object>> all = (Map<String, List<Object>>) Yaml
    .load("default-orders.yml");
    // Insert employees
    Ebean.save(all.get("orders"));
    Logger.info("Defaults added");
    }
  } catch (Exception e) {
    Logger.error("Defaults couldn't be added "+e.getMessage(), e);
  }
}

See list of orders
If you plan to extend test data changes are you need to check your Yaml is sane. let Yamllint to help http://yamllint.com/.

If you feel more academic interest then Yaml specification might help http://www.yaml.org/spec/1.2/spec.html


Testing with Soap UI & Browser


Setup SOAP ui
  • Define post method of xml content to be sent to localhost:9000/order 
Get test message
Post it to service
  • Send message to localhost:9000/order 
See list of orders