Top Banner
Bob McWhirter Red Hat TorqueBox Ruby on Rails (and Rack) with Enterprise Goodness John Williams
114

TorqueBox

Jan 19, 2015

Download

Technology

bobmcwhirter

Presentation on TorqueBox at Strange Loop 2009 in St. Louis, Missouri
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: TorqueBox

Bob McWhirterRed Hat

TorqueBoxRuby on Rails (and Rack) with Enterprise Goodness

John Williams

Page 2: TorqueBox

Agenda: Part 1

Who are these guys up here, talking to you?

The Language Cusp

Ruby vs Java

Polyglotism

Picture of Bill

App servers for Java and Ruby

Basic of Rails on TorqueBox

Beyond Rails on TorqueBox

Rack on TorqueBox

Sinatra on TorqueBox

Page 3: TorqueBox

Agenda: Part 2

Why TorqueBoxDeploying with BundlesDeploying using Capistrano

Page 4: TorqueBox

Active in open-source Doing Java for a dozen years Doing Ruby for a handful of years Research & Prototyping group at JBoss

Who is Bob McWhirter?

Page 5: TorqueBox

Early user of TorqueBox Interested in anything open-source Doing RoR for 4 years Doing web development for 8 years Wrote theme music to Star Wars

Who is John Williams?

Page 6: TorqueBox

Who are you?

Page 7: TorqueBox

Java is facing competition from other languages

Page 8: TorqueBox

The Language Cusp

Page 9: TorqueBox

a mixture or confusion of

languages

polyglot:

Page 10: TorqueBox

Polyglotism

“Polyglotism is the worst idea I ever heard”-Bill Burke, coworker

Page 11: TorqueBox

Polyglotism

Polyglotism may indeed be bad within a single developer’s head or even within a single team.

RubyJavaScalaGroovy

Ruby Java

Page 12: TorqueBox

Polyglotism

Underlying infrastructure, if polyglotic, can support a larger community and market.

JBoss

Java

Ruby

Other

Page 13: TorqueBox

Services vs APIs

JBoss already has a full suite of enterprise-grade services.

JBoss AS 5.x

Web Container Message Bus SOAP

Page 14: TorqueBox

Services vs APIs

Wrapped with standard Java APIs...

JBoss AS 5.x

Web Container Message Bus SOAP

Servlet API JMS API JAX-WS API

Java Application

Page 15: TorqueBox

Services vs APIs

Why not wrap with Ruby APIs?

JBoss AS 5.x

Web Container Message Bus SOAP

Rails TorqueBox TorqueBox

Ruby Application

Page 16: TorqueBox

Ruby App Server

Then, you end up with an enterprise-grade Ruby app server.

Page 17: TorqueBox

Ruby App Server in 4 Steps

Page 18: TorqueBox

Step 1

Ruby on Rails

Page 19: TorqueBox

Step 1: Rails

JRubyThe guys got regular Rails running well under mongrel using JRuby

There is also Warbler for creating deployable WAR files

Gl*ssfish can run Rails apps in-place

Page 20: TorqueBox

But that’s not good enough

Step 1: Rails

Page 21: TorqueBox

Step 1: Rails on JBoss

JBossRun Rails apps in-place under JBossNo WAR-creation requiredRuns alongside other JEE appsRuns alongside other Servlets within the same application

Page 22: TorqueBox

Step 1.5

Databases

Page 23: TorqueBox

Step 1.5: Databases

Since Java has the very nice JDBC drivers, let’s use them

But don’t want to teach Rubyists JDBCAdd a few ActiveRecord driver gems, and your Rails application accesses the DB through JDBC

Page 24: TorqueBox

Step 1.5: Databases

No changes to config/database.yml required

Rails is managing the connections itself

Page 25: TorqueBox

Step 1.75: Managed connections on Rails

If’n you want to use a managed datasource deployed outside of the application...You can make changes to config/database.yml to use a datasource

Datasource located via JNDI

Page 26: TorqueBox

Step 1.75: Managed connections on Rails

You can even deploy your datasource from within your Rails application:config/mydb-ds.xml

Page 27: TorqueBox

Step 1.97: Deployment

Deployment with TorqueBox is slightly different, but familiar

to JBoss users.

Page 28: TorqueBox

Inversion of Deployment

Traditional RailsYou pull HTTP functionality into your app

You run your app, which listens on a port

Page 29: TorqueBox

Inversion of Deployment: Traditional

Rails Application

controllerscontrollers

controllers

modelsmodels

modelsmodels

viewsviews

views

web-server gemsmongrel, etc

HTTP listener

Page 30: TorqueBox

Rails in an app serverLoad your app into an app-server which already listens to HTTP

App server routes some requests to your app or other apps

Inversion of Deployment

Page 31: TorqueBox

Inversion of Deployment: App server

App Server

HTTP listener

Rails Application

controllerscontrollers

controllers

modelsmodels

modelsmodels

viewsviews

views

Rails Application

controllerscontrollers

controllers

modelsmodels

modelsmodels

viewsviews

views

Page 32: TorqueBox

Deployment

You don’t “start the app”You “deploy” it into an App ServerTorqueBox comes with Rake tasks to helprake torquebox:rails:deployrake torquebox:run

Page 33: TorqueBox

Deployment Descriptor

Page 34: TorqueBox

Simple Deployment

application:

RAILS_ENV: development

RAILS_ROOT: /path/to/my/app

web:

context: /

Page 35: TorqueBox

Simple Deployment

application:

RAILS_ENV: development

RAILS_ROOT: /path/to/my/app

web:

context: /

Page 36: TorqueBox

Simple Deployment

application:

RAILS_ENV: development

RAILS_ROOT: /path/to/my/app

web:

context: /

Page 37: TorqueBox

Simple Deployment

application:

RAILS_ENV: development

RAILS_ROOT: /path/to/my/app

web:

context: /

host: www.myhost.com

Page 38: TorqueBox

Act like normal

Once deployed, continue to editModelsViewsControllers

Without re-deploying your app

Page 39: TorqueBox

Go beyond Rails

Page 40: TorqueBox

Step 2: Scheduled Jobs

Sometimes you’ve got a recurring task not associated with a web request

A cron job

Page 41: TorqueBox

Step 2: Scheduled Jobs

Let’s use Quartz, it comes with JBoss

github.commit_poller: description: Poll GitHub job: Github::CommitPoller cron: 12 */10 * * * ?

config/jobs.yml

Page 42: TorqueBox

Step 2: Scheduled Jobs

We’re used toapp/controllers/**.rb

app/views/**.erb

app/models/**.rb

So let’s go withapp/jobs/**.rb

Page 43: TorqueBox

Step 2: Scheduled Jobs

module GitHub

class CommitPoller

include TorqueBox::Jobs::Base

def run()

# do work here

end

end

end

Page 44: TorqueBox

Step 2: Scheduled Jobs

module GitHub

class CommitPoller

include TorqueBox::Jobs::Base

def run()

# do work here

end

end

end

Page 45: TorqueBox

Step 2: Scheduled Jobs

module GitHub

class CommitPoller

include TorqueBox::Jobs::Base

def run()

# do work here

end

end

end

Page 46: TorqueBox

Step 2: Scheduled Jobs

module GitHub

class CommitPoller

include TorqueBox::Jobs::Base

def run()

# do work here

end

end

end

Page 47: TorqueBox

Step 2: Scheduled Jobs

Jobs will deploy with your appJobs will undeploy with your appJobs have complete access to your ActiveRecord models

Jobs have complete access to your lib/ classes

Jobs can be live edited like anything else

Page 48: TorqueBox

Well, that was easy

Page 49: TorqueBox

Step 3: Async Task Queues

Sometimes you want something non-recurring to happen

Perhaps outside of the context of a web request

Perhaps triggered by a web request, though

Page 50: TorqueBox

That sounds like a message queue.

JBoss has one of those.

Page 51: TorqueBox

Step 3: Async Task Queues

Like you’d expect...app/queues/**.rb

A class per queueA method per task

Page 52: TorqueBox

Step 3: Async Task Queues

class MyQueue

include TorqueBox::Queue::Base

def do_something(payload={})

# do work here

end

end

Page 53: TorqueBox

Step 3: Async Task Queues

class MyQueue

include TorqueBox::Queue::Base

def do_something(payload={})

# do work here

end

end

Page 54: TorqueBox

Step 3: Async Task Queues

class MyQueue

include TorqueBox::Queue::Base

def do_something(payload={})

# do work here

end

end

Page 55: TorqueBox

Step 3: Async Task Queues

class MyQueue

include TorqueBox::Queue::Base

def do_something(payload={})

# do work here

end

end

Page 56: TorqueBox

Step 3: Enqueuing

MyQueue.enqueue(:do_something,{

:quantity=>100,

:cheese=>:gouda

})

Page 57: TorqueBox

Step 3: Enqueuing

MyQueue.enqueue(:do_something,{

:quantity=>100,

:cheese=>:gouda

})

Page 58: TorqueBox

Step 3: Enqueuing

MyQueue.enqueue(:do_something,{

:quantity=>100,

:cheese=>:gouda

})

Page 59: TorqueBox

Step 3: Async Task Queues

A JMS queue is created for each queue class

The payload is anything that can be serialized into bytesIncluding ActiveRecord models

Page 60: TorqueBox

Sometimes you’ve got to use SOAP

Page 61: TorqueBox

Step 4: SOAP

Sure, SOAP is obnoxiousSOAP from Ruby is obnoxious, and underpowered

Apache CXF is some good stuffSometimes you have to do SOAP, so at least you can do it from Ruby

Page 62: TorqueBox

Step 4: SOAP

Goal is not to generate WSDL from Ruby endpoints

Instead, only supports binding Ruby endpoints to existing WSDL

If you’re doing greenfield development, prefer REST. Or sockets. Or pigeons.

Page 63: TorqueBox

Step 4: SOAP

As you’d expect, again...app/endpoints/**.rb

app/endpoints/**.wsdl

Page 64: TorqueBox

Step 4: SOAP

module Amazon class Ec2Endpoint

include TorqueBox::Endpoints::Base

endend

Page 65: TorqueBox

Step 4: SOAP

module Amazon

class Ec2Endpoint

include TorqueBox::Endpoints::Base

endpoint_configuration do

target_namespace 'http://ec2.amazonaws.com/doc/2008-12-01/'

port_name 'AmazonEC2'

security do

inbound do

verify_timestamp

verify_signature

end

end

end

end

end

Page 66: TorqueBox

Step 4: SOAP

module Amazon

class Ec2Endpoint

include TorqueBox::Endpoints::Base

endpoint_configuration do

target_namespace 'http://ec2.amazonaws.com/doc/2008-12-01/'

port_name 'AmazonEC2'

security do

inbound do

verify_timestamp

verify_signature

end

end

end

end

end

Page 67: TorqueBox

Step 4: SOAP

module Amazon

class Ec2Endpoint

include TorqueBox::Endpoints::Base

endpoint_configuration do

target_namespace 'http://ec2.amazonaws.com/doc/2008-12-01/'

port_name 'AmazonEC2'

security do

inbound do

verify_timestamp

verify_signature

end

end

end

end

end

Page 68: TorqueBox

Step 4: SOAP

module Amazon

class Ec2Endpoint

def describe_instances

response = create_response

request.instancesSet.each do |instance_id| reservation_info = response.reservationSet.create reservation_info.ownerId = ... end

return response

end end

end

Page 69: TorqueBox

Step 4: SOAP

TorqueBox provides...full request/response XSD data-binding (like JAXB)

security, such as X.509 signature verification

Page 70: TorqueBox

Now you have a pretty nice Ruby app server.

Not too shabby.

Page 71: TorqueBox

Wait, that was just Ruby on Rails...

Page 72: TorqueBox

Anything Rack

TorqueBox uses Rack plumbing to handle RoR

Now Soon will allow deploying of arbitrary Rack applications

Page 73: TorqueBox

config.ru

app = lambda{|env|

[ 200,

{'Content-Type'=>'text/html'},

'Hello World']

}

run app

Page 74: TorqueBox

config.ru

app = lambda{|env|

[ 200,

{'Content-Type'=>'text/html'},

'Hello World']

}

run app

Page 75: TorqueBox

config.ru

app = lambda{|env|

[ 200,

{'Content-Type'=>'text/html'},

'Hello World']

}

run app

Page 76: TorqueBox

config.ru

app = lambda{|env|

[ 200,

{'Content-Type'=>'text/html'},

'Hello World']

}

run app

Page 77: TorqueBox

config.ru

app = lambda{|env|

[ 200,

{'Content-Type'=>'text/html'},

'Hello World']

}

run app

Page 78: TorqueBox

config.ru

app = lambda{|env|

[ 200,

{'Content-Type'=>'text/html'},

'Hello World']

}

run app

Page 79: TorqueBox

*-rack.yml

application: RACK_ROOT: /path/to/myapp RACK_ENV: production rackup: config.ru

web: host: myapp.com

Page 80: TorqueBox

*-rack.yml

application: RACK_ROOT: /path/to/myapp RACK_ENV: production rackup: config.ru

web: host: myapp.com

Page 81: TorqueBox

*-rack.yml

application: RACK_ROOT: /path/to/myapp RACK_ENV: production rackup: config.ru

web: host: myapp.com

Page 82: TorqueBox

*-rack.yml

application: RACK_ROOT: /path/to/myapp RACK_ENV: production rackup: config.ru

web: host: myapp.com

Page 83: TorqueBox

*-rack.yml

application: RACK_ROOT: /path/to/myapp RACK_ENV: production rackup: config.ru

web: host: myapp.com

Page 84: TorqueBox

*-rack.yml

application: RACK_ROOT: /path/to/myapp RACK_ENV: production rackup: config.ru

web: host: myapp.com

Page 85: TorqueBox

Sinatra!

Page 86: TorqueBox

config.ru

require 'app'

use TorqueBox::Rack::Reloader,

File.dirname(__FILE__)

run Sinatra::Application

Page 87: TorqueBox

config.ru

require 'app'

use TorqueBox::Rack::Reloader,

File.dirname(__FILE__)

run Sinatra::Application

Page 88: TorqueBox

config.ru

require 'app'

use TorqueBox::Rack::Reloader,

File.dirname(__FILE__)

run Sinatra::Application

Page 89: TorqueBox

config.ru

require 'app'

use TorqueBox::Rack::Reloader,

File.dirname(__FILE__)

run Sinatra::Application

Page 90: TorqueBox

app.rb

require 'rubygems'require 'sinatra'

get '/' do "Hello world"end

Page 91: TorqueBox

app.rb

require 'rubygems'require 'sinatra'

get '/' do "Hello world"end

Page 92: TorqueBox

app.rb

require 'rubygems'require 'sinatra'

get '/' do "Hello world"end

Page 93: TorqueBox

app.rb

require 'rubygems'require 'sinatra'

get '/' do "Hello world"end

Page 94: TorqueBox

Questions?

Page 95: TorqueBox

Deploying Rails Applications to

TorqueBox

Page 96: TorqueBox

Why TorqueBox?

Page 97: TorqueBox

Why TorqueBox?Rails Application

20 Mongrels

Rails Application

20 Mongrels

TorqueBox

Rails Application Rails Application

Capistrano Deployed Bundle Deployed

Page 98: TorqueBox

Methods to Deploy

Application Bundle CapistranoOR

Page 99: TorqueBox

Application Bundle

What is an Application Bundle?

Page 100: TorqueBox

Application Bundle

Web Application Archive (WAR) of your Rails application.

It will be created with a .rails file extension.

Page 101: TorqueBox

Application Bundle

How do I create it?

Page 102: TorqueBox

Application Bundle

App Bundle Rake tasks:

rake torquebox:rails:bundlerake torquebox:rails:deploy:bundle

Page 103: TorqueBox

Application Bundle

What to do next?

Page 104: TorqueBox

Application Bundle

Drop it in your TorqueBox deploy directory.

ORDeploy it locally using the Rake tasks using:

rake torquebox:rails:deploy:bundle

Page 105: TorqueBox

Application Bundle

Don’t forget...

Page 106: TorqueBox

Application Bundle

config/web.yml

ANDconfig/rails-env.yml

Page 107: TorqueBox

config/web.yml

Host ContextAND

Page 108: TorqueBox

config/web.yml

Example:

host: torquebox.orgcontext: /

Page 109: TorqueBox

config/rails-env.yml

Rails Environment

Page 110: TorqueBox

config/rails-env.yml

Example:

RAILS_ENV: production

Page 111: TorqueBox

Capistrano

Complete Example:

http://github.com/torquebox/ballast-rails

Page 112: TorqueBox

Capistrano

daemontools init.dAND

Supports:

Page 113: TorqueBox

Capistrano

Don’t Forget...

require 'recipes/torquebox'

Page 114: TorqueBox

Questions?