Jaoo Michael Neale 09
- 1. JBoss
Rules, Rails
JAOO, Australia, 2009
Sydney, Brisbane
Michael Neale
JBoss R&D
Red Hat Middleware
1
- 2. Michael Neale
R&D on Drools (rule engine).
Open source history (user -> fulltime
developer).
Contribute to other jboss and non jboss
projects
me on the web:
www.michaelneale.net, twitter.com/michaelneale,
michaelneale.blogspot.com
2
- 3. Agenda
•Doing more with less...
•But isn't java hard/slow?
•Quick introduction to Rails basics
•Setting up JBoss for Rails
•What are rules and why use them?
•Drools
3
- 4. More, with less
Does any one need to:
Build apps of growing complexity
Do it quicker and cheaper
Cope with people changing their mind
All the time
At runtime
If not – you can go !
4
- 5. Drools:
Logic and declarative programming for
developers
User friendly GUIs and management
tools for the rest
Allows controlled changes to business
logic (even at runtime)
5
- 6. Rails
Popular RESTful web-app framework
(full stack)
Runs just fine on the JVM
Famous for productivity
6
- 19. ERb Templates
<p>
There are <%= @post.comments.size %>
new comments since your last visit:
</p>
<% for comment in @post.comments %>
<% div_for( comment ) do %>
<%= comment.author.full_name %>
<% end %>
<% end %>
19
- 21. ActionController
class CommentsController < ApplicationController
before_filter :load_post
def create
@comment = @post.comments.build( params[:comment] )
....
end
private
def load_post
@post = Post.find_by_slug( params[:slug] )
redirect_to posts_url and return false unless @post
end
end
21
- 22. ActionController
Actions
class CommentsController < ApplicationController
before_filter :load_post
def create
@comment = @post.comments.build( params[:comment] )
....
end
private
def load_post
@post = Post.find_by_slug( params[:slug] )
redirect_to posts_url and return false unless @post
end
end
22
- 23. ActionController
Filters
class CommentsController < ApplicationController
before_filter :load_post
def create
@comment = @post.comments.build( params[:comment] )
....
end
private
def load_post
@post = Post.find_by_slug( params[:slug] )
redirect_to posts_url and return false unless @post
end
end
23
- 26. Run Rails in the
JVM
After solving a few
issues, Rails runs
easily within most any
servlet container.
26
- 27. Why JBoss, then?
•JBoss provides a perfectly nice servlet
container.
•JBoss provides a whole lot more, too:
•JMS
• Transactions
•Rules-Engine
•Telecom
27
- 28. Rails is not enough
Rails is a great
solution...
for the web.
28
- 30. Ruby is just a
syntax
Approach Ruby as just
another syntax for
driving JEE/JVM
technologies.
30
- 32. Ingredients
JDK6
JBoss AS5
JRuby
Rails
JBoss-Rails
32
- 34. Install JBoss AS5.x
$ unzip jboss-5.0.1.GA-jdk6.zip
Archive: jboss-5.0.1.GA-jdk6.zip
creating: jboss-5.0.1.GA/
creating: jboss-5.0.1.GA/bin/
...
34
- 35. Set $JBOSS_HOME
$ cd jboss-5.0.1.GA
$ export JBOSS_HOME=$PWD
$ echo $JBOSS_HOME
/Users/mic/jboss-5.0.1.GA
35
- 36. Install JRuby
$ unzip jruby-bin-1.2.0RC2.zip
Archive: jruby-bin-1.2.0RC2.zip
creating: jruby-1.2.0RC2/
creating: jruby-1.2.0RC2/bin/
...
36
- 37. Prefer JRuby
$ cd jruby-1.2.0RC2/
$ export JRUBY_HOME=$PWD
$ export
PATH=$JRUBY_HOME/bin:$PATH
37
- 39. JBoss-Rails
The Deployer
The first part of JBoss-
Rails is the deployer.
39
- 40. JBoss-Rails
The Deployer
The deployer makes
JBoss AS5 Rails-
aware.
40
- 41. JBoss-Rails
The Deployer
Install it into the
server’s deployers/
directory
41
- 45. (or copy it)
$ cp jboss-rails-deployer.jar
$JBOSS_HOME/server/default/deployers/
45
- 47. JBoss-Rails
jboss-rails-support
The second part of
JBoss-Rails is
application-support
library.
47
- 48. JBoss-Rails
jboss-rails-support
It goes right into your Rails
app.
So we need a Rails app.
48
- 49. Install Rails
$ gem install rails --version 2.2.2
Successfully installed activesupport-2.2.2
Successfully installed activerecord-2.2.2
Successfully installed actionpack-2.2.2
Successfully installed actionmailer-2.2.2
Successfully installed activeresource-2.2.2
Successfully installed rails-2.2.2
6 gems installed
49
- 50. Create an app
$ rails twiggl
create
create app/controllers
create app/helpers
create app/models
create app/views/layouts
create config/environments
create config/initializers
create config/locales
...
50
- 51. Freeze Rails
$ rake rails:freeze:gems
Freezing to the gems for Rails 2.2.2
rm -rf vendor/rails
mkdir -p vendor/rails
cd vendor/rails
Unpacked gem: '/Users/bob/twiggl/vendor/rails/activesupport-2.2.2'
mv activesupport-2.2.2 activesupport
Unpacked gem: '/Users/bob/twiggl/vendor/rails/activerecord-2.2.2'
mv activerecord-2.2.2 activerecord
Unpacked gem: '/Users/bob/twiggl/vendor/rails/actionpack-2.2.2'
mv actionpack-2.2.2 actionpack
Unpacked gem: '/Users/bob/twiggl/vendor/rails/actionmailer-2.2.2'
mv actionmailer-2.2.2 actionmailer
Unpacked gem: '/Users/bob/twiggl/vendor/rails/activeresource-2.2.2'
mv activeresource-2.2.2 activeresource
Unpacked gem: '/Users/bob/twiggl/vendor/rails/rails-2.2.2'
cd -
51
- 53. JBoss-Rails
jboss-rails-support
Now we can install the
application-support
library.
53
- 54. JBoss-Rails
jboss-rails-support
$ cd vendor/plugins/
$ unzip ~/downloads/jboss-rails-support.zip
Archive: /Users/bob/downloads/jboss-rails-support.zip
creating: jboss-rails-support/
creating: jboss-rails-support/lib/
creating: jboss-rails-support/lib/jboss/
creating: jboss-rails-support/lib/jboss/endpoints/
creating: jboss-rails-support/lib/jboss/jobs/
creating: jboss-rails-support/lib/recipes/
creating: jboss-rails-support/lib/tasks/
inflating: jboss-rails-support/init.rb
.....
54
- 57. Create the DB stuff
postgres> create user twiggl
with password 'twiggl';
CREATE ROLE
postgres> create database
twiggl_development
with owner twiggl
encoding 'UTF8';
CREATE DATABASE
57
- 58. Set up your app
config/database.yml
development:
adapter: postgresql
database: twiggl_development
username: twiggl
password: twiggl
host: localhost
encoding: UTF8
58
- 59. Set up your app
config/database.yml
development:
adapter: postgresql
Just like
database: twiggl_development
username: twiggl
regular Rails!
password: twiggl
host: localhost
encoding: UTF8
59
- 63. Install the JDBC
gems activerecord-jdbc
$ rake jboss:gems:jdbc:install
INFO: Installing activerecord-jdbc
adapter-0.8.3
63
- 65. You’re ready!
•AS5 is ready to serve Rails apps.
•A bare database is setup.
•A bare Rails app is setup.
• Configured to access the database.
•Using JDBC.
•Extra JBoss goodness is installed.
65
- 68. Deployment Descriptor
$JBOSS_HOME/server/default/deploy/twiggl-
rails.yml
application:
RAILS_ENV: development
RAILS_ROOT: /Users/bob/twiggl
web:
context: /
68
- 70. Start AS
$ rake jboss:as:run
(in /Users/bob/twiggl)
JBoss-Rails server: /Users/bob/jboss-5.0.1.GA/server/default
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: /Users/bob/jboss-5.0.1.GA
JAVA: /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home//bin/java
JAVA_OPTS: -Dprogram.name=run.sh -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss. resolver.warning=true -Dsun.
rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000
CLASSPATH: /Users/bob/preso/jboss-5.0.1.GA/bin/run.jar
=========================================================================
13:44:45,281 INFO [ServerImpl] Starting JBoss (Microcontainer)...
13:44:45,283 INFO [ServerImpl] Release ID: JBoss [Morpheus] 5.0.1.GA (build: SVNTag=JBoss_5_0_1_GA date=200902232048)
13:44:45,283 INFO [ServerImpl] Bootstrap URL: null
13:44:45,283 INFO [ServerImpl] Home Dir: /Users/bob/j boss-5.0.1.GA
13:44:45,283 INFO [ServerImpl] Home URL: file:/Users/bob/jboss-5.0.1.GA/
13:44:45,287 INFO [ServerImpl] Library URL: fi le:/Users/bob/jboss-5.0.1.GA/lib/
13:44:45,288 INFO [ServerImpl] Patch URL: null
13:44:45,288 INFO [ServerImpl] Common Base URL: fi le:/Users/bob/jboss-5.0.1.GA/common/
13:44:45,288 INFO [ServerImpl] Common Library URL: file:/Users/bob/jboss-5.0.1.GA/common/lib/
13:44:45,288 INFO [ServerImpl] Server Name: default
13:44:45,289 INFO [ServerImpl] Server Base Dir: /Users/bob/jboss-5.0.1.GA/server
13:44:45,289 INFO [ServerImpl] Server Base URL: file:/Users/bob/jboss-5.0.1.GA/server/
13:44:45,289 INFO [ServerImpl] Server Confi g URL: file:/Users/bob/jboss-5.0.1.GA/server/default/conf/
13:44:45,289 INFO [ServerImpl] Server Home Dir: /Users/bob/jboss-5.0.1.GA/server/default
13:44:45,289 INFO [ServerImpl] Server Home URL: file:/Users/bob/jboss-5.0.1.GA/server/default/
70
- 74. Create models
$ jruby ./script/generate resource twig
...
create app/models/twig.rb
...
create db/migrate/20090308180254_create_twigs.rb
74
- 75. Create models
$ jruby ./script/generate resource twig
...
create app/models/twig.rb
...
create db/migrate/20090308180254_create_twigs.rb
...
create app/controllers/twigs_controller.rb
75
- 76. Create models
$ jruby ./script/generate resource twig
...
create app/models/twig.rb
...
create db/migrate/20090308180254_create_twigs.rb
...
create app/controllers/twigs_controller.rb
...
route map.resources :twigs
76
- 77. Create models
db/migrate/*_create_twigs.rb
class CreateTwigs < ActiveRecord::Migration
def self.up
create_table :twigs do |t|
t.string :name, :limit=>42, :null=>false
t.timestamps
end
end
def self.down
drop_table :twigs
end
end
77
- 78. Blow it into the DB
$ rake db:migrate
(in /Users/bob/twiggl)
== CreateTwigs: migrating
===============
-- create_table(:twigs)
-> 0.0669s
-> 0 rows
== CreateTwigs: migrated (0.0683s) ======
78
- 79. Rough in a controller
app/controllers/twigs_controller.rb
class TwigsController < ApplicationController
def index
@twigs = Twig.find( :all )
end
end
79
- 80. Rough in a template
app/views/twigs/index.html.erb
<p>
There are <%= @twigs.size %> twigs.
</p>
<% for twig in @twigs %>
<% div_for( twig ) do %>
<%= twig.name %>
<% end %>
<% end %>
80
- 81. Rough in a template
app/views/twigs/index.html.erb
<p>
There are <%= @twigs.size %> twigs.
</p>
<% for twig in @twigs %>
<% div_for( twig ) do %>
<%= twig.name %>
<% end %>
<% end %>
81
- 82. Rough in a template
app/views/twigs/index.html.erb
<p>
There are <%= @twigs.size %> twigs.
</p>
<% for twig in @twigs %>
<% div_for( twig ) do %>
<%= twig.name %>
<% end %>
<% end %>
82
- 86. Twig form
app/views/twigs/new.html.erb
<% form_for @twig do %>
<%= label :twig, :name %>
<%= text_field :twig, :name %>
<%= submit_tag 'Create twig!' %>
<% end %>
86
- 88. Twig view
app/views/twigs/show.html.erb
<% div_for @twig do %>
<h1><%= @twig.name %></h1>
<% end %>
88
- 96. Jobs
app/jobs/**/*.rb
96
- 97. Job class
app/jobs/twitter_sender.rb
class TwitterSender < JBoss::Jobs::BaseJob
def run
new_twigs = Twig.find( :all,
:conditions=>[
'created_at >= ?',
Time.now - 30.minutes
] )
return if new_twigs.empty?
tweet( new_twigs.size )
end
def tweet(num_new_twigs)
..
end
end
97
- 98. Job schedule
config/jobs.yml
twitter.sender:
description: Send a tweet
cron: 0 */30 * * * ?
job: TwitterSender
98
- 99. Job schedule
config/jobs.yml
twitter.sender:
description: Send a tweet
cron: 0 */30 * * * ?
job: TwitterSender
99
- 100. Job schedule
config/jobs.yml
twitter.sender:
description: Send a tweet
cron: 0 */30 * * * ?
job: TwitterSender
100
- 101. Job schedule
config/jobs.yml
twitter.sender:
description: Send a tweet
cron: 0 */30 * * * ?
job: TwitterSender
101
- 102. Job schedule
config/jobs.yml
twitter.sender:
description: Send a tweet
cron: 0 */30 * * * ?
job: TwitterSender
102
- 104. Why redeploy?
Jobs are deployed when
your app is deployed.
Adding a job means you
need to redeploy your
app.
104
- 106. Hot, hot code
Once your job is
deployed, you can
continue to edit the
actual service method.
106
- 115. Drools
Drools provides a runtime,
compiler and tools to develop
and manage executable
knowledge bases
(all open source of course)
115
- 116. For example:
rule “age and history compliance”
when
Driver(age < 25, sex=”M”)
not Accident(severity > 3)
not Infringement(type==”dui”)
then
approveDriver(“Let this one through”)
end
116
- 117. For example:
rule “age and history compliance”
when
Driver(age < 25, sex=”M”)
not Accident(severity > 3)
not Infringement(type==”dui”)
then
approveDriver(“Let this one through”)
end
117
- 118. For example:
rule “age and history compliance”
when
Driver(age < 25, sex=”M”)
not Accident(severity > 3)
not Infringement(type==”dui”)
then
approveDriver(“Let this one through”)
end
118
- 119. For example:
rule “age and history compliance”
when
Driver(age < 25, sex=”M”)
not Accident(severity > 3)
not Infringement(type==”dui”)
then
approveDriver(“Let this one through”)
end
119
- 120. For example:
rule “age and history compliance”
when
Driver(age < 25, sex=”M”)
not Accident(severity > 3)
not Infringement(type==”dui”)
then
approveDriver(“Let this one through”)
end
120
- 121. For example:
rule “age and history compliance”
when
Driver(age < 25, sex=”M”)
not Accident(severity > 3)
not Infringement(type==”dui”)
then
approveDriver(“Let this one through”)
end
121
- 122. For example:
rule “age and history compliance”
when
Driver(age < 25, sex=”M”)
not Accident(severity > 3)
not Infringement(type==”dui”)
then
approveDriver(“Let this one through”)
end
122