Monday, October 28, 2013

Play2 and TeamCity

Play2 and TeamCity


TeamCity


TeamCity from JetBrains is one of main rivals on Continuous Integration space. 

Study the power of TeamCity at


Ot try it live


TeamCity doesn't have SBT or Play2 support out of box, but this is more of a fact than real limitation. As you need to accept that fact you are faced with several options for building your app with TeamCity.

Build with Maven 


You could take layered approach, and add Pom file to your project and control builds with 3rd party Maven plugin. This approach means that you can use existing maven infrastructure and tasks. On the other hand, 3r party maven plugin is extra component which is out of your control and might not be supported after a while.

I haven't tried Maven-Play2-plugin, but it looks like having quite a set of functions.


Build with SBT


Play2's command line tools function as lightweight wrapper over SBT. So, installing SBT to your TeamCity agents and getting build done with SBT looks like sensible approach. 

Again, I can just guess how well this can work, example with Bamboo is here.


Build with Play shell


You can also get Play2 directly installed to TeamCity agents and use command line tools just like you'd do in your local environment

Installing Play to build agent is simple. 
  1. Get Play2 2.2 as Classic distribution zip from http://www.playframework.com/download
  2. Extract to preferred location at your TeamCity agent
  3. Add env.playframework.dir=<extracted-to-dir-name> to <agent home>/conf/buildAgent.properties

Installation brings %env.playframework.dir% environment variable visible to your configurations, and additionally TeamCity manages to restrict build steps only to agents which have Play installed and %env.playframework.dir% defined.

Kicking in play build from command line is simple. 
  • %env.playframework.dir%/play -Dbuild.number=%build.counter% clean dist

Build number is defined using %build.counter% property, which is passed to SBT thru build.number property.

Version numbered build results can be produced easily. Play2's command line parameters can be passed thru SBT to be used in build.sbt. Properties like build.number are read at build.sbt using sys.props. This way version number can be set easily using one-liner.


  • // usage: play -Dbuild.number=123 dist
  • version      := "1.0"+"."+sys.props("build.number")

Here's example of using System.getProperty ("..") which is same as sys.props in build.sbt.

http://www.scala-sbt.org/release/docs/Examples/Quick-Configuration-Examples.html

Build Parameters usage can be checked from TeamCity's documentation


Further steps


No tests? Try "play clean test dist". If needed components could be also published to Nexus. Try "play clean test dist publish", but don't forget publishTo and credentials definitions from build.sbt.  Want your app to be installed directly as part of nightly build. Well.. Here you have more options, since now we can go to direction of AWS, Heroku, Cloudbees or your own dedicated servers.

Tuesday, October 22, 2013

Play2 and Sonatype Nexus

Play2 and Sonatype Nexus


Sonatype Nexus IN & OUT

Binary repositories like Sonatype Nexus can be used to share artifacts within single company. 

It's very common requirement for Play2 application to get shared artifacts from binary repository, but as viable to publish project as shared artifact for later deployment or to be integrated to other applications.

Play shell is based on SBT. SBT defines mechanisms for fetching and publishing artifacts. Resolvers define way of getting content from repositories and publishTo defines how to share project with others thru repository.

If your repository is not open for everyone and for everything, you need to supply credentials. Credentials can be hardcoded to your build file or stored on local user specific configuration. Hardcoding is not preferable.

You can find more info of publishing from here


Defining resolvers

Endpoints for repositories are defined as resolvers. You might have multiple resolvers, and thus you define them as sequence.
      
resolvers ++= Seq (
)
   

Defining publishing

Publishing destination is defined as endpoint with publishTo

publishTo := Some("Local proxy of central repo" at "http://192.168.24.3:8081/nexus/content/groups/development")

If you want to control what is to be published you can enable or disable publishing per artifact.

// disable publishing the main API jar
publishArtifact in (Compile, packageDoc) := false

// disable publishing the main sources jar
publishArtifact in (Compile, packageSrc) := false

How to enable or disable publishing per artifact is documented here


Defining credentials

Hardcoded credentials are defined at build.sbt like

 credentials += Credentials("Sonatype Nexus Repository Manager", "192.168.0.1", "developer", "password")

Dynamic loading of credentials can be done from ivy configuration

credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")

Configuration file must contain realm, host and user with password

realm=Sonatype Nexus Repository Manager
host=192.168.24.3
user=research
password=research

Further steps

Next you might want to see how to connect publishing to CI tool of your choice. 

Whether it is Jenkins, Teamcity, Bamboo or anything else, there might not be direct integration to Play2 in which case you could first see integrations to SBT instead. 

There are multiple strategies for building and packaging your app, of which one of the easiest is to use Play2's shell and "play publish" command to produce zip of whole app.

If you have already heavy loads of Maven based processes you might even want to produce or use plugins that wrap play2 shell commands to maven plugins.

Another considerations for CI process is if you need to provide Play2 app as war to be deployed to application server. Yes, it is possible, but seems really counter intuitive to me. 

Play2 and MySql

Play2 and MySql


Happened so far


I have developed my Play2 app using H2 in memory database. Wonderful! Next step is to set up local Postgres, and after a while also this works ok. WIth Postgres I don't anymore have automatic evolutions in use, but H2 was generating Postgres compatible SQL after some JPA annotation tuning and I felt happy.

BTW: All this was possible since Play2 has really neat feature called evolutions


MySQL comes to Play


My organization is using MySql. Fine. I try with existing sql generated by evolutions. SQL has errors. No big deal -- yet.

I feel I could live with couple of new reserved words like "lines", which couldn't be anymore used as fields name as MySQL uses "lines" on ETL definitions. So; I rename fields on JPA classes and generate SQL again. No problem.

After this comes shock. Play2 / Ebean autogenerated SQL is nice, readable, and follows SQL standard(!), and I had not paid attention to fact that MySql doesn't follow SQL standards.

You find more of the problem from here

Decision


Oh my. Should I define all my seqences to be autoincrements? And what about referential integrity. Use InnoDB? Annotate all ID's with @GeneratedValue? And just accept other MySql anomalies? And be locked to develop usign MySql?

No. I will play political games, and try to convince my organization to accept one more database -- for greenfield project this might be accepted. Let's see.

Further steps


There's lot of comparisons, but many of them look like flamewars. It's important to notice, that whichever you want to use is not only up to your own preferences, but also your use case. And your company's policy, also.


Since MySql feels like no-go to me, I'll need to go deeper and see how to justify Postgres - or file based H2.


Wednesday, October 16, 2013

Play2 and Deploying your app

Play2 and packaging your app


Play apps are easy to start using play console, "~run" command is excellent on development mode, "start" command shows how application behaves on production. 

There remains question, how to prepare distibution packages which are startable without play console?

Packaging with stage and Dist


Play has commands "Stage" and "dist". "Stag"e is preparing app. "Dist" is packaging it to Zip. You can easily package Play2 app to other as Zip package by using universal packager.

Stage


"stage" command can be used to collect sources and store them under "target/universal/stage" directory. Your application is then startable with generated script which is under "bin" directory. Name of script file will be name of your application. If needed config file can be used to customize runtime behavior.

Example flow

  1. play stage
  2. target/universal/stage/bin/<app-name> -Dconfig.file=/full/path/to/conf/application-prod.conf

Dist


"dist" command will package application generated to zip file. Zip file will be located under "target/universal" and is named after your applications name and version number.

Example flow

  1. play dist
  2. .. copy .zip to given location
  3. .. unzip
  4. bin/<app-name> -Dconfig.file=/full/path/to/conf/application-prod.conf

Custom


If you prefer or need some other packaging methods as zip it's possible to use packager directly

Example flow

  1. play universal:package-zip-tarball
  2. .. 

Publishing to Maven repository


"publish" command can be used to publish project. For this you need to define in "build.sbt" where artifact are about to be published (publishTo) and rights needed (credentials) to access given repository.

Example flow
  1. make needed changes to build.sbt
  2. play publish

Further steps


All this is pretty theoretical until you try it. Please do. You'll find more info from here to support your efforts.


Friday, October 11, 2013

Play2 build files

Play2 build files


Play2 2.2 documentation suggested that one should convert "./project/build.scala" to "./build.sbt".

http://www.playframework.com/documentation/2.2.x/SBTSubProjects

"The following example uses a build.scala file to declare a play.Project. This approach was the way Play applications were defined prior to version 2.2. The approach is retained in order to support backward compatibility. We recommend that you convert to the build.sbt based approach or, if using a build.scala, you use sbt's Project type and project macro."

You most propably want to read thru docs - I did, and felt bit dizzed...

.sbt build file

http://www.scala-sbt.org/0.12.2/docs/Getting-Started/Basic-Def.html

.scala build file

http://www.scala-sbt.org/0.12.2/docs/Getting-Started/Full-Def.html

Easy stuff? Found example, and followed it. Try same.

http://mikeslinn.blogspot.de/2013/09/sample-play-22x-buildsbt.html

build.scala


Build.scala is basically build.sbt expressed with scala. So, if you understand what kind of object model build file forms you have straightforward task here.

import sbt._
import Keys._
import play.Project._

object ApplicationBuild extends Build {

  val appName = "resource_delivery_admin"
  val appVersion = "1.0-SNAPSHOT"

  val appDependencies = Seq(
    "postgresql" % "postgresql" % "9.1-901.jdbc4",
    javaCore,
    javaJdbc,
    javaEbean  

  )

  val main = play.Project(appName, appVersion, appDependencies).settings(
    resolvers += "JBoss repository" at "http://repository.jboss.org/nexus/content/groups/public-jboss/"
    
  )

}

build.sbt


What comes out is this. Simple? That was how I did it. And cleaned and compiled.

import sbt._
import Keys._
import play.Project._

play.Project.playJavaSettings

name         := "your-project"

version      := "1.0-SNAPSHOT"

libraryDependencies ++= Seq (
    "postgresql" % "postgresql" % "9.1-901.jdbc4",
    javaCore,
    javaJdbc,
    javaEbean  
  )


Resolver for JBoss repository was eventually used, but as I wanted to cut down lines to make this easier to you to read I took Smooks dependencies off.

Further steps


Just try to get it right and enjoy.

http://www.scala-sbt.org/release/docs/Getting-Started/Summary.html

There's whole lot concepts you want to understand, but take your time. SBT will be later defined to be acronym without meaning like Soap, which isn't anymore thought to be "simple".

Play2 and Postgres

Play2 and Postgres


H2 is great database and it integrates well to Play2 during development. I use Ebean ORM and it just works. When I decided to try local Postgres I found some differences, but basically everything went fine.

More on developing with H2 from here.

http://www.playframework.com/documentation/2.2.x/Developing-with-the-H2-Database

Installing Postgres


Postgres installation options for Mac are here

http://www.postgresql.org/download/macosx/

I selected Postgres.app, which was perfect for me, since it's easy to operate.

http://postgresapp.com/

Just to make sure all goes well I also added it to path in .profiles file

  • export PG_HOME=/Applications/Postgres.app/Contents/MacOS/bin 
  • export PATH="$PG_HOME:$PATH" 

Testing connection was easy

  • psql -h localhost

But I also installed induction.app for browsing content

http://inductionapp.com/


Getting driver


I used Postgres 9.3 and wanted to use latest driver. Driver was easy to find from maven central.

project/build.scala needed single new dependency for jdbc driver

  "postgresql" % "postgresql" % "9.1-901.jdbc4",

Here's more of setting up your database

http://www.playframework.com/documentation/2.2.x/JavaDatabase

Setting up connection


I could have hacked existing application.conf, but decided to have separate conf/postgres-local.conf for Postgres database settings

  • db.default.driver=org.postgresql.Driver
  • db.default.url="jdbc:postgresql://localhost/nikkijuk"
  • db.default.user="nikkijuk"
  • db.default.password=""
nikkijuk = $USER, so please replace with your local account name

You can find more of JDBC settings from here

http://www.playframework.com/documentation/2.2.x/SettingsJDBC

Starting app


For deploying Play2 apps to production one shouldn't ever use "run". I wanted to override settings from command line and use Postgres as 2nd development database. So; "run" is ok.

  • play -Dconfig.file=conf/postgres-local.conf ~run

If you want to know more of overriding settings, please see

http://www.playframework.com/documentation/2.2.x/ProductionConfiguration

Datatype generation


I had in Entities some strange stuff like maximum size of numeric identifier.

@NotNull
@Column(unique = true)
// @Size(min = 2, max = 64)
public long processId;


"@Size(min = 2, max = 64)" definiton generated fields with type bigint(64), which went thru on H2, but were inappropriate on Postgres. Commenting out extra annotations solved problems here.

Development process


I found out that Ebean and H2 are unbeatable during development. Changes on data model (Entity classes) were automatically detected, sql was generated, and database model changed according model.

With Postgres there isn't as tight integration. My process is thus, that I first develop all with H2, and then let Play2 to run SQL sentences that set up Postgres. This works fine to me, and at the end I know that I have two very good databases on my service locally.

Further steps


Get your app to Cloud. Heroku is here a good option, since it supports natively both Play2 and Postgres.


Tuesday, October 08, 2013

Play2 forms and Bootstrap


Play2 forms and Bootstrap 


Bootstrap gives developer grid layout, some css magic and components. As Play2 contains support for Bootstrap directly one can think that it's all easy no brainer to have some fields rendered with easy helpers.

Yeah, but...

Bootstrap 1.X, 2.X and 3.X


Play2 2.1 contains helpers, which render Bootstrap 1.4 markup. Since there's quite some changes between Bootstrap versions, Play2's built in support starts to look like a teaser.

If you want to study Bootstrap differences, it's all there


Built in standard field rendering (no bootstrap)


Let's see simple Scala template example without Bootstrap. 

Here's our form template. Form type is defined as input, template imports helpers,  form and inputText helpers are used to render html form.

@(userForm: Form[models.jpa.Users])

@* helper._ import is required to be able to use the @form tag *@
@import helper._
        
    @helper.form(action = routes.UserController.save()) {
<fieldset>   
     @helper.inputText(userForm("id")) 
     @helper.inputText(userForm("username")) 
     @helper.inputText(userForm("password")) 
      </fieldset>
      <input type="submit" class="btn primary">
}
        
}

When rendered to html result looks like this. Form has got url address and method, each field has label and id and values are retrieved from form.

<form action="/users" method="POST" >
  <fieldset>  

  <dl class=" " id="id_field">
    <dt><label for="id">id</label></dt>
    <dd>
    <input type="text" id="id" name="id" value="3" >
    </dd>    
  </dl>

  <dl class=" " id="username_field">
    <dt><label for="username">username</label></dt>
    <dd>
    <input type="text" id="username" name="username" value="user1" >
    </dd>
  </dl>

  <dl class=" " id="password_field">
    <dt><label for="password">password1</label></dt>
    <dd>
    <input type="text" id="password" name="password" value="" >
    </dd>
  </dl>

  </fieldset>
  <input type="submit" class="btn primary">
</form>

Works, but not exactly eye-candy.

Documentation for templates can be found from here:

Built in Bootstrap field rendering (Bootstrap 1.4)


Taking bootstrap in use is really really simple. Just add import of Bootstrap helpers. Everything else stays same.

@(userForm: Form[models.jpa.Users])
@import helper._

@* helper.twitterBootstrap._ import is required for formatting *@
@import helper.twitterBootstrap._ 

When html is rendered you can see how form definition has not been changed, but fields are now defined with divs. Same happens to all fields.

<div class="clearfix  " id="id_field">
    <label for="id">id</label>
    <div class="input">
        
    <input type="text" id="id" name="id" value="3" >

        <span class="help-inline"></span>
        <span class="help-block"></span> 
    </div>
</div>

If it looks funny when rendered by your browser, remember that helpers and thus generated CSS is for Bootstrap 1.4 and your pages might use some other version. So; either get right Bootstrap files or abandon standard Bootstrap helpers and go on.

Customizing field rendering (Bootstrap 2.X and 3.X)


Play2 Input helpers and present Bootstrap (1.4) helpers might be enough for simple use cases, but if you want to have fields in any other layout than vertical, i.e. label with field name at top and field right under label, you probably need to implement your own rendering.

Possibilities how to proceed
  • Write html as it is, no helpers, all tags are up to you 
  • Develop reusable code blocks and save them to any exiting template to use them later
  • Develop reusable template files, which can be called directly
  • Develop reusable template files, which are registered to be used during rendering 
When you try to gain some reusability you get all the time more Scala on your bandwagon. Let's face it. Java is not enough here.

Example from "Play2 for Java" (Bootstrap 1.X)

"Play2 for Java" book is still work in progress, but MEAP is pretty good stuff. Example from book shows how standard Bootstrap helper is written.

@* Example from: play2 for java, meap 8, page 163 *@


@(elements: views.html.helper.FieldElements)
@import play.api.i18n._
@import views.html.helper._

* Generate input according twitter bootsrap rules *

<div class="clearfix @elements.args.get('_class)
    @if(elements.hasErrors) {error}"
    id="@elements.args.get('_id).getOrElse(elements.id + "_field")">
  <label for="@elements.id">@elements.label(elements.lang)</label>
  <div class="input">
      @elements.input
      <span class="help-inline">
          @elements.errors(elements.lang).mkString(", ")
      </span>
      <span class="help-block">
          @elements.infos(elements.lang).mkString(", ")
      </span>
  </div>
</div>

Reading sources of Play2 helps you to understand what you can do with FieldElements. At least I was bit surprised of FieldElements since input, for example, is just a parameter with html content.



Example of reusable registered rendering templates (Bootstap 2.X)


James Ward has published nice tips to us. James' tips help you directly if you use Bootstrap 2.X as Bootstrap 2.X has control groups and controls, but Bootstrap 3.X uses form-group instead of control-group. Maybe this clarification on naming between Bootstrap versions was needed, but at least it breaks your code. 

James' example uses single form constructor, which is registered on page which uses it. Field constructor is like any other Scala template file.


@(elements: helper.FieldElements)

<div class="control-group @if(elements.hasErrors) {error}">
    <label for="@elements.id" class="control-label">@elements.label</label>
    <div class="controls">
        @elements.input
        <span class="help-inline">@elements.errors.mkString(", ")</span>
    </div>
</div>

It's all explained here. No need to repeat.


Example of scala helpers (Bootstrap 2.X)


Here's simple example from Philip M. Johnson how to use single field constructor.


But life's not that simple. Here's another example from Philip that can bring you closer to understand the problem in depth.


Philip says: "The canonical recommendation for users of Twitter Bootstrap 2.x is to create a single "implicit" field constructor. The problem with this recommendation is that a single implicit field constructor cannot satisfy all of Twitter Bootstrap's layout requirements for form controls (for example, multiple checkboxes). This example illustrates a more general solution in which normal (i.e. "explicit") scala templates (i.e. field constructors) are defined in theviews.bootstrap package for each of the Twitter Bootstrap controls. IMHO, the code is significantly easier to understand and debug for Java-based Play framework users."

You should read this well, and understand it. After reading it's up to you to try to figure out if there's mismatch between your needs and what Play2 helpers provide. If you follow Philips advice you are suddenly starting to do all by yourself. Goodbye form helpers, welcome control. But is that right way to go? Maybe. It depends.

Philips field template for simple text field looks like this. Pretty clean.

@(field: Field, label:String, placeholder:String, help:String)

<div class="control-group @if(field.hasErrors) {error}">
  <label class="control-label">@label</label>
  <div class="controls">
    <input
      class="input-xlarge"
      type="text"
      id="@field.id"
      name="@field.name"
      value="@field.value.getOrElse("")"
      placeholder="@placeholder" />
    <p class="help-block">@help</p>
    <p class="help-block">@{field.error.map { error => error.message }}</p>
  </div>
</div>


Example from "Play2 for Scala" (Bootstrap 2.X)


"Play2 for Scala" book presents example FieldConstructor which is written for Bootstrap 2.X, but I'll add it here to give you idea.

@* Example from: play2 for scala, page 187 *@

@(elements: views.html.helper.FieldElements)
@import play.api.i18n._
@import views.html.helper._
<div class="control-group @elements.args.get('_class)
  @if(elements.hasErrors) {error}"
  id="@elements.args.get('_id).getOrElse(elements.id + "_field")" >
  <label class="control-label" for="@elements.id">
    @elements.label(elements.lang)
  </label>
  <div class="controls">
    @elements.input
    <span class="help-inline">
      @if(elements.errors(elements.lang).nonEmpty) {
        @elements.errors(elements.lang).mkString(", ")
      } else {
        @elements.infos(elements.lang).mkString(", ")
} </span>
  </div>
</div>

You should read chapter 7.3.4 "Customizing generated HTML" to go deeper to topic. This might save your day, since I haven't found too many places where this topic would be well discussed.  

My-2-Cents template (Bootstrap 3.X)

Twitter Bootstap 3.X needs right css class definition for form and fitting structure for fields also. I decided to write my template simple way, so: get class for label and for div thru element params. 

@import play.api.i18n._
@import views.html.helper._
<div class="form-group @elements.args.get('_class) @if(elements.hasErrors) {error}">
  <label for="@elements.id" class="@elements.args.get('_label_class)">@elements.label(elements.lang)</label>
    @elements.input
    <span class="help-block">
      @if(elements.errors(elements.lang).nonEmpty) {
        @elements.errors(elements.lang).mkString(", ")
      } else {
        @elements.infos(elements.lang).mkString(", ")
} </span>
</div>

My solution is just imitation of ones listed already, and it's about to be used like this

@(userForm: Form[models.jpa.Users])
@implicitFieldConstructor = @{ helper.FieldConstructor(bootstrapInput.render) }

@* helper._ import is required to be able to use the @form tag *@
@import helper._

@helper.form(action = routes.UserController.save(), 
'class -> "form-horizontal", 'role -> "form") {
<fieldset>   

     @helper.inputText(userForm("id"),
'_label_class -> "col-md-2"
'class -> "col-md-2", '_label -> "ID") 
     
@helper.inputText(userForm("username"),
'_label_class -> "col-md-2"
'class -> "col-md-2") 
     
@helper.inputText(userForm("password"),
'_label_class -> "col-md-2", 'class -> "col-md-2") 

      </fieldset>
      <input type="submit" class="btn primary">
}

Rendering looks like this. ID fields name is overwritten, class has went to input element and _label_class to label. If I'd used _class it would have went to div.

<form action="/users" method="POST" class="form-horizontal" role="form">
<fieldset>   

<div class="form-group  ">
  <label for="id" class="col-md-2">ID</label>
    <input type="text" id="id" name="id" value="3" class="col-md-2">
    <span class="help-block">
    </span>
</div>

<div class="form-group  ">
  <label for="username" class="col-md-2">username</label>
  <input type="text" id="username" name="username" value="user1" class="col-md-2">
  <span class="help-block">
  </span>
</div>

Please see how this matches to Bootstrap 3.X documentation, and modify as needed.


Further steps


Java developers, like me, who have dreamed to get power of Play2 without any added complexity might feel like cheated after reading "Play2 for Java" and learning that forms and bootstrap support are all built-in, since it's not all that easy. You really need to go beyond examples of books and learn some Scala.

It's possible to implement integration libraries like one that is currently embedded to Play2,  or leave implementation always for project. Important is to follow DRY principle - so: don't repeat yourself, use reusable templates. Whether these templates are made by you, copy pasted or acquired as dependencies is up to presence of such components and your needs.

And please read some more posts. Maybe learn some more Scala.