Play Framework
A walkthrough
Play Framework
Based on Netty
Stateless play framework
Full stack web framework
Includes model persistence, template (views), controllers, testing
Developer friendly
Hot reload: Framework listens for changes and compiles & deploys in background
Fully compiled and type safe
Nice features:
Netty
Introduction
Basic internals
Netty Server
Netty is :
IO library
Asynchronous
Non-blocking
Multi-protocol
Netty gives:
Good Performance
Low resource consumption
Netty Server Asynchronous
All I/O operations do not block
Get notified when operation completed
Be able to share threads across many connections
In OS:
select()/poll() : traditional POSIX polling
epoll() : event based polling, on Linux 2.5.44+
Kqueue : on FreeBSD, MacOS X
How Netty works?
NIO ServerSocketChannel is a channel that can listen for incoming TCP
connections
How threads work: boss threads and worker threads.
Boss Thread:
Each bound ServerSocketChannel has its own boss thread
if you opened two server ports such as 80 and 443, you will have two boss threads
A boss thread accepts incoming connections until the port is unbound.
Once a connection is accepted successfully, the boss thread passes the accepted Channel to one
of the worker threads
Main Components
Bootstrap and ServerBootstrap
EventLoop
Channel
ChannelFuture
ChannelPipeline
ChannelHandlers
ChannelHandlerContext
ServerBootstrap bind() ServerChannel
Channel
ServerChannel is created
when bind() is called
A new channel is
created when a
connection is accepted
Structure
Code structure
Setup
Project Structure
app/
Contains application’s core in models, controllers and views
conf/
Application config files, route definition file, message file for internationalization etc.
project/
Contains the build script
public/
Contains all publically available resources like javascripts, stylesheets and images
Play Setup and Run
REQUEST
RESPONSE
Controller Business Data Access
Presentation
Database
Web Application Overview
Routers
Introduction
Rules
HTTP Verb
Routing in action
Introduction
Component that translates each incoming HTTP request to an action call
Made up of HTTP Verb, path and action function
All calls go to right method with help of routers
Routers
Route Example
GET /index controllers.Application.index()
Method Path Method
HTTP Methods
GET
POST
PUT
DELETE
And more
Controllers,
Actions And
Results
Controllers
Actions
Results
Data Parsing
Controllers, Actions and Result
Controllers are classes
Located in apps/controllers folder
Inherit from abstract controllers class
Methods which handle request inside controllers are called actions
Return Result object
Views
Play Views
Static Page
Arguments
Iterations
Conditions
Templates
Layout
Play Views
Scala comes with Twirl, a scala based template engine
Twirl engine is:
Compact, expressive and fluid
Easy to learn
Easy to edit
It is a simple text file which contains small scala code blocks
Very close to HTML
Simple naming convention views/filename.scala.html
JPA/Hibernate
Introduction
Hibernate/JPA
Object Relational Mapping
During application development, we want to focus on business concepts, not
relational database structure
Provide abstraction during communication with database
Allow automatic synchronization between java objects and database tables
Database independent
Query abstraction, database specific queries are autogenerated
Object and query caching is done by ORM
Java Persistence API (JPA)
Specification for management of persistence and object relational mapping with
java
Provide object relational mapping by mapping java POJOs to relational
databases
POJO based persistence model
Support for enriched domain modeling i.e. inheritance, polymorphism etc
Expanded query language
Support for pluggable persistence provider
JPA: Persistence Entity
Annotated POJO
Lightweight persistent domain model
Persistent identity field
Provide support for
Abstract class and inheritance
Relationships (OneToOne, OneToMany, ManyToMany)
Each entity is typically represented by one table
Each entity can have both persistent and nonpersistent state
Data Model
Set of concepts to describe structure of database
Specify constraints that database should follow
Operations on data model may include basic operations and user defined
operations
Building blocks
Entity : data will be stored and collected in them
Attribute: Characteristics of entity
Relationship: association between entities
Evolutions Introduction
Evolutions
Helps track and organize your database schema (in case of relational databases)
Play tracks your database evolutions using several evolutions script.
Scripts located at:
conf/evolutions/{database name}
Each script contains two parts:
The Ups part the describe the required transformations.
The Downs part that describe how to revert them.
Evolutions are automatically activated if a database is configured in
Filters
Introduction
Filters
Standard Filters
Custom Filters
In Action
Filters
The filter API is intended for cross cutting concerns that are applied
indiscriminately to all routes.
Filters wrap the action after the action has been looked up by the router.
Cannot use a filter to transform a path, method or query parameter to impact the
router.
Can direct the request to a different action by invoking that action directly from
the filter
Common use case of filters:
Logging/metrics collection
Dependency
Injection
Introduction
Guice
In Action
Introduction
Dependency Injection is ability to inject external dependency into software
component
Benefits:
Easier testing and refactoring
Easier maintenance
Loose coupling
Managing object lifetime
Better design and use
Hide implementation details
Guice
Dependency injection framework
Convention over configuration
Easier to use, test, maintain, refactor and learn
Static and compile time verification
Favor good design with immutability, valid object and thread safe object
Basic Annotations
@Inject
@ImplementedBy
Logging
Introduction
Why Logs
Add Logs
Best Practices
MDC And Default Parameters
Why we need logging?
Monitoring
Debugging
Error Tracking
Business Intelligence
Play provides an API for logging which is accessed through the Logger object and
uses Logback as the default logging engine.
Logback Logging Architecture
Different components:
Logger
Default logger named “application”
Can create our own logger
Log Level :
OFF : use to turn off logging
ERROR: Runtime error, or unexpected exception
WARN: Deprecated Api, unexpected situation
Logback Logging Architecture
Appender
Handle responsibility to write event to component
Kinds of appender:
OutputStreamAppender: Append events to OutputStream
ConsoleAppender: Append events to console, or System.out or System.err
FileAppender: Append events to file
RollingFileAppender: Append events to file with the capability to rollover log files
Time based rolling policy
Size and time based rolling policy
Appender
Event
doAppender
(Event e)
DB
File
Console
Logback Logging Architecture
Encoder
Accept events and transform these events into byte array
Write into output stream
Total control of what and when bytes gets written to the output stream
Layout
Transform an incoming event into a String
Has no control over when events get written out
Layouts can not aggregate events into batches
Using Logger
Import play.Logger
Logger.debug("Result={}", result)
Never do Logger.debug(“Result=”+result), as it will do string concatenation
every time without we actually adding it in log file based on Log level.
Play puts both the console and the file logger behind the logback
AsyncAppender
Config file path : conf/logback.xml
Sample appender logback.xml
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${application.home:-.}/logs/application.log</file>
<encoder>
<pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
</encoder>
</appender>
<appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="STDOUT" />
</appender>
MDC: Map Diagnostic Context
Help uniquely stamp request
Manages contextual information on a per thread basis
MDC.put(“userkey”, value)
MDC.remove(“userkey”)
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%coloredLevel %logger{15} %X{userkey} - %message%n%xException{10}</pattern>
</encoder>
</appender>
Best Practices
Always keep date on log file name
Always add some name to your log file name, which help in distinguish it from
other log files.
Always log time and date of events
Store date in YYYYMMDDHHMMSS format (ideally) as it helps in sorting.
Use 24 hour time format.
In multi threaded system, use thread id.
Use different name of logger, depending on kind of logs as that help in
Best Practices
Log single event in single line, stack trace kind of thing can be multiline.
Log with a delimiter between fields so logs can be easily parsed. Don’t skip
empty fields add something like - or delimiter to identify it.
Log identification information as that helps in debugging.
Don’t log sensitive information like passwords etc.
Questions
?

Play framework : A Walkthrough

  • 1.
  • 2.
    Play Framework Based onNetty Stateless play framework Full stack web framework Includes model persistence, template (views), controllers, testing Developer friendly Hot reload: Framework listens for changes and compiles & deploys in background Fully compiled and type safe Nice features:
  • 3.
  • 4.
    Netty Server Netty is: IO library Asynchronous Non-blocking Multi-protocol Netty gives: Good Performance Low resource consumption
  • 5.
    Netty Server Asynchronous AllI/O operations do not block Get notified when operation completed Be able to share threads across many connections In OS: select()/poll() : traditional POSIX polling epoll() : event based polling, on Linux 2.5.44+ Kqueue : on FreeBSD, MacOS X
  • 6.
    How Netty works? NIOServerSocketChannel is a channel that can listen for incoming TCP connections How threads work: boss threads and worker threads. Boss Thread: Each bound ServerSocketChannel has its own boss thread if you opened two server ports such as 80 and 443, you will have two boss threads A boss thread accepts incoming connections until the port is unbound. Once a connection is accepted successfully, the boss thread passes the accepted Channel to one of the worker threads
  • 7.
    Main Components Bootstrap andServerBootstrap EventLoop Channel ChannelFuture ChannelPipeline ChannelHandlers ChannelHandlerContext
  • 8.
    ServerBootstrap bind() ServerChannel Channel ServerChannelis created when bind() is called A new channel is created when a connection is accepted
  • 9.
  • 10.
    Project Structure app/ Contains application’score in models, controllers and views conf/ Application config files, route definition file, message file for internationalization etc. project/ Contains the build script public/ Contains all publically available resources like javascripts, stylesheets and images
  • 11.
  • 12.
    REQUEST RESPONSE Controller Business DataAccess Presentation Database Web Application Overview
  • 13.
  • 14.
    Introduction Component that translateseach incoming HTTP request to an action call Made up of HTTP Verb, path and action function All calls go to right method with help of routers
  • 15.
    Routers Route Example GET /indexcontrollers.Application.index() Method Path Method
  • 16.
  • 17.
  • 18.
    Controllers, Actions andResult Controllers are classes Located in apps/controllers folder Inherit from abstract controllers class Methods which handle request inside controllers are called actions Return Result object
  • 19.
  • 20.
    Play Views Scala comeswith Twirl, a scala based template engine Twirl engine is: Compact, expressive and fluid Easy to learn Easy to edit It is a simple text file which contains small scala code blocks Very close to HTML Simple naming convention views/filename.scala.html
  • 21.
  • 22.
    Object Relational Mapping Duringapplication development, we want to focus on business concepts, not relational database structure Provide abstraction during communication with database Allow automatic synchronization between java objects and database tables Database independent Query abstraction, database specific queries are autogenerated Object and query caching is done by ORM
  • 23.
    Java Persistence API(JPA) Specification for management of persistence and object relational mapping with java Provide object relational mapping by mapping java POJOs to relational databases POJO based persistence model Support for enriched domain modeling i.e. inheritance, polymorphism etc Expanded query language Support for pluggable persistence provider
  • 24.
    JPA: Persistence Entity AnnotatedPOJO Lightweight persistent domain model Persistent identity field Provide support for Abstract class and inheritance Relationships (OneToOne, OneToMany, ManyToMany) Each entity is typically represented by one table Each entity can have both persistent and nonpersistent state
  • 25.
    Data Model Set ofconcepts to describe structure of database Specify constraints that database should follow Operations on data model may include basic operations and user defined operations Building blocks Entity : data will be stored and collected in them Attribute: Characteristics of entity Relationship: association between entities
  • 26.
  • 27.
    Evolutions Helps track andorganize your database schema (in case of relational databases) Play tracks your database evolutions using several evolutions script. Scripts located at: conf/evolutions/{database name} Each script contains two parts: The Ups part the describe the required transformations. The Downs part that describe how to revert them. Evolutions are automatically activated if a database is configured in
  • 28.
  • 29.
    Filters The filter APIis intended for cross cutting concerns that are applied indiscriminately to all routes. Filters wrap the action after the action has been looked up by the router. Cannot use a filter to transform a path, method or query parameter to impact the router. Can direct the request to a different action by invoking that action directly from the filter Common use case of filters: Logging/metrics collection
  • 30.
  • 31.
    Introduction Dependency Injection isability to inject external dependency into software component Benefits: Easier testing and refactoring Easier maintenance Loose coupling Managing object lifetime Better design and use Hide implementation details
  • 32.
    Guice Dependency injection framework Conventionover configuration Easier to use, test, maintain, refactor and learn Static and compile time verification Favor good design with immutability, valid object and thread safe object Basic Annotations @Inject @ImplementedBy
  • 33.
    Logging Introduction Why Logs Add Logs BestPractices MDC And Default Parameters
  • 34.
    Why we needlogging? Monitoring Debugging Error Tracking Business Intelligence Play provides an API for logging which is accessed through the Logger object and uses Logback as the default logging engine.
  • 35.
    Logback Logging Architecture Differentcomponents: Logger Default logger named “application” Can create our own logger Log Level : OFF : use to turn off logging ERROR: Runtime error, or unexpected exception WARN: Deprecated Api, unexpected situation
  • 36.
    Logback Logging Architecture Appender Handleresponsibility to write event to component Kinds of appender: OutputStreamAppender: Append events to OutputStream ConsoleAppender: Append events to console, or System.out or System.err FileAppender: Append events to file RollingFileAppender: Append events to file with the capability to rollover log files Time based rolling policy Size and time based rolling policy
  • 37.
  • 38.
    Logback Logging Architecture Encoder Acceptevents and transform these events into byte array Write into output stream Total control of what and when bytes gets written to the output stream Layout Transform an incoming event into a String Has no control over when events get written out Layouts can not aggregate events into batches
  • 39.
    Using Logger Import play.Logger Logger.debug("Result={}",result) Never do Logger.debug(“Result=”+result), as it will do string concatenation every time without we actually adding it in log file based on Log level. Play puts both the console and the file logger behind the logback AsyncAppender Config file path : conf/logback.xml
  • 40.
    Sample appender logback.xml <appendername="FILE" class="ch.qos.logback.core.FileAppender"> <file>${application.home:-.}/logs/application.log</file> <encoder> <pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern> </encoder> </appender> <appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender"> <appender-ref ref="FILE" /> </appender> <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender"> <appender-ref ref="STDOUT" /> </appender>
  • 41.
    MDC: Map DiagnosticContext Help uniquely stamp request Manages contextual information on a per thread basis MDC.put(“userkey”, value) MDC.remove(“userkey”) <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%coloredLevel %logger{15} %X{userkey} - %message%n%xException{10}</pattern> </encoder> </appender>
  • 42.
    Best Practices Always keepdate on log file name Always add some name to your log file name, which help in distinguish it from other log files. Always log time and date of events Store date in YYYYMMDDHHMMSS format (ideally) as it helps in sorting. Use 24 hour time format. In multi threaded system, use thread id. Use different name of logger, depending on kind of logs as that help in
  • 43.
    Best Practices Log singleevent in single line, stack trace kind of thing can be multiline. Log with a delimiter between fields so logs can be easily parsed. Don’t skip empty fields add something like - or delimiter to identify it. Log identification information as that helps in debugging. Don’t log sensitive information like passwords etc.
  • 44.