Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

This branch is 624 commits behind torquebox:2x-dev

Fetching latest commit…

Cannot retrieve the latest commit at this time

..
Failed to load latest commit information.
lib
spec
README.md
pom.xml

README.md

Extending the configuration DSL

To add something to the DSL, you just need to modify lib/configuration/global.rb in two places. As an example, we'll add two new keywords to our dsl: stomp & stomplet:

  • stomp is used to set overall options for the stomp functionality, such as host and port. We want to be able to call it multiple times, with the settings being merged into one hash, no matter how many times it is called

  • stomplet is used to define a stomplet that will be instantiated. Each call should create a discrete config for that stomplet.

Adding the keywords

The ENTRY_MAP in GlobalConfiguration (global.rb) defines all of the keywords for the dsl. It is a hash of keyword-as-a-symbol to the Entry class that implements the keyword. lib/configuration.rb defines the following Entry classes:

  • ThingEntry: foo :bar
  • OptionsEntry: foo :bar => :baz
  • ThingWithOptionsEntry: foo :bar, :ham => :biscuit

The Entry classes can be customized with the with_settings() class method to add validation and more.

First, let's add the stomp keyword. Let's assume it is just a simple hash of options, and those options can only be :host and :port. We want to be able to specify it like so:

stomp :host => 'ham.biscu.it'

and:

stomp {
  port 59009
}

To support this, we add the following to the ENTRY_MAP:

:stomp => OptionsEntry.with_settings( :validate => { :optional => [:host, :port] } )

Now let's add stomplet. Let's assume you must always specify the class that implements the stomplet, along with the route. You can optionally specify a name and a boolean fungible option for the stomplet as well. We also want each stomplet call to create a discrete stomplet. We want to be able to specify it as:

stomplet MyStomplet, :route => '/a/b/:c', :fungible => true

and

stomplet MyStomplet do 
  route '/a/b/:c'
  name 'foobar'
  fungible false
end

To support this, we add the following to the ENTRY_MAP:

:stomplet => ThingWithOptionsEntry.with_settings( :discrete => true,
                                                  :validate => {
                                                    :required => [ :route ],
                                                    :optional => [ :name, { :fungible => [ true, false ] } ] } )

The :discrete setting signals this keyword to accumulate entries in an array instead of merging into a hash based of off the 'thing' ('MyStomplet' in this case). This allows for multiple stomplets using the same class.

Converting to the expected yaml format

The DSL has its own simple hash and array based representation of the configuration. Since the output of the DSL gets fed into the front of the *YamlParsingProcessor chain, we have to convert the configuration into the same format that the yaml parser spits out. That's all controlled by the to_metadata_hash method in global.rb.

Assuming the stomp and stomplet yaml configuration looks like:

stomp:
  host: ham.biscu.it
  stomplets:
    ham.stomplet:
      class: MyStomplet
      route: '/a/b/:c'
      fungible: true

This will result in a hash format like:

{ 'stomp' => 
  { 'host' => 'ham.biscu.it',
    'stomplets' => {
      'ham.stomplet' => {
        'class' => 'MyStomplet',
        'route' => '/a/b/:c',
        'fungible' => true } } } }

Since that is the format the StompYamlParsingProcessor will expect, we'll need to convert from the DSL's internal format to the above. Our DSL examples above will result in the following internal representation:

{ 'stomp' => { 'host' => 'ham.biscu.it' },
  'stomplet' => [ 'MyStomplet', { 'route' => '/a/b/:c', 'name' => 'foobar', 'fungible' => false } ] }

To add our conversion, simply add when blocks to the case statement in to_metadata_hash:

# for stomplet
when 'stomplet' 
  entry_data.each do |klass, data|
    name = data.delete( :name ) || unique_name( klass.to_s, metadata['stomp']['stomplets'].keys )
    stomplet = metadata['stomp']['stomplets'][name] = {}
    stomplet['class'] = klass.to_s
    stomplet.merge!( data )
   end

# for stomp, we just fall through to the default case

Testing

You should add tests to global_spec.rb and the torquebox_rb_spec.rb integ. I leave those as an exercise for the reader.

Something went wrong with that request. Please try again.