adaptation 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1 -0
- data/README +90 -0
- data/bin/about +5 -0
- data/bin/adaptation +19 -0
- data/bin/destroy +5 -0
- data/bin/generate +5 -0
- data/bin/mom +8 -0
- data/bin/subscribe +8 -0
- data/configs/boot.rb +10 -0
- data/configs/databases/mysql.yml +48 -0
- data/configs/empty.log +0 -0
- data/configs/mom.yml +8 -0
- data/dispatches/dispatch.rb +8 -0
- data/dispatches/publish.rb +11 -0
- data/doc/README_FOR_APP +2 -0
- data/fresh_rakefile +10 -0
- data/helpers/publish.rb +24 -0
- data/helpers/test_helper.rb +6 -0
- data/lib/adaptation/adaptor.rb +32 -0
- data/lib/adaptation/base.rb +70 -0
- data/lib/adaptation/message.rb +328 -0
- data/lib/adaptation/mom.rb +70 -0
- data/lib/adaptation/oapdaemon.rb +38 -0
- data/lib/adaptation/test/test_help.rb +282 -0
- data/lib/adaptation/version.rb +9 -0
- data/lib/adaptation.rb +5 -0
- data/lib/commands/about.rb +3 -0
- data/lib/commands/destroy.rb +6 -0
- data/lib/commands/generate.rb +6 -0
- data/lib/commands/mom.rb +8 -0
- data/lib/commands/subscribe.rb +11 -0
- data/lib/commands.rb +17 -0
- data/lib/rails_generator/base.rb +262 -0
- data/lib/rails_generator/commands.rb +582 -0
- data/lib/rails_generator/generated_attribute.rb +42 -0
- data/lib/rails_generator/generators/applications/app/USAGE +13 -0
- data/lib/rails_generator/generators/applications/app/app_generator.rb +133 -0
- data/lib/rails_generator/generators/components/adaptor/USAGE +25 -0
- data/lib/rails_generator/generators/components/adaptor/adaptor_generator.rb +21 -0
- data/lib/rails_generator/generators/components/adaptor/templates/adaptor.rb +6 -0
- data/lib/rails_generator/generators/components/adaptor/templates/functional_test.rb +16 -0
- data/lib/rails_generator/generators/components/message/USAGE +16 -0
- data/lib/rails_generator/generators/components/message/message_generator.rb +28 -0
- data/lib/rails_generator/generators/components/message/templates/fixtures.xml +3 -0
- data/lib/rails_generator/generators/components/message/templates/message.rb +2 -0
- data/lib/rails_generator/generators/components/message/templates/unit_test.rb +25 -0
- data/lib/rails_generator/generators/components/model/USAGE +26 -0
- data/lib/rails_generator/generators/components/model/model_generator.rb +38 -0
- data/lib/rails_generator/generators/components/model/templates/fixtures.yml +11 -0
- data/lib/rails_generator/generators/components/model/templates/migration.rb +13 -0
- data/lib/rails_generator/generators/components/model/templates/model.rb +2 -0
- data/lib/rails_generator/generators/components/model/templates/unit_test.rb +10 -0
- data/lib/rails_generator/lookup.rb +209 -0
- data/lib/rails_generator/manifest.rb +53 -0
- data/lib/rails_generator/options.rb +143 -0
- data/lib/rails_generator/scripts/destroy.rb +7 -0
- data/lib/rails_generator/scripts/generate.rb +7 -0
- data/lib/rails_generator/scripts/update.rb +12 -0
- data/lib/rails_generator/scripts.rb +85 -0
- data/lib/rails_generator/simple_logger.rb +46 -0
- data/lib/rails_generator/spec.rb +44 -0
- data/lib/rails_generator.rb +43 -0
- data/lib/ruby_version_check.rb +17 -0
- metadata +142 -0
data/CHANGELOG
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* 0.0.1 (18 June 2007)
|
data/README
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
== Welcome to Adaptation
|
2
|
+
|
3
|
+
Adaptation is a framework that tries to facilitate data interchange
|
4
|
+
between applications. Applications send and receive xml messages through
|
5
|
+
a message oriented middleware using a publish/subscribe pattern:
|
6
|
+
|
7
|
+
Application A publishes messages on topic A, and all applications interested
|
8
|
+
on reading messages from A subscribe to its topic.
|
9
|
+
|
10
|
+
Adaptation focuses on facilitate building _adaptors_. _adaptors_ are programs
|
11
|
+
that are executed for an application subscribed to a topic, when a message is
|
12
|
+
received on that topic.
|
13
|
+
|
14
|
+
_adaptors_ are built in a similar way that web apps are built using
|
15
|
+
the Ruby on Rails framework. This way adaptation uses a nice pattern
|
16
|
+
of separation between data input/output and logic. When building an
|
17
|
+
_adaptor_, logic will be stored under __Adaptors__ (in Rails these would
|
18
|
+
be Controllers) , and xml data interaction with the middleware will be
|
19
|
+
performed by a __Message__. __adaptors__ also can use ActiveRecord based
|
20
|
+
models for data interaction with applications database, like Rails does, if
|
21
|
+
adapting a database-backed application.
|
22
|
+
|
23
|
+
|
24
|
+
== Getting started
|
25
|
+
|
26
|
+
1. At the command prompt, start a new adaptation adaptor using the adaptation command
|
27
|
+
and your adaptor name. Ex: adaptation myadaptor
|
28
|
+
This will generate a an adaptor file tree.
|
29
|
+
2. If no message oriented middleware has been alreay set, change directory into myadaptor
|
30
|
+
and start the mom (message oriented middleware):
|
31
|
+
<tt>script/mom</tt>
|
32
|
+
This will start a mom in localhost (default), listening on port 8080 (default).
|
33
|
+
3. Subscribe your adaptor to the mom, so it will be executed when a message is received on
|
34
|
+
a topic your adaaptor is interested in:
|
35
|
+
<tt>script/subscribe</tt>
|
36
|
+
By default this will try to subscribe to a mom listening on localhost:8080, using port
|
37
|
+
8081 to subscribe. These values can be changed editing <tt>config/mom.yml</tt>. In mom.yml
|
38
|
+
you can also specify wich topics your adaptor is interested in.
|
39
|
+
4. Start developing your adaptor, probably generating __Adaptors__, __Messages__ and __Models__.
|
40
|
+
|
41
|
+
|
42
|
+
== Moms
|
43
|
+
|
44
|
+
By default, Adaptation will try to use druby to execute the built-in Ruby mom. This
|
45
|
+
mom is suitable for development, but not for production. For a production environment
|
46
|
+
a more stable solution like Xmlblaster should be chosen.
|
47
|
+
|
48
|
+
|
49
|
+
== Description of contents
|
50
|
+
|
51
|
+
app
|
52
|
+
Holds all the code that's specific to this particular adaptor.
|
53
|
+
|
54
|
+
app/adaptors
|
55
|
+
Holds adaptors that should be named like messagename_adaptor.rb for
|
56
|
+
automated mapping. All adaptors should descend from Adaptation::Adaptor.
|
57
|
+
|
58
|
+
app/messages
|
59
|
+
Holds messages that should be named like messagename.rb.
|
60
|
+
Messages descend from Adaptation::Message.
|
61
|
+
|
62
|
+
app/models
|
63
|
+
Holds models that should be named like post.rb.
|
64
|
+
Most models will descend from ActiveRecord::Base.
|
65
|
+
|
66
|
+
config
|
67
|
+
Configuration files for the Adaptation environment, the mom, the adapted application,
|
68
|
+
the database, and other dependencies.
|
69
|
+
|
70
|
+
db
|
71
|
+
Contains database related scripts.
|
72
|
+
|
73
|
+
doc
|
74
|
+
This directory is where your adaptor documentation will be stored.
|
75
|
+
|
76
|
+
lib
|
77
|
+
Application specific libraries. Basically, any kind of custom code that doesn't
|
78
|
+
belong under adaptors, models, or messages.
|
79
|
+
|
80
|
+
public
|
81
|
+
The directory available for the calling the adaptor and for utilities the adaptaed
|
82
|
+
application must be aware of, like a tool for publishing messages to the mom.
|
83
|
+
|
84
|
+
script
|
85
|
+
Helper scripts for automation and generation.
|
86
|
+
|
87
|
+
test
|
88
|
+
Unit and functional tests along with fixtures. When using the script/generate scripts, template
|
89
|
+
test files will be generated for you and placed in this directory.
|
90
|
+
|
data/bin/about
ADDED
data/bin/adaptation
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/ruby_version_check'
|
2
|
+
Signal.trap("INT") { puts; exit }
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + '/../lib/adaptation/version'
|
5
|
+
if %w(--version -v).include? ARGV.first
|
6
|
+
puts "Adaptation #{Adaptation::VERSION::STRING}"
|
7
|
+
exit(0)
|
8
|
+
end
|
9
|
+
|
10
|
+
# freeze = ARGV.any? { |option| %w(--freeze -f).include?(option) }
|
11
|
+
app_path = ARGV.first
|
12
|
+
|
13
|
+
require File.dirname(__FILE__) + '/../lib/rails_generator'
|
14
|
+
|
15
|
+
require 'rails_generator/scripts/generate'
|
16
|
+
Rails::Generator::Base.use_application_sources!
|
17
|
+
Rails::Generator::Scripts::Generate.new.run(ARGV, :generator => 'app')
|
18
|
+
|
19
|
+
# Dir.chdir(app_path) { `rake rails:freeze:gems`; puts "froze" } if freeze
|
data/bin/destroy
ADDED
data/bin/generate
ADDED
data/bin/mom
ADDED
data/bin/subscribe
ADDED
data/configs/boot.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Don't change this file. Configuration is done in config/environment.rb and config/environments/*.rb
|
2
|
+
|
3
|
+
unless defined?(RAILS_ROOT)
|
4
|
+
root_path = File.join(File.dirname(__FILE__), '..')
|
5
|
+
unless RUBY_PLATFORM =~ /mswin32/
|
6
|
+
require 'pathname'
|
7
|
+
root_path = Pathname.new(root_path).cleanpath(true).to_s
|
8
|
+
end
|
9
|
+
RAILS_ROOT = root_path
|
10
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# MySQL (default setup). Versions 4.1 and 5.0 are recommended.
|
2
|
+
#
|
3
|
+
# Install the MySQL driver:
|
4
|
+
# gem install mysql
|
5
|
+
# On MacOS X:
|
6
|
+
# gem install mysql -- --include=/usr/local/lib
|
7
|
+
# On Windows:
|
8
|
+
# gem install mysql
|
9
|
+
# Choose the win32 build.
|
10
|
+
# Install MySQL and put its /bin directory on your path.
|
11
|
+
#
|
12
|
+
# And be sure to use new-style password hashing:
|
13
|
+
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
|
14
|
+
development:
|
15
|
+
adapter: mysql
|
16
|
+
database: <%= app_name %>_development
|
17
|
+
username: root
|
18
|
+
password:
|
19
|
+
<% if socket -%>
|
20
|
+
socket: <%= socket %>
|
21
|
+
<% else -%>
|
22
|
+
host: localhost
|
23
|
+
<% end -%>
|
24
|
+
|
25
|
+
# Warning: The database defined as 'test' will be erased and
|
26
|
+
# re-generated from your development database when you run 'rake'.
|
27
|
+
# Do not set this db to the same as development or production.
|
28
|
+
test:
|
29
|
+
adapter: mysql
|
30
|
+
database: <%= app_name %>_test
|
31
|
+
username: root
|
32
|
+
password:
|
33
|
+
<% if socket -%>
|
34
|
+
socket: <%= socket %>
|
35
|
+
<% else -%>
|
36
|
+
host: localhost
|
37
|
+
<% end -%>
|
38
|
+
|
39
|
+
production:
|
40
|
+
adapter: mysql
|
41
|
+
database: <%= app_name %>_production
|
42
|
+
username: root
|
43
|
+
password:
|
44
|
+
<% if socket -%>
|
45
|
+
socket: <%= socket %>
|
46
|
+
<% else -%>
|
47
|
+
host: localhost
|
48
|
+
<% end -%>
|
data/configs/empty.log
ADDED
File without changes
|
data/configs/mom.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
unless defined? ADAPTOR_ROOT
|
2
|
+
ADAPTOR_ROOT = File.expand_path(File.dirname(__FILE__) + '/..')
|
3
|
+
end
|
4
|
+
require 'drb'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
config = YAML::load(File.open("#{ADAPTOR_ROOT}/config/mom.yml"))
|
8
|
+
mom_uri = "druby://#{config["mom"]["host"]}:#{config["mom"]["port"]}"
|
9
|
+
|
10
|
+
mom = DRbObject.new(nil, mom_uri)
|
11
|
+
mom.publish ARGV[1], ARGV[0]
|
data/doc/README_FOR_APP
ADDED
data/fresh_rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
|
+
|
4
|
+
require(File.join(File.dirname(__FILE__), 'config', 'boot'))
|
5
|
+
|
6
|
+
require 'rake'
|
7
|
+
require 'rake/testtask'
|
8
|
+
require 'rake/rdoctask'
|
9
|
+
|
10
|
+
require 'tasks/rails'
|
data/helpers/publish.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
class Adaptation::Adaptor
|
2
|
+
|
3
|
+
def publish *options
|
4
|
+
|
5
|
+
message_object = nil
|
6
|
+
if options.first.is_a?(Adaptation::Message)
|
7
|
+
message_object = options.first
|
8
|
+
elsif options.first.is_a?(String)
|
9
|
+
xml_message = options.first
|
10
|
+
message_type = xml_message[1..(xml_message.index(/(>| )/) - 1)]
|
11
|
+
message_class = get_class_object(message_type.capitalize)
|
12
|
+
message_object = message_class.to_object(xml_message)
|
13
|
+
end
|
14
|
+
|
15
|
+
mom = File.new(File.dirname(__FILE__) + '/mom.txt', "a")
|
16
|
+
mom.write("#{message_object.to_xml.to_s}\n")
|
17
|
+
mom.close
|
18
|
+
|
19
|
+
# configuration = {}
|
20
|
+
# configuration.update(options.pop) if options.last.is_a?(Hash)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Adaptation
|
2
|
+
#= Adaptation::Adaptor -- The message processor
|
3
|
+
#
|
4
|
+
#Adaptation::Adaptor is the base class for those classes containing the logic to be executed when a message is read through the mom.
|
5
|
+
#
|
6
|
+
#Each class extending Adaptation::Adaptor must implement the _process_ function, using it as the main entry point for the logic to be executed when a message arrives. The name of the class extending Adaptation::Message associates the class with the one to be executed when a message arrives. Ie. if a message is received with a root element named _<hello>_, adaptation will search for a class extending Adaptation::Adaptor named _HelloAdaptor_.
|
7
|
+
#
|
8
|
+
#<i>Adaptation::Adaptors</i> (classes extending Adaptation::Adaptor) must be stored under <i>app/adaptors_name</i> in the adaptation file tree. This is done automatically when an adaptor is generated using adaptation built-in generator:
|
9
|
+
# script/generate adaptor hello
|
10
|
+
#
|
11
|
+
class Adaptor
|
12
|
+
|
13
|
+
def publish *options
|
14
|
+
message_object = nil
|
15
|
+
if options.first.is_a?(Message)
|
16
|
+
message_object = options.first
|
17
|
+
elsif options.first.is_a?(String)
|
18
|
+
xml_message = options.first
|
19
|
+
message_type = xml_message[1..(xml_message.index(/(>| )/) - 1)]
|
20
|
+
message_class = get_class_object(message_type.capitalize)
|
21
|
+
message_object = message_class.to_object(xml_message)
|
22
|
+
end
|
23
|
+
|
24
|
+
xml = message_object.to_xml
|
25
|
+
unless system("oappublish '#{$config["application"]}' '#{xml}'")
|
26
|
+
puts "Problem publishing: #{xml}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Adaptation
|
2
|
+
|
3
|
+
class Base
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
$environment = "development"
|
7
|
+
$config = YAML::load(File.open("config/settings.yml"))[$environment]
|
8
|
+
|
9
|
+
# require all adaptors
|
10
|
+
Dir["#{ADAPTOR_ROOT}/app/adaptors/*.rb"].each do |f|
|
11
|
+
require f
|
12
|
+
end
|
13
|
+
|
14
|
+
# require all messages
|
15
|
+
Dir["#{ADAPTOR_ROOT}/app/messages/*.rb"].reject{|f| f =~ /\/_/}.each do |f|
|
16
|
+
require f
|
17
|
+
end
|
18
|
+
|
19
|
+
# require all models
|
20
|
+
Dir["#{ADAPTOR_ROOT}/app/models/*.rb"].each do |f|
|
21
|
+
require f
|
22
|
+
end
|
23
|
+
|
24
|
+
# connect with database -> this could also be avoided?
|
25
|
+
if File.exists?("config/database.yml")
|
26
|
+
development_configurations = YAML::load(File.open("config/database.yml"))[$environment]
|
27
|
+
ActiveRecord::Base.configurations.update("development" => development_configurations)
|
28
|
+
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[$environment])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def process(xml_message)
|
33
|
+
# dirty method to discover the message type
|
34
|
+
message_type = xml_message[1..(xml_message.index(/(>| )/) - 1)]
|
35
|
+
|
36
|
+
begin
|
37
|
+
message_class = get_class_object(message_type.capitalize)
|
38
|
+
message = message_class.to_object(xml_message)
|
39
|
+
|
40
|
+
adaptor_class = get_class_object("#{message_type.capitalize}Adaptor")
|
41
|
+
adaptor = adaptor_class.new
|
42
|
+
rescue Exception => e
|
43
|
+
# message no implemented in this adaptor
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
unless message.check
|
48
|
+
puts "WARNING:Message doesn't validate!"
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
52
|
+
adaptor.process message
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_class_object(searched_class)
|
56
|
+
class_object = nil
|
57
|
+
ObjectSpace.each_object(Class){|aClass|
|
58
|
+
class_object = aClass if aClass.to_s == searched_class
|
59
|
+
}
|
60
|
+
if class_object.nil?
|
61
|
+
#puts "Unknown class #{searched_class}."
|
62
|
+
raise Exception.new("Unknown class #{searched_class}.")
|
63
|
+
else
|
64
|
+
return class_object
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|