SlideShare a Scribd company logo
1 of 62
Download to read offline
DataMapper on Infinispan
                             Clustered NoSQL
                                 Lance Ball




Thursday, September 22, 11                     1
Lance Ball

                    •Red Hat senior engineer
                    •TorqueBox core developer
                    •Perl -> C++ -> Java -> Ruby
                    •@lanceball

Thursday, September 22, 11                         2
project:odd




Thursday, September 22, 11    3
What are we talking about?


                    • DataMapper - Ruby ORM
                    • Infinispan - Java+Scala distributed cache
                    • Hibernate Search - Java ORM
                    • Lucene - Indexing and search
                    • JBoss AS7 - JEE application server
                    • TorqueBox - JRuby application server

Thursday, September 22, 11                                        4
TorqueBox




                     JRuby Application Server
                       http://torquebox.org
Thursday, September 22, 11                      5
TorqueBox

                             The Power of JBoss

                                   with the

                        Expressiveness of Ruby

Thursday, September 22, 11                        6
Thursday, September 22, 11   7
TorqueBox
                •Ruby, baby!
                •Rack apps
                •Scheduled Jobs
                •Background Tasks
                •Message Queues & Topics
                •Message Processors
                •Long-running Services
                •Distributed / Replicated Cache
Thursday, September 22, 11                        8
JRuby
                   •Healthy community
                   •Real threads
                   •Java libraries
                   •Java tools
                   •Fast runtime
                   •Better memory management**
                         ** for long running things like servers


Thursday, September 22, 11                                         9
Java
                CacheFactory.java

              public class CacheFactory {

                public CacheFactory() {
                  config = new Configuration();
                  store = new FileCacheStoreConfig();
                  store.purgeOnStartup( false );
                  config.fluent().loaders().addCacheLoader( store );
                  manager = new DefaultCacheManager( config.build() );
                }

                public Cache getCache() { return manager.getCache(); }
              }




Thursday, September 22, 11                                               10
JRuby
                cache_factory.rb

              class CacheFactory
                def initialize
                  @config = Configuration.new
                  @store = FileCacheStore.new
                  @store.purge_on_startup false
                  @config.fluent.loaders.add_cache_loader( @store )
                  @manager = DefaultCacheManager.new( @config.build )
                end

                def get_cache ; @manager.get_cache end
              end




Thursday, September 22, 11                                              11
Infinispan

                       An extremely scalable,
                       highly available data grid

                       http://www.jboss.org/infinispan



Thursday, September 22, 11                              12
Infinispan

                    •Key / Value store
                    •Highly concurrent core
                    •Data Grid
                     •Replicated
                     •Distributed
                     •Local
Thursday, September 22, 11                    13
Hotrod

                    •Binary TCP protocol
                    •Clients
                     •Java
                     •Python
                     •Ruby
                     •...
Thursday, September 22, 11                 14
NoSQL?

                    •Non-relational
                    •Scales out, not up
                    •Big data
                    •Low ceremony

Thursday, September 22, 11                15
Infinispan API
                Cache.java

                 cache.put(key, value, lifespan, timeUnit);

                 cache.putIfAbsent(key, value, lifespan, timeUnit);

                 cache.replace(key, oldVal, value, lifespan, timeUnit);

                 cache.putAsync(key, value, lifespan, timeUnit);

                 cache.keySet();

                 cache.values();

                 cache.entrySet();




Thursday, September 22, 11                                                16
Hibernate Search
                Example.java



                    import org.hibernate.search.annotations.*;

              @Indexed @ProvidedId
              public class Book {
                 @Field String title;
                 @Field String description;
                 @Field Date publicationYear;
              }




Thursday, September 22, 11                                       17
Indexing: Lucene
                Search.java


                    org.apache.lucene.search.Query luceneQuery =
                      queryBuilder.phrase()
                                    .onField( "description" )
                                    .andField( "title" )
                                    .sentence( "pat the bunny" )
                                    .createQuery();

              CacheQuery query = searchManager.getQuery( luceneQuery,
                                                         Book.class );




Thursday, September 22, 11                                               18
DataMapper

                    •Object Relational Mapper
                    •Alternative to ActiveRecord
                    •Written in Ruby
                    •http://datamapper.org

Thursday, September 22, 11                         19
Resources
                beer.rb

              class Beer
                include DataMapper::Resource
                property   :id,     Serial
                property   :name,   String
                property   :rating, Integer
                property   :notes, Text
                belongs_to :user
              end



Thursday, September 22, 11                     20
DataMapper Queries
                sample.rb


              Beer.all

              Beer.get(1)

              Beer.first( :name => 'Pisgah Pale' )

              Beer.last( :name.like => 'IPA' )

              Beer.all( :notes.like => 'hoppy' )




Thursday, September 22, 11                           21
DataMapper Adapter SPI
                sample_adapter.rb

              module DataMapper::Adapters

                class        SampleAdapter < AbstractAdapter
                  def        initialize( name, options ) ; end
                  def        create( resources ) ; end
                  def        read( query ) ; end
                  def        update( attributes, collection ) ; end
                  def        delete( collection ) ; end
                end

              end




Thursday, September 22, 11                                            22
DataMapper Filtering
                some_adapter.rb




                  def read( query )
                    records = @search_manager.search( query )
                    query.filter_records( records )
                  end




Thursday, September 22, 11                                      23
Testing
                adapter_spec.rb

              require 'dm-core/spec/shared/adapter_spec'
              describe DataMapper::Adapters::InfinispanAdapter do

                before :all do
                  @adapter = DataMapper.setup(:default,
                                              :adapter => 'infinispan')
                end

                it_should_behave_like 'An Adapter'

                describe "other important things to test" do
                  # Your tests here
                end
              end



Thursday, September 22, 11                                                24
torquebox-cache

                    • TorqueBox 2.0 gem
                    • dm-infinispan-adapter
                    • TorqueBox::Infinispan::Cache
                    • ActiveSupport::Cache::TorqueBoxStore


Thursday, September 22, 11                                   25
dm-infinispan-adapter



                       Use Infinispan as your
                       object data store



Thursday, September 22, 11                     26
dm-infinispan-adapter
               require 'dm-core'
               require 'dm-infinispan-adapter'

               class Beer
                 include DataMapper::Resource
                 property :id,     Serial
                 property :name,   String
                 property :rating, Integer
                 property :notes, Text
                 belongs_to :user
               end

               DataMapper.setup(:default,
                                :adapter=>'infinispan', :persist=>true)




Thursday, September 22, 11                                                27
But How?


Thursday, September 22, 11              28
Hibernate Search


                       Annotated Java classes




Thursday, September 22, 11                      29
Runtime Class Creation


                       How do we make Ruby’s
                       Beer.class look like an
                       annotated Java class at
                       runtime?


Thursday, September 22, 11                       30
Metaprogramming!
                dm-infinispan-adapter.rb


         require 'datamapper/model'

         module DataMapper::Adapters

           class InfinispanAdapter < AbstractAdapter

             DataMapper::Model.append_inclusions( Infinispan::Model )

           end
         end




Thursday, September 22, 11                                              31
Metaprogramming!
                datamapper/model.rb


         module Infinispan
           module Model

             def self.included(model)
               model.extend(ClassMethods)
               model.before_class_method(:finalize, :configure_index)
             end

           end
         end




Thursday, September 22, 11                                              32
Annotations
                datamapper/model.rb




        require ‘jruby/core_ext’

        annotation = {org.hibernate.search.annotations.Field => {}}
        add_method_annotation( “getName”, annotation )




Thursday, September 22, 11                                            33
Annotations
                datamapper/model.rb


        require ‘jruby/core_ext’

        annotation = {
          org.hibernate.search.annotations.Indexed => {},
          org.hibernate.search.annotations.ProvidedId => {},
          org.infinispan.marshall.SerializeWith => {"value" =>
        org.torquebox.cache.marshalling.JsonExternalizer.java_class }}

        add_class_annotation( annotation )




Thursday, September 22, 11                                               34
Become Java!



              java_class = become_java!




Thursday, September 22, 11                35
JSON Externalizer

                       Forget

                       java.io.Serializable



Thursday, September 22, 11                    36
JSON Externalizer
                JsonExternalizer.java

              public class JsonExternalizer
                  implements Externalizer<IRubyObject> {

              " @Override
              " public void writeObject(ObjectOutput output,
                                         IRubyObject object)
              " " " throws IOException {
              " " String theType = object.getType().getName();
              " " output.writeObject( theType );
              " " output.writeObject( toJSON(object) );
              " }
               }




Thursday, September 22, 11                                       37
JSON Externalizer
                JsonExternalizer.java


              public class JsonExternalizer implements
              Externalizer<IRubyObject> {

              " @Override
              " public IRubyObject readObject(ObjectInput input)
                        throws IOException, ClassNotFoundException {
              " " String theType = (String) input.readObject();
              " " String theJson = (String) input.readObject();
              " " return fromJSON(theJson, theType);"
              " }
               }




Thursday, September 22, 11                                             38
JSON Externalizer
                JsonExternalizer.java


        public class JsonExternalizer
            implements Externalizer<IRubyObject> {

            protected IRubyObject fromJSON(String json,
                                           String type)
                      throws ClassNotFoundException {

                RubyModule objectClass = runtime.getClassFromPath( type );
                return (IRubyObject) JavaEmbedUtils.invokeMethod( runtime,
                                                                  objectClass, "new",
                                                                  new Object[] { jsonHash },
                                                                  IRubyObject.class);
            }
         }




Thursday, September 22, 11                                                                     39
JSON Externalizer
                JsonExternalizer.java



        public class JsonExternalizer implements Externalizer<IRubyObject> {

            protected String toJSON(IRubyObject object) {
                return (String) JavaEmbedUtils.invokeMethod(
                                    getCurrentRuntime(), object, "to_json",
                                    EMPTY_OBJECT_ARRAY, String.class );
            }
         }




Thursday, September 22, 11                                                     40
Sequences
                dm-core/property/serial.rb




              DataMapper::Property::Serial




Thursday, September 22, 11                   41
Sequences
                dm-core/adapters/abstract_adapter.rb




              initialize_serial( resource, next_id )




Thursday, September 22, 11                             42
Sequences
                cache.rb

              module TorqueBox
                module Infinispan

                  class      Cache
                    def      increment( sequence_name, amount = 1 )
                      #      increment an integer
                    end
                    def      decrement(name, amount = 1)
                      #      decrement an integer
                    end
                  end

                end
              end



Thursday, September 22, 11                                            43
Sequences
                dm-infinispan-adapter.rb




              @metadata = Cache.new( options )

              initialize_serial( resource,
                @metadata.increment( “metadata/beers/index” ) )




Thursday, September 22, 11                                        44
Transactions
                cache_spec.rb

                describe "with JTA transactions" do

                  it "should behave like a transaction" do
                    @cache.transaction do |cache|
                      cache.put('Tommy', 'Dorsey')
                      raise "yikes!"
                      cache.put('Elvis', 'Presley')
                    end
                    @cache.get('Tommy').should be_nil
                    @cache.get('Elvis').should be_nil
                  end
                
                 end




Thursday, September 22, 11                                   45
Transactions
                dm-infinispan-adapter.rb



                  def delete( collection )
                    cache.transaction do
                      collection.each do |resource|
                        cache.remove( key(resource) )
                      end
                    end
                  end




Thursday, September 22, 11                              46
TorqueBox::Infinispan::Cache




                       Use Infinispan for...




Thursday, September 22, 11                    47
Cache
                some_file.rb



              include TorqueBox::Infinispan::Cache

              cache = Cache.new(:name => 'MyCache',
                                :mode => :replicated)

              cache.put(key, value)
              cache.get(key)




Thursday, September 22, 11                              48
ActiveSupport::Cache::TorqueBoxStore




                       Caching in Rails.

                       Replaces in-memory or
                       memcached caches.


Thursday, September 22, 11                             49
TorqueBoxStore
                config/application.rb



              module YourApp

                class Application < Rails::Application
                  config.cache_store = :torque_box_store
                end

              end




Thursday, September 22, 11                                 50
TorqueBoxStore
                my_app.rb

              require 'sinatra'
              require 'torquebox'

              class MyApp < Sinatra::Base

                use TorqueBox::Session::ServletStore

                get '/' do
                  session[:message] = 'Hello World!'
                  haml :index
                end

              end




Thursday, September 22, 11                             51
Beer Catalogue!




                             http://www.flickr.com/photos/burnblue/308441464/




Thursday, September 22, 11                                                     52
Model
                beer.rb
        require 'dm-core'
        require 'dm-infinispan-adapter'

        class Beer
          include DataMapper::Resource
          property :id, Serial
          property :name, String
          property :rating, Integer
          property :notes, Text
          belongs_to :user
        end

        DataMapper.setup(:default, :adapter=>'infinispan',
                                   :persist=>true)




Thursday, September 22, 11                                   53
Sinatra
                application.rb
        module BeerCatalogue
          class Application < Sinatra::Base
            get '/' do
              @beers = Beer.all( :user_id => current_user.id )
              haml :index
            end

            post '/beer' do
              Beer.create(
                :name=>params[:name], :notes=>params[:notes],
                :rating=>params[:rating], :user=>current_user)
              redirect '/'
            end
          end
        end



Thursday, September 22, 11                                       54
View
                views/index.haml
        #welcome
          Hello
          =current_user.name

        #body
          #beer-list
            %h2 Your Beers
            - if @beers.empty?
              %strong You haven't rated any beers yet. Do that now!
            %ul
              - @beers.each do |beer|
                %li
                  =beer.name
                  =beer.rating
                  =beer.notes



Thursday, September 22, 11                                            55
Source


                       http://github.com/torquebox/torquebox
                       http://github.com/torquebox/presentations




Thursday, September 22, 11                                         56
Installation
         $ gem install torquebox-server --pre 
             --source http://torquebox.org/2x/builds/LATEST/gem-repo/

         $ gem install bundler

         $ bundle install

         $ torquebox deploy .
         Deployed: beer.yml
             into: /path/to/jboss/standalone/deployments

         $ torquebox run




Thursday, September 22, 11                                              57
http://www.flickr.com/photos/crystalflickr/2317183342/




Thursday, September 22, 11                                                          58
TorqueBox 2.x

                    • Under development
                    • Continuous integration
                    • TorqueBox::Infinispan::Cache
                    • ActiveSupport::Cache::TorqueBoxStore
                    • dm-infinispan-adapter

Thursday, September 22, 11                                   59
TorqueBox 1.x


                    • Version 1.1.1 released in August
                    • Continuous integration
                    • ActiveSupport::Cache::TorqueBoxStore


Thursday, September 22, 11                                   60
Resources

                    •        http://torquebox.org/
                    •        http://github.com/torquebox
                    •        #torquebox on FreeNode
                    •        @torquebox



Thursday, September 22, 11                                 61
Questions




                             http://www.flickr.com/photos/eleaf/2536358399/




Thursday, September 22, 11                                                   62

More Related Content

What's hot

When Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of TorqueboxWhen Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of Torqueboxrockyjaiswal
 
Torquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosTorquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosBruno Oliveira
 
The Enterprise Strikes Back
The Enterprise Strikes BackThe Enterprise Strikes Back
The Enterprise Strikes BackBurke Libbey
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011tobiascrawley
 
JUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxJUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxmarekgoldmann
 
JUDCon 2010 Boston : BoxGrinder
JUDCon 2010 Boston : BoxGrinderJUDCon 2010 Boston : BoxGrinder
JUDCon 2010 Boston : BoxGrindermarekgoldmann
 
Torquebox @ Raleigh.rb - April 2011
Torquebox @ Raleigh.rb - April 2011Torquebox @ Raleigh.rb - April 2011
Torquebox @ Raleigh.rb - April 2011tobiascrawley
 
ZK_Arch_notes_20081121
ZK_Arch_notes_20081121ZK_Arch_notes_20081121
ZK_Arch_notes_20081121WANGCHOU LU
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)ngotogenome
 
Java 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevJava 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevMattias Karlsson
 
When Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the EnterpriseWhen Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the Enterprisebenbrowning
 
Open Source Compiler Construction for the JVM
Open Source Compiler Construction for the JVMOpen Source Compiler Construction for the JVM
Open Source Compiler Construction for the JVMTom Lee
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Hiroshi SHIBATA
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the worldHiroshi SHIBATA
 
Ruby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developerRuby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developergicappa
 
Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Mark Menard
 
Apache Camel: The Swiss Army Knife of Open Source Integration
Apache Camel: The Swiss Army Knife of Open Source IntegrationApache Camel: The Swiss Army Knife of Open Source Integration
Apache Camel: The Swiss Army Knife of Open Source Integrationprajods
 
Spring into rails
Spring into railsSpring into rails
Spring into railsHiro Asari
 

What's hot (19)

When Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of TorqueboxWhen Ruby Meets Java - The Power of Torquebox
When Ruby Meets Java - The Power of Torquebox
 
Torquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundosTorquebox - O melhor dos dois mundos
Torquebox - O melhor dos dois mundos
 
The Enterprise Strikes Back
The Enterprise Strikes BackThe Enterprise Strikes Back
The Enterprise Strikes Back
 
Torquebox OSCON Java 2011
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
 
JUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBoxJUDCon 2010 Boston : TorqueBox
JUDCon 2010 Boston : TorqueBox
 
JUDCon 2010 Boston : BoxGrinder
JUDCon 2010 Boston : BoxGrinderJUDCon 2010 Boston : BoxGrinder
JUDCon 2010 Boston : BoxGrinder
 
Torquebox @ Raleigh.rb - April 2011
Torquebox @ Raleigh.rb - April 2011Torquebox @ Raleigh.rb - April 2011
Torquebox @ Raleigh.rb - April 2011
 
How DSL works on Ruby
How DSL works on RubyHow DSL works on Ruby
How DSL works on Ruby
 
ZK_Arch_notes_20081121
ZK_Arch_notes_20081121ZK_Arch_notes_20081121
ZK_Arch_notes_20081121
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
 
Java 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from OredevJava 7 Whats New(), Whats Next() from Oredev
Java 7 Whats New(), Whats Next() from Oredev
 
When Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the EnterpriseWhen Two Worlds Collide: Java and Ruby in the Enterprise
When Two Worlds Collide: Java and Ruby in the Enterprise
 
Open Source Compiler Construction for the JVM
Open Source Compiler Construction for the JVMOpen Source Compiler Construction for the JVM
Open Source Compiler Construction for the JVM
 
Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0Gemification for Ruby 2.5/3.0
Gemification for Ruby 2.5/3.0
 
How to distribute Ruby to the world
How to distribute Ruby to the worldHow to distribute Ruby to the world
How to distribute Ruby to the world
 
Ruby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developerRuby on Rails survival guide of an aged Java developer
Ruby on Rails survival guide of an aged Java developer
 
Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1Ruby on Rails Training - Module 1
Ruby on Rails Training - Module 1
 
Apache Camel: The Swiss Army Knife of Open Source Integration
Apache Camel: The Swiss Army Knife of Open Source IntegrationApache Camel: The Swiss Army Knife of Open Source Integration
Apache Camel: The Swiss Army Knife of Open Source Integration
 
Spring into rails
Spring into railsSpring into rails
Spring into rails
 

Similar to DataMapper on Infinispan

Charla ruby nscodermad
Charla ruby nscodermadCharla ruby nscodermad
Charla ruby nscodermadnscoder_mad
 
The Enterprise Strikes Back
The Enterprise Strikes BackThe Enterprise Strikes Back
The Enterprise Strikes BackBurke Libbey
 
Node.js, toy or power tool?
Node.js, toy or power tool?Node.js, toy or power tool?
Node.js, toy or power tool?Ovidiu Dimulescu
 
Writing Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason LeeWriting Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason Leejaxconf
 
Rails Performance Tuning
Rails Performance TuningRails Performance Tuning
Rails Performance TuningBurke Libbey
 
CloudFoundry and MongoDb, a marriage made in heaven
CloudFoundry and MongoDb, a marriage made in heavenCloudFoundry and MongoDb, a marriage made in heaven
CloudFoundry and MongoDb, a marriage made in heavenPatrick Chanezon
 
Rails ORM De-mystifying Active Record has_many
Rails ORM De-mystifying Active Record has_manyRails ORM De-mystifying Active Record has_many
Rails ORM De-mystifying Active Record has_manyBlazing Cloud
 
Enterprise javascriptsession3
Enterprise javascriptsession3Enterprise javascriptsession3
Enterprise javascriptsession3Troy Miles
 
Практики применения JRuby
Практики применения JRubyПрактики применения JRuby
Практики применения JRuby.toster
 
NoSQL CGN: CouchDB (11/2011)
NoSQL CGN: CouchDB (11/2011)NoSQL CGN: CouchDB (11/2011)
NoSQL CGN: CouchDB (11/2011)Sebastian Cohnen
 
Introduction to Java 7 (Devoxx Nov/2011)
Introduction to Java 7 (Devoxx Nov/2011)Introduction to Java 7 (Devoxx Nov/2011)
Introduction to Java 7 (Devoxx Nov/2011)Martijn Verburg
 
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Nilesh Panchal
 
Extending Spring for Custom Usage
Extending Spring for Custom UsageExtending Spring for Custom Usage
Extending Spring for Custom UsageJoshua Long
 
Server Side Javascript
Server Side JavascriptServer Side Javascript
Server Side Javascriptrajivmordani
 
Introducing Hibernate OGM: porting JPA applications to NoSQL, Sanne Grinovero...
Introducing Hibernate OGM: porting JPA applications to NoSQL, Sanne Grinovero...Introducing Hibernate OGM: porting JPA applications to NoSQL, Sanne Grinovero...
Introducing Hibernate OGM: porting JPA applications to NoSQL, Sanne Grinovero...OpenBlend society
 

Similar to DataMapper on Infinispan (20)

Charla ruby nscodermad
Charla ruby nscodermadCharla ruby nscodermad
Charla ruby nscodermad
 
Pocket Knife JS
Pocket Knife JSPocket Knife JS
Pocket Knife JS
 
The Enterprise Strikes Back
The Enterprise Strikes BackThe Enterprise Strikes Back
The Enterprise Strikes Back
 
Node.js, toy or power tool?
Node.js, toy or power tool?Node.js, toy or power tool?
Node.js, toy or power tool?
 
JRuby and You
JRuby and YouJRuby and You
JRuby and You
 
JRubyConf 2009
JRubyConf 2009JRubyConf 2009
JRubyConf 2009
 
Writing Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason LeeWriting Plugged-in Java EE Apps: Jason Lee
Writing Plugged-in Java EE Apps: Jason Lee
 
Rails Performance Tuning
Rails Performance TuningRails Performance Tuning
Rails Performance Tuning
 
eZ Publish nextgen
eZ Publish nextgeneZ Publish nextgen
eZ Publish nextgen
 
CloudFoundry and MongoDb, a marriage made in heaven
CloudFoundry and MongoDb, a marriage made in heavenCloudFoundry and MongoDb, a marriage made in heaven
CloudFoundry and MongoDb, a marriage made in heaven
 
RubyConf 2009
RubyConf 2009RubyConf 2009
RubyConf 2009
 
Rails ORM De-mystifying Active Record has_many
Rails ORM De-mystifying Active Record has_manyRails ORM De-mystifying Active Record has_many
Rails ORM De-mystifying Active Record has_many
 
Enterprise javascriptsession3
Enterprise javascriptsession3Enterprise javascriptsession3
Enterprise javascriptsession3
 
Практики применения JRuby
Практики применения JRubyПрактики применения JRuby
Практики применения JRuby
 
NoSQL CGN: CouchDB (11/2011)
NoSQL CGN: CouchDB (11/2011)NoSQL CGN: CouchDB (11/2011)
NoSQL CGN: CouchDB (11/2011)
 
Introduction to Java 7 (Devoxx Nov/2011)
Introduction to Java 7 (Devoxx Nov/2011)Introduction to Java 7 (Devoxx Nov/2011)
Introduction to Java 7 (Devoxx Nov/2011)
 
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
 
Extending Spring for Custom Usage
Extending Spring for Custom UsageExtending Spring for Custom Usage
Extending Spring for Custom Usage
 
Server Side Javascript
Server Side JavascriptServer Side Javascript
Server Side Javascript
 
Introducing Hibernate OGM: porting JPA applications to NoSQL, Sanne Grinovero...
Introducing Hibernate OGM: porting JPA applications to NoSQL, Sanne Grinovero...Introducing Hibernate OGM: porting JPA applications to NoSQL, Sanne Grinovero...
Introducing Hibernate OGM: porting JPA applications to NoSQL, Sanne Grinovero...
 

Recently uploaded

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 

Recently uploaded (20)

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 

DataMapper on Infinispan

  • 1. DataMapper on Infinispan Clustered NoSQL Lance Ball Thursday, September 22, 11 1
  • 2. Lance Ball •Red Hat senior engineer •TorqueBox core developer •Perl -> C++ -> Java -> Ruby •@lanceball Thursday, September 22, 11 2
  • 4. What are we talking about? • DataMapper - Ruby ORM • Infinispan - Java+Scala distributed cache • Hibernate Search - Java ORM • Lucene - Indexing and search • JBoss AS7 - JEE application server • TorqueBox - JRuby application server Thursday, September 22, 11 4
  • 5. TorqueBox JRuby Application Server http://torquebox.org Thursday, September 22, 11 5
  • 6. TorqueBox The Power of JBoss with the Expressiveness of Ruby Thursday, September 22, 11 6
  • 8. TorqueBox •Ruby, baby! •Rack apps •Scheduled Jobs •Background Tasks •Message Queues & Topics •Message Processors •Long-running Services •Distributed / Replicated Cache Thursday, September 22, 11 8
  • 9. JRuby •Healthy community •Real threads •Java libraries •Java tools •Fast runtime •Better memory management** ** for long running things like servers Thursday, September 22, 11 9
  • 10. Java CacheFactory.java public class CacheFactory {   public CacheFactory() {     config = new Configuration();     store = new FileCacheStoreConfig();     store.purgeOnStartup( false );     config.fluent().loaders().addCacheLoader( store );     manager = new DefaultCacheManager( config.build() );   }   public Cache getCache() { return manager.getCache(); } } Thursday, September 22, 11 10
  • 11. JRuby cache_factory.rb class CacheFactory   def initialize     @config = Configuration.new     @store = FileCacheStore.new     @store.purge_on_startup false     @config.fluent.loaders.add_cache_loader( @store )     @manager = DefaultCacheManager.new( @config.build )   end   def get_cache ; @manager.get_cache end end Thursday, September 22, 11 11
  • 12. Infinispan An extremely scalable, highly available data grid http://www.jboss.org/infinispan Thursday, September 22, 11 12
  • 13. Infinispan •Key / Value store •Highly concurrent core •Data Grid •Replicated •Distributed •Local Thursday, September 22, 11 13
  • 14. Hotrod •Binary TCP protocol •Clients •Java •Python •Ruby •... Thursday, September 22, 11 14
  • 15. NoSQL? •Non-relational •Scales out, not up •Big data •Low ceremony Thursday, September 22, 11 15
  • 16. Infinispan API Cache.java    cache.put(key, value, lifespan, timeUnit);    cache.putIfAbsent(key, value, lifespan, timeUnit);    cache.replace(key, oldVal, value, lifespan, timeUnit);    cache.putAsync(key, value, lifespan, timeUnit);    cache.keySet();    cache.values();    cache.entrySet(); Thursday, September 22, 11 16
  • 17. Hibernate Search Example.java import org.hibernate.search.annotations.*; @Indexed @ProvidedId public class Book { @Field String title; @Field String description; @Field Date publicationYear; } Thursday, September 22, 11 17
  • 18. Indexing: Lucene Search.java org.apache.lucene.search.Query luceneQuery = queryBuilder.phrase() .onField( "description" ) .andField( "title" ) .sentence( "pat the bunny" ) .createQuery(); CacheQuery query = searchManager.getQuery( luceneQuery, Book.class ); Thursday, September 22, 11 18
  • 19. DataMapper •Object Relational Mapper •Alternative to ActiveRecord •Written in Ruby •http://datamapper.org Thursday, September 22, 11 19
  • 20. Resources beer.rb class Beer   include DataMapper::Resource   property :id, Serial   property :name, String   property :rating, Integer   property :notes, Text   belongs_to :user end Thursday, September 22, 11 20
  • 21. DataMapper Queries sample.rb Beer.all Beer.get(1) Beer.first( :name => 'Pisgah Pale' ) Beer.last( :name.like => 'IPA' ) Beer.all( :notes.like => 'hoppy' ) Thursday, September 22, 11 21
  • 22. DataMapper Adapter SPI sample_adapter.rb module DataMapper::Adapters   class SampleAdapter < AbstractAdapter     def initialize( name, options ) ; end     def create( resources ) ; end     def read( query ) ; end     def update( attributes, collection ) ; end     def delete( collection ) ; end   end end Thursday, September 22, 11 22
  • 23. DataMapper Filtering some_adapter.rb     def read( query ) records = @search_manager.search( query )       query.filter_records( records )     end Thursday, September 22, 11 23
  • 24. Testing adapter_spec.rb require 'dm-core/spec/shared/adapter_spec' describe DataMapper::Adapters::InfinispanAdapter do   before :all do     @adapter = DataMapper.setup(:default, :adapter => 'infinispan')   end   it_should_behave_like 'An Adapter'   describe "other important things to test" do # Your tests here   end end Thursday, September 22, 11 24
  • 25. torquebox-cache • TorqueBox 2.0 gem • dm-infinispan-adapter • TorqueBox::Infinispan::Cache • ActiveSupport::Cache::TorqueBoxStore Thursday, September 22, 11 25
  • 26. dm-infinispan-adapter Use Infinispan as your object data store Thursday, September 22, 11 26
  • 27. dm-infinispan-adapter require 'dm-core' require 'dm-infinispan-adapter' class Beer   include DataMapper::Resource   property :id, Serial   property :name, String   property :rating, Integer   property :notes, Text   belongs_to :user end DataMapper.setup(:default, :adapter=>'infinispan', :persist=>true) Thursday, September 22, 11 27
  • 29. Hibernate Search Annotated Java classes Thursday, September 22, 11 29
  • 30. Runtime Class Creation How do we make Ruby’s Beer.class look like an annotated Java class at runtime? Thursday, September 22, 11 30
  • 31. Metaprogramming! dm-infinispan-adapter.rb require 'datamapper/model' module DataMapper::Adapters   class InfinispanAdapter < AbstractAdapter     DataMapper::Model.append_inclusions( Infinispan::Model )   end end Thursday, September 22, 11 31
  • 32. Metaprogramming! datamapper/model.rb module Infinispan   module Model     def self.included(model)       model.extend(ClassMethods) model.before_class_method(:finalize, :configure_index)     end end end Thursday, September 22, 11 32
  • 33. Annotations datamapper/model.rb require ‘jruby/core_ext’ annotation = {org.hibernate.search.annotations.Field => {}} add_method_annotation( “getName”, annotation ) Thursday, September 22, 11 33
  • 34. Annotations datamapper/model.rb require ‘jruby/core_ext’ annotation = {   org.hibernate.search.annotations.Indexed => {},   org.hibernate.search.annotations.ProvidedId => {},   org.infinispan.marshall.SerializeWith => {"value" => org.torquebox.cache.marshalling.JsonExternalizer.java_class }} add_class_annotation( annotation ) Thursday, September 22, 11 34
  • 35. Become Java! java_class = become_java! Thursday, September 22, 11 35
  • 36. JSON Externalizer Forget java.io.Serializable Thursday, September 22, 11 36
  • 37. JSON Externalizer JsonExternalizer.java public class JsonExternalizer implements Externalizer<IRubyObject> { " @Override " public void writeObject(ObjectOutput output, IRubyObject object) " " " throws IOException { " " String theType = object.getType().getName(); " " output.writeObject( theType ); " " output.writeObject( toJSON(object) ); " }  } Thursday, September 22, 11 37
  • 38. JSON Externalizer JsonExternalizer.java public class JsonExternalizer implements Externalizer<IRubyObject> { " @Override " public IRubyObject readObject(ObjectInput input) throws IOException, ClassNotFoundException { " " String theType = (String) input.readObject(); " " String theJson = (String) input.readObject(); " " return fromJSON(theJson, theType);" " }  } Thursday, September 22, 11 38
  • 39. JSON Externalizer JsonExternalizer.java public class JsonExternalizer implements Externalizer<IRubyObject> {     protected IRubyObject fromJSON(String json, String type) throws ClassNotFoundException {         RubyModule objectClass = runtime.getClassFromPath( type );         return (IRubyObject) JavaEmbedUtils.invokeMethod( runtime, objectClass, "new", new Object[] { jsonHash }, IRubyObject.class);     }  } Thursday, September 22, 11 39
  • 40. JSON Externalizer JsonExternalizer.java public class JsonExternalizer implements Externalizer<IRubyObject> {     protected String toJSON(IRubyObject object) {         return (String) JavaEmbedUtils.invokeMethod( getCurrentRuntime(), object, "to_json", EMPTY_OBJECT_ARRAY, String.class );     }  } Thursday, September 22, 11 40
  • 41. Sequences dm-core/property/serial.rb DataMapper::Property::Serial Thursday, September 22, 11 41
  • 42. Sequences dm-core/adapters/abstract_adapter.rb initialize_serial( resource, next_id ) Thursday, September 22, 11 42
  • 43. Sequences cache.rb module TorqueBox   module Infinispan     class Cache       def increment( sequence_name, amount = 1 ) # increment an integer       end       def decrement(name, amount = 1) # decrement an integer       end     end   end end Thursday, September 22, 11 43
  • 44. Sequences dm-infinispan-adapter.rb @metadata = Cache.new( options ) initialize_serial( resource, @metadata.increment( “metadata/beers/index” ) ) Thursday, September 22, 11 44
  • 45. Transactions cache_spec.rb   describe "with JTA transactions" do     it "should behave like a transaction" do       @cache.transaction do |cache|         cache.put('Tommy', 'Dorsey')         raise "yikes!"         cache.put('Elvis', 'Presley')       end       @cache.get('Tommy').should be_nil       @cache.get('Elvis').should be_nil     end    end Thursday, September 22, 11 45
  • 46. Transactions dm-infinispan-adapter.rb     def delete( collection )       cache.transaction do         collection.each do |resource|           cache.remove( key(resource) )         end       end     end Thursday, September 22, 11 46
  • 47. TorqueBox::Infinispan::Cache Use Infinispan for... Thursday, September 22, 11 47
  • 48. Cache some_file.rb include TorqueBox::Infinispan::Cache cache = Cache.new(:name => 'MyCache', :mode => :replicated) cache.put(key, value) cache.get(key) Thursday, September 22, 11 48
  • 49. ActiveSupport::Cache::TorqueBoxStore Caching in Rails. Replaces in-memory or memcached caches. Thursday, September 22, 11 49
  • 50. TorqueBoxStore config/application.rb module YourApp   class Application < Rails::Application     config.cache_store = :torque_box_store end end Thursday, September 22, 11 50
  • 51. TorqueBoxStore my_app.rb require 'sinatra' require 'torquebox' class MyApp < Sinatra::Base   use TorqueBox::Session::ServletStore   get '/' do     session[:message] = 'Hello World!'     haml :index   end end Thursday, September 22, 11 51
  • 52. Beer Catalogue! http://www.flickr.com/photos/burnblue/308441464/ Thursday, September 22, 11 52
  • 53. Model beer.rb require 'dm-core' require 'dm-infinispan-adapter' class Beer   include DataMapper::Resource   property :id, Serial   property :name, String   property :rating, Integer   property :notes, Text   belongs_to :user end DataMapper.setup(:default, :adapter=>'infinispan', :persist=>true) Thursday, September 22, 11 53
  • 54. Sinatra application.rb module BeerCatalogue   class Application < Sinatra::Base     get '/' do       @beers = Beer.all( :user_id => current_user.id )       haml :index     end     post '/beer' do       Beer.create( :name=>params[:name], :notes=>params[:notes], :rating=>params[:rating], :user=>current_user)       redirect '/'     end   end end Thursday, September 22, 11 54
  • 55. View views/index.haml #welcome   Hello   =current_user.name #body   #beer-list     %h2 Your Beers     - if @beers.empty?       %strong You haven't rated any beers yet. Do that now!     %ul       - @beers.each do |beer|         %li           =beer.name           =beer.rating =beer.notes Thursday, September 22, 11 55
  • 56. Source http://github.com/torquebox/torquebox http://github.com/torquebox/presentations Thursday, September 22, 11 56
  • 57. Installation $ gem install torquebox-server --pre --source http://torquebox.org/2x/builds/LATEST/gem-repo/ $ gem install bundler $ bundle install $ torquebox deploy . Deployed: beer.yml into: /path/to/jboss/standalone/deployments $ torquebox run Thursday, September 22, 11 57
  • 59. TorqueBox 2.x • Under development • Continuous integration • TorqueBox::Infinispan::Cache • ActiveSupport::Cache::TorqueBoxStore • dm-infinispan-adapter Thursday, September 22, 11 59
  • 60. TorqueBox 1.x • Version 1.1.1 released in August • Continuous integration • ActiveSupport::Cache::TorqueBoxStore Thursday, September 22, 11 60
  • 61. Resources • http://torquebox.org/ • http://github.com/torquebox • #torquebox on FreeNode • @torquebox Thursday, September 22, 11 61
  • 62. Questions http://www.flickr.com/photos/eleaf/2536358399/ Thursday, September 22, 11 62