From shinohara.shunichi at future.co.jp Thu May 10 00:17:53 2007 From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp) Date: Thu, 10 May 2007 13:17:53 +0900 Subject: [ap4r-devel] test Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDA0@045MAIL.future.co.jp> test again --------------------------------- SHINOHARA, Shun'ichi Future Architect, Inc. 1-2-2 Osaki Shinagawa-Ku Tokyo, JAPAN (ZIP 141-0032) 070-6991-0765 (cell phone) shinohara.shunichi at future.co.jp From shino at rubyforge.org Thu May 10 00:42:10 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 10 May 2007 00:42:10 -0400 (EDT) Subject: [ap4r-devel] [163] trunk/ap4r/ap4r-devel-test.txt: test ap4r-devel mailing list 3 Message-ID: <20070510044210.8DF4F5240C40@rubyforge.org> Revision: 163 Author: shino Date: 2007-05-10 00:42:10 -0400 (Thu, 10 May 2007) Log Message: ----------- test ap4r-devel mailing list 3 Modified Paths: -------------- trunk/ap4r/ap4r-devel-test.txt Modified: trunk/ap4r/ap4r-devel-test.txt =================================================================== --- trunk/ap4r/ap4r-devel-test.txt 2007-05-10 04:38:29 UTC (rev 162) +++ trunk/ap4r/ap4r-devel-test.txt 2007-05-10 04:42:10 UTC (rev 163) @@ -1,2 +1,3 @@ test test2 +test3 From kato-k at rubyforge.org Thu May 10 01:11:36 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Thu, 10 May 2007 01:11:36 -0400 (EDT) Subject: [ap4r-devel] [164] trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb: Experimentally, support block for async_dispatch. Message-ID: <20070510051136.D02B25240C5C@rubyforge.org> Revision: 164 Author: kato-k Date: 2007-05-10 01:11:34 -0400 (Thu, 10 May 2007) Log Message: ----------- Experimentally, support block for async_dispatch. Modified Paths: -------------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb 2007-05-10 04:42:10 UTC (rev 163) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb 2007-05-10 05:11:34 UTC (rev 164) @@ -27,7 +27,7 @@ DRUBY_HOST = ENV['AP4R_DRUBY_HOST'] || 'localhost' DRUBY_PORT = ENV['AP4R_DRUBY_PORT'] || '6438' - DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}" + DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}" @@default_dispatch_mode = :HTTP @@default_rm_options = { :delivery => :once, :dispatch_mode => @@default_dispatch_mode } @@ -43,7 +43,7 @@ # # If the execution of +block+ finishes successfully, database transaction is committed and # forward process of each stored message begins. - # Forward process composed in two parts. First puts the message into a queue, secondary update + # Forward process composed in two parts. First puts the message into a queue, secondary update # or delete the entry from a management table. # # SAF (store and forward) processing like this guarantees that any message @@ -77,7 +77,7 @@ # Once some error occured, such as disconnect reliable-msg or server crush, # which is smart to keep to put a message or stop to do it? # In the case of being many async messages, the former strategy is not so good. - # + # # TODO: add delayed forward mode 2007/05/02 by shino Thread.current[:stored_messages].each {|k,v| __queue_put(v[:queue_name], v[:queue_message], v[:queue_headers]) @@ -124,7 +124,33 @@ # Object of argumemts (async_params, options and rm_options) will not be modified. # Implementors (of this class and converters) should not modify them. # - def async_dispatch(url_options = {}, async_params = nil, rm_options = nil) + def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block) + + queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options) + + if block_given? + yield + end + + + if Thread.current[:use_saf] + stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers) + + Thread.current[:stored_messages].store( + stored_message.id, + { + :queue_message => queue_message, + :queue_name => queue_name, + :queue_headers => queue_headers + } ) + return stored_message.id + end + + __queue_put(queue_name, queue_message, queue_headers) + end + + private + def __before_block_evaluation(url_options, async_params, rm_options) # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino if logger.debug? logger.debug("url_options: ") @@ -145,27 +171,9 @@ converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self) logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"} - queue_name = __get_queue_name(url_options, rm_options) - queue_message = converter.make_params - queue_headers = converter.make_rm_options - - if Thread.current[:use_saf] - stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers) - - Thread.current[:stored_messages].store( - stored_message.id, - { - :queue_message => queue_message, - :queue_name => queue_name, - :queue_headers => queue_headers - } ) - return stored_message.id - end - - __queue_put(queue_name, queue_message, queue_headers) + return __get_queue_name(url_options, rm_options), converter.make_params, converter.make_rm_options end - private def __queue_put(queue_name, queue_message, queue_headers) # TODO: can use a Queue instance repeatedly? 2007/05/02 by shino q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI) From kato-k at rubyforge.org Thu May 10 03:01:45 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Thu, 10 May 2007 03:01:45 -0400 (EDT) Subject: [ap4r-devel] [165] trunk/samples/HelloWorld: Refactoring, change name space and use forwardable. Message-ID: <20070510070145.B84305240C6D@rubyforge.org> Revision: 165 Author: kato-k Date: 2007-05-10 03:01:44 -0400 (Thu, 10 May 2007) Log Message: ----------- Refactoring, change name space and use forwardable. Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb Added Paths: ----------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb Removed Paths: ------------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_class.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-10 05:11:34 UTC (rev 164) +++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-10 07:01:44 UTC (rev 165) @@ -19,15 +19,10 @@ def execute_with_block write('Hello') -# req = {:world_id => rand(100), :message => "World", :sleep => params[:sleep]} -# async_dispatch({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do -# req[:world_id] = rand(100) -# req[:message] = "World" -# req[:sleep] = params[:sleep] -# req[:foo] = {:a => 1, :b => 2} -# req[:bar] = [0, 1, 2] -# end - + #TODO: change first argument like the following sample, 2007/5/10 kato-k + # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...) + # + #TODO: support more flexible description in block, 2007/5/10 kato-k ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do req[:world_id] = rand(100) req[:message] = "World" @@ -40,7 +35,7 @@ end def execute_with_saf - Ap4r::AsyncController::Base.saf_delete_mode = :logical + Ap4r::AsyncHelper::Base.saf_delete_mode = :logical ap4r.transaction do write('Hello') Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-10 05:11:34 UTC (rev 164) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-10 07:01:44 UTC (rev 165) @@ -2,12 +2,12 @@ # Copyright:: Copyright (c) 2007 Future Architect Inc. # Licence:: MIT Licence -require 'async_controller' require 'ap4r/stored_message' -require 'ap4r_class' +require 'async_helper' +require 'ap4r_client' class ActionController::Base def ap4r - @ap4r ||= Ap4rClass.new(self) + @ap4r ||= ::Ap4r::Client.new(self) end end Deleted: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_class.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_class.rb 2007-05-10 05:11:34 UTC (rev 164) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_class.rb 2007-05-10 07:01:44 UTC (rev 165) @@ -1,27 +0,0 @@ -# Author:: Kiwamu Kato -# Copyright:: Copyright (c) 2007 Future Architect Inc. -# Licence:: MIT Licence - -class Ap4rClass - include ::Ap4r::AsyncController::Base - - def initialize controller - @controller = controller - end - - def async_to(url_options = {}, async_params = nil, rm_options = nil, &block) - async_dispatch(url_options, async_params,rm_options, &block) - end - - def transaction active_record_class = ::Ap4r::StoredMessage, *objects, &block - transaction_with_saf(active_record_class, *objects, &block) - end - - def logger - @controller.logger - end - - def url_for(url_for_options, *parameter_for_method_reference) - @controller.url_for(url_for_options, *parameter_for_method_reference) - end -end Added: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb (rev 0) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-10 07:01:44 UTC (rev 165) @@ -0,0 +1,26 @@ +# Author:: Kiwamu Kato +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'forwardable' + +module Ap4r + class Client + extend Forwardable + include ::Ap4r::AsyncHelper::Base + + def initialize controller + @controller = controller + end + + def async_to(url_options = {}, async_params = nil, rm_options = nil, &block) + async_dispatch(url_options, async_params,rm_options, &block) + end + + def transaction active_record_class = ::Ap4r::StoredMessage, *objects, &block + transaction_with_saf(active_record_class, *objects, &block) + end + + def_delegators :@controller, :logger, :url_for + end +end Deleted: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb 2007-05-10 05:11:34 UTC (rev 164) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb 2007-05-10 07:01:44 UTC (rev 165) @@ -1,304 +0,0 @@ -# Author:: Shunichi Shinohara -# Copyright:: Copyright (c) 2007 Future Architect Inc. -# Licence:: MIT Licence - -require 'reliable-msg' -#require 'ap4r/stored_message' - -module Ap4r - - # This +AsyncController+ is the Rails plugin for asynchronous processing. - # Asynchronous logics are called via various protocols, such as XML-RPC, - # SOAP, HTTP POST, and more. Now default protocol is HTTP POST. - # - # Examples: The part of calling next asynchronous logics in a controller in the HelloWorld Sample. - # - # req = WorldRequest.new([:world_id => 1, :message => "World"}) - # async_dispatch(req, - # {:controller => 'async_world', :action => 'execute'}, - # :dispatch_mode => :XMLRPC }) # skippable - # - # render :action => 'response' - # - module AsyncController - - module Base - Converters = {} - - DRUBY_HOST = ENV['AP4R_DRUBY_HOST'] || 'localhost' - DRUBY_PORT = ENV['AP4R_DRUBY_PORT'] || '6438' - DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}" - - @@default_dispatch_mode = :HTTP - @@default_rm_options = { :delivery => :once, :dispatch_mode => @@default_dispatch_mode } - @@default_queue_prefix = "queue." - - mattr_accessor :default_dispatch_mode, :default_rm_options, :default_queue_prefix, :saf_delete_mode - - # Provides at-least-once QoS level. - # +block+ are tipically composed of database accesses and +async_dispatch+ calls. - # Database accesses are executed transactionallly by +active_record_class+'s transaction method. - # In the +block+, +async_dispatch+ calls invoke NOT immediate queueing but just storing messages - # to the database (assumed to be the same one as application uses). - # - # If the execution of +block+ finishes successfully, database transaction is committed and - # forward process of each stored message begins. - # Forward process composed in two parts. First puts the message into a queue, secondary update - # or delete the entry from a management table. - # - # SAF (store and forward) processing like this guarantees that any message - # is never lost and keeps reasonable performance (without two phase commit). - # - # Examples: Just call async_dispath method in this block. - # - # transaction_with saf do - # req = WorldRequest.new([:world_id => 1, :message => "World"}) - # async_dispatch(req, - # {:controller => 'async_world', :action => 'execute'}, - # :dispatch_mode => :XMLRPC }) # skippable - # - # render :action => 'response' - # end - # - def transaction_with_saf(active_record_class = ::Ap4r::StoredMessage, *objects, &block) - - Thread.current[:use_saf] = true - Thread.current[:stored_messages] = {} - - # store - active_record_class ||= ::Ap4r::StoredMessage - active_record_class.transaction(*objects, &block) - - # forward - forwarded_messages = {} - begin - - # TODO: reconsider forwarding strategy, 2006/10/13 kato-k - # Once some error occured, such as disconnect reliable-msg or server crush, - # which is smart to keep to put a message or stop to do it? - # In the case of being many async messages, the former strategy is not so good. - # - # TODO: add delayed forward mode 2007/05/02 by shino - Thread.current[:stored_messages].each {|k,v| - __queue_put(v[:queue_name], v[:queue_message], v[:queue_headers]) - forwarded_messages[k] = v - } - rescue Exception => err - # Don't raise any Exception. Application logic has already completed and messages are saved. - logger.warn("Failed to put a message into queue: #{err}") - end - - begin - StoredMessage.transaction do - options = {:delete_mode => @@saf_delete_mode || :physical} - forwarded_messages.keys.each {|id| - ::Ap4r::StoredMessage.destroy_if_exists(id, options) - } - end - rescue Exception => err - # Don't raise any Exception. Application logic has already completed and messages are saved. - logger.warn("Failed to put a message into queue: #{err}") - end - - ensure - Thread.current[:use_saf] = false - Thread.current[:stored_messages] = nil - end - - # Queue a message for next asynchronous logic. Some options are supported. - # - # Use options to specify target url, etc. - # Accurate meanings are defined by a individual converter class. - # * :controller (name of next logic) - # * :action (name of next logic) - # - # Use rm_options to pass parameter in queue-put. - # Listings below are AP4R extended options. - # See the reliable-msg docuememt for more details. - # * :target_url (URL of target, prevail over :controller) - # * :target_action (action of target, prevail over :action) - # * :target_method (HTTP method, e.g. "GET", "POST", etc.) - # * :dispatch_mode (protocol in dispatching) - # * :queue_name (prevail over :controller and :action) - # - # Object of argumemts (async_params, options and rm_options) will not be modified. - # Implementors (of this class and converters) should not modify them. - # - def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block) - - queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options) - - if block_given? - yield - end - - - if Thread.current[:use_saf] - stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers) - - Thread.current[:stored_messages].store( - stored_message.id, - { - :queue_message => queue_message, - :queue_name => queue_name, - :queue_headers => queue_headers - } ) - return stored_message.id - end - - __queue_put(queue_name, queue_message, queue_headers) - end - - private - def __before_block_evaluation(url_options, async_params, rm_options) - # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino - if logger.debug? - logger.debug("url_options: ") - logger.debug(url_options.inspect) - logger.debug("async_params: ") - logger.debug(async_params.inspect) - logger.debug("rm_options: ") - logger.debug(rm_options.inspect) - end - - # TODO: clone it, 2006/10/16 shino - url_options ||= {} - url_options[:controller] ||= self.controller_path.gsub("/", ".") - rm_options = @@default_rm_options.merge(rm_options || {}) - - # Only async_params is not cloned. options and rm_options are cloned before now. - # This is a current contract between this class and converter classes. - converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self) - logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"} - - return __get_queue_name(url_options, rm_options), converter.make_params, converter.make_rm_options - end - - def __queue_put(queue_name, queue_message, queue_headers) - # TODO: can use a Queue instance repeatedly? 2007/05/02 by shino - q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI) - q.put(queue_message, queue_headers) - end - - def __get_queue_name(options, rm_options) - rm_options[:queue_name] ||= - @@default_queue_prefix.clone.concat(options[:controller].to_s).concat('.').concat(options[:action].to_s) - rm_options[:queue_name] - end - - end - - module Converters #:nodoc: - - # A base class for converter classes. - # Responsibilities of subclasses are as folows - # * by +make_params+, convert async_params to appropriate object - # * by +make_rm_options+, make appropriate +Hash+ passed by ReliableMsg::Queue#put - class Base - - # Difine a constant +DISPATCH_MODE+ to value 'mode_symbol' and - # add self to a Converters list. - def self.dispatch_mode(mode_symbol) - self.const_set(:DISPATCH_MODE, mode_symbol) - ::Ap4r::AsyncController::Base::Converters[mode_symbol] = self - end - - def initialize(url_options, async_params, rm_options, url_for_handler) - @url_options = url_options - @async_params = async_params - @rm_options = rm_options - @url_for_handler = url_for_handler - end - - # Returns a object which passed to ReliableMsg::Queue.put(message, headers)'s - # first argument +message+. - # Should be implemented by subclasses. - def make_params - raise 'must be implemented in subclasses' - end - - # Returns a object which passed to ReliableMsg::Queue.put(message, headers)'s - # second argument +headers+. - # Should be implemented by subclasses. - def make_rm_options - raise 'must be implemented in subclasses' - end - - private - # helper method for ActionController#url_for - def url_for(url_for_options, *parameter_for_method_reference) - @url_for_handler.url_for(url_for_options, *parameter_for_method_reference) - end - - end - - class Http < Base - dispatch_mode :HTTP - - def make_params - @async_params - end - - def make_rm_options - @rm_options[:target_url] ||= url_for(@url_options) - @rm_options[:target_method] ||= 'POST' - #TODO: make option key to specify HTTP headers, 2006/10/16 shino - @rm_options - end - end - - class WebService < Base - def make_params - message_obj = {} - @async_params.each_pair{|k,v| message_obj[k.to_sym]=v} - message_obj - end - - def make_rm_options - @rm_options[:target_url] ||= target_url_name - @rm_options[:target_action] ||= action_api_name - @rm_options - end - - def action_api_name - action_method_name = @url_options[:action] - action_method_name.camelcase - end - - def options_without_action - new_opts = @url_options.dup - new_opts[:action] = nil - new_opts - end - - end - - class XmlRpc < WebService - dispatch_mode :XMLRPC - - def target_url_name - url_for(options_without_action) + rails_api_url_suffix - end - - private - def rails_api_url_suffix - '/api' - end - end - - class SOAP < WebService - dispatch_mode :SOAP - - def target_url_name - url_for(options_without_action) + rails_wsdl_url_suffix - end - - private - def rails_wsdl_url_suffix - '/service.wsdl' - end - end - - end - end -end Added: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb (rev 0) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-10 07:01:44 UTC (rev 165) @@ -0,0 +1,303 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'reliable-msg' + +module Ap4r + + # This +AsyncHelper+ is the Rails plugin for asynchronous processing. + # Asynchronous logics are called via various protocols, such as XML-RPC, + # SOAP, HTTP POST, and more. Now default protocol is HTTP POST. + # + # Examples: The part of calling next asynchronous logics in a controller in the HelloWorld Sample. + # + # req = WorldRequest.new([:world_id => 1, :message => "World"}) + # async_dispatch(req, + # {:controller => 'async_world', :action => 'execute'}, + # :dispatch_mode => :XMLRPC }) # skippable + # + # render :action => 'response' + # + module AsyncHelper + + module Base + Converters = {} + + DRUBY_HOST = ENV['AP4R_DRUBY_HOST'] || 'localhost' + DRUBY_PORT = ENV['AP4R_DRUBY_PORT'] || '6438' + DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}" + + @@default_dispatch_mode = :HTTP + @@default_rm_options = { :delivery => :once, :dispatch_mode => @@default_dispatch_mode } + @@default_queue_prefix = "queue." + + mattr_accessor :default_dispatch_mode, :default_rm_options, :default_queue_prefix, :saf_delete_mode + + # Provides at-least-once QoS level. + # +block+ are tipically composed of database accesses and +async_dispatch+ calls. + # Database accesses are executed transactionallly by +active_record_class+'s transaction method. + # In the +block+, +async_dispatch+ calls invoke NOT immediate queueing but just storing messages + # to the database (assumed to be the same one as application uses). + # + # If the execution of +block+ finishes successfully, database transaction is committed and + # forward process of each stored message begins. + # Forward process composed in two parts. First puts the message into a queue, secondary update + # or delete the entry from a management table. + # + # SAF (store and forward) processing like this guarantees that any message + # is never lost and keeps reasonable performance (without two phase commit). + # + # Examples: Just call async_dispath method in this block. + # + # transaction_with saf do + # req = WorldRequest.new([:world_id => 1, :message => "World"}) + # async_dispatch(req, + # {:controller => 'async_world', :action => 'execute'}, + # :dispatch_mode => :XMLRPC }) # skippable + # + # render :action => 'response' + # end + # + def transaction_with_saf(active_record_class = ::Ap4r::StoredMessage, *objects, &block) + + Thread.current[:use_saf] = true + Thread.current[:stored_messages] = {} + + # store + active_record_class ||= ::Ap4r::StoredMessage + active_record_class.transaction(*objects, &block) + + # forward + forwarded_messages = {} + begin + + # TODO: reconsider forwarding strategy, 2006/10/13 kato-k + # Once some error occured, such as disconnect reliable-msg or server crush, + # which is smart to keep to put a message or stop to do it? + # In the case of being many async messages, the former strategy is not so good. + # + # TODO: add delayed forward mode 2007/05/02 by shino + Thread.current[:stored_messages].each {|k,v| + __queue_put(v[:queue_name], v[:queue_message], v[:queue_headers]) + forwarded_messages[k] = v + } + rescue Exception => err + # Don't raise any Exception. Application logic has already completed and messages are saved. + logger.warn("Failed to put a message into queue: #{err}") + end + + begin + StoredMessage.transaction do + options = {:delete_mode => @@saf_delete_mode || :physical} + forwarded_messages.keys.each {|id| + ::Ap4r::StoredMessage.destroy_if_exists(id, options) + } + end + rescue Exception => err + # Don't raise any Exception. Application logic has already completed and messages are saved. + logger.warn("Failed to put a message into queue: #{err}") + end + + ensure + Thread.current[:use_saf] = false + Thread.current[:stored_messages] = nil + end + + # Queue a message for next asynchronous logic. Some options are supported. + # + # Use options to specify target url, etc. + # Accurate meanings are defined by a individual converter class. + # * :controller (name of next logic) + # * :action (name of next logic) + # + # Use rm_options to pass parameter in queue-put. + # Listings below are AP4R extended options. + # See the reliable-msg docuememt for more details. + # * :target_url (URL of target, prevail over :controller) + # * :target_action (action of target, prevail over :action) + # * :target_method (HTTP method, e.g. "GET", "POST", etc.) + # * :dispatch_mode (protocol in dispatching) + # * :queue_name (prevail over :controller and :action) + # + # Object of argumemts (async_params, options and rm_options) will not be modified. + # Implementors (of this class and converters) should not modify them. + # + def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block) + + queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options) + + if block_given? + yield + end + + + if Thread.current[:use_saf] + stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers) + + Thread.current[:stored_messages].store( + stored_message.id, + { + :queue_message => queue_message, + :queue_name => queue_name, + :queue_headers => queue_headers + } ) + return stored_message.id + end + + __queue_put(queue_name, queue_message, queue_headers) + end + + private + def __before_block_evaluation(url_options, async_params, rm_options) + # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino + if logger.debug? + logger.debug("url_options: ") + logger.debug(url_options.inspect) + logger.debug("async_params: ") + logger.debug(async_params.inspect) + logger.debug("rm_options: ") + logger.debug(rm_options.inspect) + end + + # TODO: clone it, 2006/10/16 shino + url_options ||= {} + url_options[:controller] ||= self.controller_path.gsub("/", ".") + rm_options = @@default_rm_options.merge(rm_options || {}) + + # Only async_params is not cloned. options and rm_options are cloned before now. + # This is a current contract between this class and converter classes. + converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self) + logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"} + + return __get_queue_name(url_options, rm_options), converter.make_params, converter.make_rm_options + end + + def __queue_put(queue_name, queue_message, queue_headers) + # TODO: can use a Queue instance repeatedly? 2007/05/02 by shino + q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI) + q.put(queue_message, queue_headers) + end + + def __get_queue_name(options, rm_options) + rm_options[:queue_name] ||= + @@default_queue_prefix.clone.concat(options[:controller].to_s).concat('.').concat(options[:action].to_s) + rm_options[:queue_name] + end + + end + + module Converters #:nodoc: + + # A base class for converter classes. + # Responsibilities of subclasses are as folows + # * by +make_params+, convert async_params to appropriate object + # * by +make_rm_options+, make appropriate +Hash+ passed by ReliableMsg::Queue#put + class Base + + # Difine a constant +DISPATCH_MODE+ to value 'mode_symbol' and + # add self to a Converters list. + def self.dispatch_mode(mode_symbol) + self.const_set(:DISPATCH_MODE, mode_symbol) + ::Ap4r::AsyncHelper::Base::Converters[mode_symbol] = self + end + + def initialize(url_options, async_params, rm_options, url_for_handler) + @url_options = url_options + @async_params = async_params + @rm_options = rm_options + @url_for_handler = url_for_handler + end + + # Returns a object which passed to ReliableMsg::Queue.put(message, headers)'s + # first argument +message+. + # Should be implemented by subclasses. + def make_params + raise 'must be implemented in subclasses' + end + + # Returns a object which passed to ReliableMsg::Queue.put(message, headers)'s + # second argument +headers+. + # Should be implemented by subclasses. + def make_rm_options + raise 'must be implemented in subclasses' + end + + private + # helper method for ActionController#url_for + def url_for(url_for_options, *parameter_for_method_reference) + @url_for_handler.url_for(url_for_options, *parameter_for_method_reference) + end + + end + + class Http < Base + dispatch_mode :HTTP + + def make_params + @async_params + end + + def make_rm_options + @rm_options[:target_url] ||= url_for(@url_options) + @rm_options[:target_method] ||= 'POST' + #TODO: make option key to specify HTTP headers, 2006/10/16 shino + @rm_options + end + end + + class WebService < Base + def make_params + message_obj = {} + @async_params.each_pair{|k,v| message_obj[k.to_sym]=v} + message_obj + end + + def make_rm_options + @rm_options[:target_url] ||= target_url_name + @rm_options[:target_action] ||= action_api_name + @rm_options + end + + def action_api_name + action_method_name = @url_options[:action] + action_method_name.camelcase + end + + def options_without_action + new_opts = @url_options.dup + new_opts[:action] = nil + new_opts + end + + end + + class XmlRpc < WebService + dispatch_mode :XMLRPC + + def target_url_name + url_for(options_without_action) + rails_api_url_suffix + end + + private + def rails_api_url_suffix + '/api' + end + end + + class SOAP < WebService + dispatch_mode :SOAP + + def target_url_name + url_for(options_without_action) + rails_wsdl_url_suffix + end + + private + def rails_wsdl_url_suffix + '/service.wsdl' + end + end + + end + end +end From shinohara.shunichi at future.co.jp Thu May 10 03:18:26 2007 From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp) Date: Thu, 10 May 2007 16:18:26 +0900 Subject: [ap4r-devel] [163] trunk/ap4r/ap4r-devel-test.txt: test ap4r-develmailing list 3 In-Reply-To: <20070510044210.8DF4F5240C40@rubyforge.org> References: <20070510044210.8DF4F5240C40@rubyforge.org> Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDEC@045MAIL.future.co.jp> reply testing -----Original Message----- From: ap4r-devel-bounces at rubyforge.org [mailto:ap4r-devel-bounces at rubyforge.org] On Behalf Of shino at rubyforge.org Sent: Thursday, May 10, 2007 1:42 PM To: ap4r-devel at rubyforge.org Subject: [ap4r-devel] [163] trunk/ap4r/ap4r-devel-test.txt: test ap4r-develmailing list 3 Revision: 163 Author: shino Date: 2007-05-10 00:42:10 -0400 (Thu, 10 May 2007) Log Message: ----------- test ap4r-devel mailing list 3 Modified Paths: -------------- trunk/ap4r/ap4r-devel-test.txt Modified: trunk/ap4r/ap4r-devel-test.txt =================================================================== --- trunk/ap4r/ap4r-devel-test.txt 2007-05-10 04:38:29 UTC (rev 162) +++ trunk/ap4r/ap4r-devel-test.txt 2007-05-10 04:42:10 UTC (rev 163) @@ -1,2 +1,3 @@ test test2 +test3 _______________________________________________ Ap4r-devel mailing list Ap4r-devel at rubyforge.org http://rubyforge.org/mailman/listinfo/ap4r-devel From shinohara.shunichi at future.co.jp Thu May 10 03:21:42 2007 From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp) Date: Thu, 10 May 2007 16:21:42 +0900 Subject: [ap4r-devel] test of reply address Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDEF@045MAIL.future.co.jp> no message --------------------------------- SHINOHARA, Shun'ichi Future Architect, Inc. 1-2-2 Osaki Shinagawa-Ku Tokyo, JAPAN (ZIP 141-0032) 070-6991-0765 (cell phone) shinohara.shunichi at future.co.jp From shinohara.shunichi at future.co.jp Thu May 10 03:23:21 2007 From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp) Date: Thu, 10 May 2007 16:23:21 +0900 Subject: [ap4r-devel] test of reply address In-Reply-To: <14CE73B79D552644B7CBEF0428763DF60247FDEF@045MAIL.future.co.jp> References: <14CE73B79D552644B7CBEF0428763DF60247FDEF@045MAIL.future.co.jp> Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDF1@045MAIL.future.co.jp> this is a reply message. -----Original Message----- From: ap4r-devel-bounces at rubyforge.org [mailto:ap4r-devel-bounces at rubyforge.org] On Behalf Of shinohara.shunichi at future.co.jp Sent: Thursday, May 10, 2007 4:22 PM To: ap4r-devel at rubyforge.org Subject: [ap4r-devel] test of reply address no message --------------------------------- SHINOHARA, Shun'ichi Future Architect, Inc. 1-2-2 Osaki Shinagawa-Ku Tokyo, JAPAN (ZIP 141-0032) 070-6991-0765 (cell phone) shinohara.shunichi at future.co.jp _______________________________________________ ap4r-devel mailing list ap4r-devel at rubyforge.org http://rubyforge.org/mailman/listinfo/ap4r-devel From shinohara.shunichi at future.co.jp Thu May 10 03:33:57 2007 From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp) Date: Thu, 10 May 2007 16:33:57 +0900 Subject: [ap4r-devel 18] test of sequential number Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDF7@045MAIL.future.co.jp> no message --------------------------------- SHINOHARA, Shun'ichi Future Architect, Inc. 1-2-2 Osaki Shinagawa-Ku Tokyo, JAPAN (ZIP 141-0032) 070-6991-0765 (cell phone) shinohara.shunichi at future.co.jp From shinohara.shunichi at future.co.jp Thu May 10 03:43:42 2007 From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp) Date: Thu, 10 May 2007 16:43:42 +0900 Subject: [ap4r-devel:19] test of sequential number #2 Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDFB@045MAIL.future.co.jp> no message --------------------------------- SHINOHARA, Shun'ichi Future Architect, Inc. 1-2-2 Osaki Shinagawa-Ku Tokyo, JAPAN (ZIP 141-0032) 070-6991-0765 (cell phone) shinohara.shunichi at future.co.jp From shinohara.shunichi at future.co.jp Thu May 10 03:49:58 2007 From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp) Date: Thu, 10 May 2007 16:49:58 +0900 Subject: [ap4r-devel:20] Re: test of sequential number #2 In-Reply-To: <14CE73B79D552644B7CBEF0428763DF60247FDFB@045MAIL.future.co.jp> References: <14CE73B79D552644B7CBEF0428763DF60247FDFB@045MAIL.future.co.jp> Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDFE@045MAIL.future.co.jp> test of reply with squential number -----Original Message----- From: ap4r-devel-bounces at rubyforge.org [mailto:ap4r-devel-bounces at rubyforge.org] On Behalf Of shinohara.shunichi at future.co.jp Sent: Thursday, May 10, 2007 4:44 PM To: ap4r-devel at rubyforge.org Subject: [ap4r-devel:19] test of sequential number #2 no message --------------------------------- SHINOHARA, Shun'ichi Future Architect, Inc. 1-2-2 Osaki Shinagawa-Ku Tokyo, JAPAN (ZIP 141-0032) 070-6991-0765 (cell phone) shinohara.shunichi at future.co.jp _______________________________________________ ap4r-devel mailing list ap4r-devel at rubyforge.org http://rubyforge.org/mailman/listinfo/ap4r-devel From kato-k at rubyforge.org Thu May 10 03:58:45 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Thu, 10 May 2007 03:58:45 -0400 (EDT) Subject: [ap4r-devel] [166] trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb: Refactoring. Message-ID: <20070510075845.E4F305240C60@rubyforge.org> Revision: 166 Author: kato-k Date: 2007-05-10 03:58:45 -0400 (Thu, 10 May 2007) Log Message: ----------- Refactoring. Modified Paths: -------------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-10 07:01:44 UTC (rev 165) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-10 07:58:45 UTC (rev 166) @@ -13,14 +13,9 @@ @controller = controller end - def async_to(url_options = {}, async_params = nil, rm_options = nil, &block) - async_dispatch(url_options, async_params,rm_options, &block) - end - - def transaction active_record_class = ::Ap4r::StoredMessage, *objects, &block - transaction_with_saf(active_record_class, *objects, &block) - end - def_delegators :@controller, :logger, :url_for + + alias :async_to :async_dispatch + alias :transaction :transaction_with_saf end end From shino at rubyforge.org Thu May 10 04:48:31 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 10 May 2007 04:48:31 -0400 (EDT) Subject: [ap4r-devel] [167] trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb: refactoring: lengthen a varivable name to avoid accidental name collision Message-ID: <20070510084831.3E8C65240952@rubyforge.org> Revision: 167 Author: shino Date: 2007-05-10 04:48:30 -0400 (Thu, 10 May 2007) Log Message: ----------- refactoring: lengthen a varivable name to avoid accidental name collision Modified Paths: -------------- trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-10 07:58:45 UTC (rev 166) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-10 08:48:30 UTC (rev 167) @@ -8,6 +8,6 @@ class ActionController::Base def ap4r - @ap4r ||= ::Ap4r::Client.new(self) + @ap4r_client ||= ::Ap4r::Client.new(self) end end From shino at rubyforge.org Thu May 10 05:36:42 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 10 May 2007 05:36:42 -0400 (EDT) Subject: [ap4r-devel] [168] trunk/ap4r/lib/ap4r/dispatcher.rb: Refactoring: extract methods and restructure methods. Message-ID: <20070510093645.8C1465240978@rubyforge.org> Revision: 168 Author: shino Date: 2007-05-10 05:36:38 -0400 (Thu, 10 May 2007) Log Message: ----------- Refactoring: extract methods and restructure methods. Add Rdoc. Modified Paths: -------------- trunk/ap4r/lib/ap4r/dispatcher.rb Modified: trunk/ap4r/lib/ap4r/dispatcher.rb =================================================================== --- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-10 08:48:30 UTC (rev 167) +++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-10 09:36:38 UTC (rev 168) @@ -26,12 +26,20 @@ @@logger end - # Stores Dispatchers::Base's subclasses. + # storage for Dispatchers::Base's subclasses. @@subclasses = {} + + # Stores +klass+ for a dispatch mode +mode+ + # Each +klass+ is used to create instances to handle dispatching messages. def self.register_dispatcher_class(mode, klass) @@subclasses[mode] = klass end + # Sum of each dispatcher's target queues. + def targets + @dispatch_targets + end + def initialize(queue_manager, config, logger_obj) @qm = queue_manager @config = config @@ -41,12 +49,9 @@ @dispatch_targets = "" end - # Sum of each dispatcher's target queues. - def targets - @dispatch_targets - end - # Starts every dispatcher. + # If an exception is detected, this method raise it through with logging. + # def start begin logger.info{ "about to start dispatchers with config\n#{@config.to_yaml}" } @@ -81,18 +86,22 @@ private - def get_dispather_instance(dispatch_mode) + # Creates and returns an appropriate instace. + # If no class for +dispatch_mode+, raises an exception. + def get_dispather_instance(dispatch_mode, message, conf) klass = @@subclasses[dispatch_mode] raise "undefined dispatch mode #{m.headers[:mode]}" unless klass - klass.new + klass.new(message, conf) end + # Defines the general structure for each dispatcher thread + # from begging to end. def dispatching_loop(group, conf, index) group.add(Thread.current) mq = ::ReliableMsg::MultiQueue.new(conf["targets"]) logger.info{ "start dispatcher: targets= #{mq}, index= #{index})" } until Thread.current[:dying] - # TODO: better to change sleep interval depending on last result? 2007/05/09 by shino + # TODO: change sleep interval depending on last result? 2007/05/09 by shino sleep 0.1 # logger.debug{ "try dispatch #{mq} #{mq.name}" } # TODO: needs timeout?, 2006/10/16 shino @@ -103,7 +112,7 @@ break end logger.debug{"dispatcher get message\n#{m.to_yaml}"} - response = get_dispather_instance(m.headers[:dispatch_mode]).call(m, conf) + response = get_dispather_instance(m.headers[:dispatch_mode], m, conf).call logger.debug{"dispatcher get response\n#{response.to_yaml}"} } rescue Exception => err @@ -131,35 +140,61 @@ ::Ap4r::Dispatchers.register_dispatcher_class(mode_symbol, self) end - def call(message, conf) + def initialize(message, conf) + @message = message + @conf = conf + end + + def call + # TODO: rename to more appropriate one 2007/05/10 by shino + self.modify_message + self.invoke + self.varidate_response + self.response + end + + def modify_message + # nop + end + + def invoke + # TODO: rename to more appropriate one 2007/05/10 by shino raise 'must be implemented in subclasses' end + def varidate_response + # nop + end + + def response + @response + end + + private def logger ::Ap4r::Dispatchers.logger end end - # Dispatch login via HTTP. + # Dispatch logic via HTTP. class Http < Base dispatch_mode :HTTP - # Dispatches via a HTTP protocol. - # Current implementation uses POST method, irrespectively options[:target_method] + # Dispatches via a raw HTTP protocol. + # Current implementation uses only a POST method, irrespectively + # options[:target_method]. # - # Determination of "success" is two fold - # * status code should be 200, other codes (including 201-2xx) are treated as error - # * when status code is 200, body should include a string "true" - def call(message, conf) + # Determination of "success" is two fold: + # * status code should be exactly 200, other codes (including 201-2xx) are + # treated as error, and + # * body should include a string "true" + def invoke #TODO: should be added some request headers e.g. User-Agent and Accept, 2006/10/12 shino #TODO: Now supports POST only, 2006/10/12 shino - @response = Net::HTTP.post_form(URI.parse(message[:target_url]), - message.object) - varidate_response - @response + @response = Net::HTTP.post_form(URI.parse(@message[:target_url]), + @message.object) end - private def varidate_response logger.debug{"response status [#{@response.code} #{@response.message}]"} varidate_response_status(Net::HTTPOK) @@ -197,23 +232,25 @@ class XmlRpc < Base dispatch_mode :XMLRPC - def call(message, conf) - endpoint = message[:target_url] + + def invoke + endpoint = @message[:target_url] client = XMLRPC::Client.new2(endpoint) - success, response = client.call2(message[:target_action], message.object) - raise response unless success - response + @success, @response = client.call2(@message[:target_action], @message.object) end + + def varidate_response + raise @response unless @success + end end class SOAP < Base dispatch_mode :SOAP - def call(message, conf) - logger.debug{message[:target_url]} + + def invoke # TODO: nice to cache drivers probably 2007/05/09 by shino - driver = ::SOAP::WSDLDriverFactory.new(message[:target_url]).create_rpc_driver - logger.debug{driver} - driver.send(message[:target_action], message.object) + driver = ::SOAP::WSDLDriverFactory.new(@message[:target_url]).create_rpc_driver + driver.send(@message[:target_action], @message.object) end end From shino at rubyforge.org Thu May 10 23:11:39 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 10 May 2007 23:11:39 -0400 (EDT) Subject: [ap4r-devel] [169] trunk/ap4r/lib/ap4r/dispatcher.rb: Implemented url modification function briefly. Message-ID: <20070511031139.28AE85240A99@rubyforge.org> Revision: 169 Author: shino Date: 2007-05-10 23:11:38 -0400 (Thu, 10 May 2007) Log Message: ----------- Implemented url modification function briefly. Presenct implementation takes proc string in yaml, evals it and calls it. Also made Some refactorings and comment addtion. Modified Paths: -------------- trunk/ap4r/lib/ap4r/dispatcher.rb Modified: trunk/ap4r/lib/ap4r/dispatcher.rb =================================================================== --- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-10 09:36:38 UTC (rev 168) +++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-11 03:11:38 UTC (rev 169) @@ -42,7 +42,7 @@ def initialize(queue_manager, config, logger_obj) @qm = queue_manager - @config = config + @config = config # (typically) dispatcher section of queues.cfg @@logger ||= logger_obj raise "no configuration specified" unless @config @group = ThreadGroup.new @@ -88,10 +88,10 @@ # Creates and returns an appropriate instace. # If no class for +dispatch_mode+, raises an exception. - def get_dispather_instance(dispatch_mode, message, conf) + def get_dispather_instance(dispatch_mode, message, conf_per_targets) klass = @@subclasses[dispatch_mode] raise "undefined dispatch mode #{m.headers[:mode]}" unless klass - klass.new(message, conf) + klass.new(message, conf_per_targets) end # Defines the general structure for each dispatcher thread @@ -129,8 +129,12 @@ # A base class for dispathcer classes. - # Responsibilities of subclasses are as folows - # * +call+ + # Responsibilities of subclasses is to implement following methods, only +invoke+ + # is mandatory and others are optional (no operations by default). + # * +modify_message+ to preprocess a message, e.g. rewirte URL or discard message. + # * +invoke+ to execute main logic, e.g. HTTP POST call. *mandatory* + # * +varidate_response+ to judge whether +invoke+ finished successfully. + # * +response+ to return the result of +invoke+ process. class Base # Difine a constant +DISPATCH_MODE+ to value 'mode_symbol' and @@ -148,13 +152,16 @@ def call # TODO: rename to more appropriate one 2007/05/10 by shino self.modify_message + logger.debug{"Ap4r::Dispatcher after modification\n#{@message.to_yaml}"} self.invoke self.varidate_response self.response end def modify_message - # nop + modification_rules = @conf["modify_rules"] + return unless modification_rules + modify_url(modification_rules) end def invoke @@ -174,6 +181,15 @@ def logger ::Ap4r::Dispatchers.logger end + + def modify_url(modification_rules) + proc_for_url = modification_rules["url"] + return unless proc_for_url + + url = URI.parse(@message.headers[:target_url]) + eval(proc_for_url).call(url) + @message.headers[:target_url] = url.to_s + end end # Dispatch logic via HTTP. @@ -189,8 +205,9 @@ # treated as error, and # * body should include a string "true" def invoke - #TODO: should be added some request headers e.g. User-Agent and Accept, 2006/10/12 shino - #TODO: Now supports POST only, 2006/10/12 shino + # TODO: should be added some request headers 2006/10/12 shino + # e.g. X-Ap4r-Version, Accept(need it?) + # TODO: Now supports POST only, 2006/10/12 shino @response = Net::HTTP.post_form(URI.parse(@message[:target_url]), @message.object) end @@ -201,12 +218,13 @@ varidate_response_body(/true/) end - # Checks the response status is kind of +status_kind+ + # Checks whether the response status is a kind of +status_kind+. # +status_kind+ should be one of Net::HTTPRespose's subclasses. def varidate_response_status(status_kind) #TODO: make the difinition of success variable, 2006/10/13 shino unless @response.kind_of?(status_kind) - error_message = "HTTP Response FAILURE, status [#{@response.code} #{@response.message}]" + error_message = "HTTP Response FAILURE, " + + "status [#{@response.code} #{@response.message}]" logger.error(error_message) logger.info{@response.to_yaml} #TODO: must create AP4R specific Exception class, 2006/10/12 shino @@ -214,12 +232,12 @@ end end - # Checks the response body includes +pattern+. + # Checks whether the response body includes +pattern+. # +pattern+ should be a regular expression. def varidate_response_body(pattern) unless @response.body =~ pattern - error_message = "HTTP Response FAILURE, status" - + " [#{@response.code} #{@response.message}], body [#{@response.body}]" + error_message = "HTTP Response FAILURE, status" + + " [#{@response.code} #{@response.message}], body [#{@response.body}]" #TODO: Refactor error logging, 2006/10/13 shino logger.error(error_message) logger.info{@response.to_yaml} From kato-k at rubyforge.org Fri May 11 06:42:53 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 11 May 2007 06:42:53 -0400 (EDT) Subject: [ap4r-devel] [170] trunk/samples/HelloWorld: experimental implementation for async_to method with block, jsut block evaluation. Message-ID: <20070511104253.65AC45240977@rubyforge.org> Revision: 170 Author: kato-k Date: 2007-05-11 06:42:53 -0400 (Fri, 11 May 2007) Log Message: ----------- experimental implementation for async_to method with block, jsut block evaluation. Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb Added Paths: ----------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-11 03:11:38 UTC (rev 169) +++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-11 10:42:53 UTC (rev 170) @@ -23,12 +23,46 @@ # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...) # #TODO: support more flexible description in block, 2007/5/10 kato-k - ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do - req[:world_id] = rand(100) - req[:message] = "World" - req[:sleep] = params[:sleep] - req[:foo] = {:a => 1, :b => 2} - req[:bar] = [0, 1, 2] + ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do |b| + + # message body + # basically, use block argumennt + b.hoge1 = "hoge1" + b[:hoge2] = "hoge2" + + #b.hoge3 "hoge3" # not support + b.id = 1 # method "id" is also available. + + #TODO support ActiveRecord object, 2007/5/11 kato-k + b.order = @order #? + + # message header + b.headers[:target_url] = "http://..." + b.headers[:priority] = 2 + b.headers[:druby_url] = "druby://..." + + #TODO support http headers, 2007/5/11 kato-k + #b.http_headers[:accept] = "text/plain" + #b.http_headers["content-type"] = "application/json" + #b.headers[:http_header_accept] = "text/plain" + + #tricky pattern, but definition in method arguments is necessary. + req[:_num] = rand(100) + req[:_str] = "World" + req[:_hash] = {:a => 1, :b => 2} + req[:_array] = [0, 1, 2] + + + #TODO support various request formats such as xml and json, 2007/5/11 kato-k + #b.queue_message = @order, :include => :details, :format => :json + #b.queue_message = @order, :include => :details, :format => :xml + + + # contens of message are referable + p b.queue_name + p b.queue_message + p b.queue_headers + end render :nothing => true Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-11 03:11:38 UTC (rev 169) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-11 10:42:53 UTC (rev 170) @@ -2,8 +2,6 @@ # Copyright:: Copyright (c) 2007 Future Architect Inc. # Licence:: MIT Licence -require 'ap4r/stored_message' -require 'async_helper' require 'ap4r_client' class ActionController::Base Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-11 03:11:38 UTC (rev 169) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-11 10:42:53 UTC (rev 170) @@ -3,6 +3,7 @@ # Licence:: MIT Licence require 'forwardable' +require 'async_helper' module Ap4r class Client @@ -17,5 +18,10 @@ alias :async_to :async_dispatch alias :transaction :transaction_with_saf + + def message + @message ||= {} + end + end end Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-11 03:11:38 UTC (rev 169) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-11 10:42:53 UTC (rev 170) @@ -3,6 +3,8 @@ # Licence:: MIT Licence require 'reliable-msg' +require 'ap4r/stored_message' +require 'message_builder' module Ap4r @@ -128,10 +130,11 @@ queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options) if block_given? - yield + message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers) + yield message_builder + #TODO __after_block_evaluation, merge message_builder to queue_*, 2007/5/11 kato-k end - if Thread.current[:use_saf] stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers) Added: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb (rev 0) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-11 10:42:53 UTC (rev 170) @@ -0,0 +1,31 @@ +# Author:: Kiwamu Kato +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +module Ap4r + class MessageBuilder + + def initialize(queue_name, queue_message, queue_headers) + @queue_name = queue_name + @queue_message = queue_message + @queue_headers = queue_headers + end + + attr_accessor :queue_name, :queue_message, :queue_headers + + def method_missing name, *args + if name.to_s == "[]=" + @queue_message[args[0]] = args[1] + elsif name.to_s == "headers" + return @queue_headers + elsif name.to_s == "http_headers" + #TODO implementation, 2007/5/11 kato-k + return {} + else + # remove "=" + @queue_message[name.to_s.chop] = args[0] + end + end + + end +end From kato-k at rubyforge.org Mon May 14 01:27:47 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 14 May 2007 01:27:47 -0400 (EDT) Subject: [ap4r-devel] [171] trunk/samples/HelloWorld: Refactoring: extract method and add comments. Message-ID: <20070514052748.4BB615240BC4@rubyforge.org> Revision: 171 Author: kato-k Date: 2007-05-14 01:27:42 -0400 (Mon, 14 May 2007) Log Message: ----------- Refactoring: extract method and add comments. Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-11 10:42:53 UTC (rev 170) +++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-14 05:27:42 UTC (rev 171) @@ -19,10 +19,11 @@ def execute_with_block write('Hello') - #TODO: change first argument like the following sample, 2007/5/10 kato-k - # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...) + # TODO: should change first argument like the following sample, 2007/5/10 kato-k + # e.g. + # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...) # - #TODO: support more flexible description in block, 2007/5/10 kato-k + # TODO: should support more flexible description in a block, 2007/5/10 kato-k ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do |b| # message body @@ -30,18 +31,18 @@ b.hoge1 = "hoge1" b[:hoge2] = "hoge2" - #b.hoge3 "hoge3" # not support + b.hoge3 "hoge3" # this pattern is possible, but unrecommend b.id = 1 # method "id" is also available. - #TODO support ActiveRecord object, 2007/5/11 kato-k + # TODO: should support ActiveRecord object, 2007/5/11 kato-k b.order = @order #? # message header - b.headers[:target_url] = "http://..." + b.headers[:target_url] = "http://localhost:3000/async_world/execute_via_http" b.headers[:priority] = 2 - b.headers[:druby_url] = "druby://..." + b.headers[:druby_url] = "druby://:6438" - #TODO support http headers, 2007/5/11 kato-k + # TODO: should support http headers, 2007/5/11 kato-k #b.http_headers[:accept] = "text/plain" #b.http_headers["content-type"] = "application/json" #b.headers[:http_header_accept] = "text/plain" @@ -53,12 +54,12 @@ req[:_array] = [0, 1, 2] - #TODO support various request formats such as xml and json, 2007/5/11 kato-k + # TODO: should support various request formats such as xml and json, 2007/5/11 kato-k #b.queue_message = @order, :include => :details, :format => :json #b.queue_message = @order, :include => :details, :format => :xml - # contens of message are referable + # contents of message are referable p b.queue_name p b.queue_message p b.queue_headers Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-11 10:42:53 UTC (rev 170) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-14 05:27:42 UTC (rev 171) @@ -13,19 +13,27 @@ attr_accessor :queue_name, :queue_message, :queue_headers - def method_missing name, *args - if name.to_s == "[]=" + # +Ap4r::Client#async_to+ method has block argument and message header and body and so on + # are defined in a block. + # This +method_missing+ is for picking up defined parameters in a block.. + def method_missing(method_name, *args) + if method_name == :[]= @queue_message[args[0]] = args[1] - elsif name.to_s == "headers" + elsif method_name == :headers return @queue_headers - elsif name.to_s == "http_headers" + elsif method_name == :http_headers #TODO implementation, 2007/5/11 kato-k return {} else - # remove "=" - @queue_message[name.to_s.chop] = args[0] + @queue_message[remove_equal_mark_from(method_name)] = args[0] end end + private + def remove_equal_mark_from symbol + return symbol unless /=$/ =~ symbol.to_s + return symbol.to_s.chop.to_sym + end + end end From kato-k at rubyforge.org Mon May 14 02:15:44 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 14 May 2007 02:15:44 -0400 (EDT) Subject: [ap4r-devel] [172] trunk/samples/HelloWorld/vendor/plugins/ap4r/lib: Implemented merge logic after yield proccessing. Message-ID: <20070514061544.BCD775240BD0@rubyforge.org> Revision: 172 Author: kato-k Date: 2007-05-14 02:15:44 -0400 (Mon, 14 May 2007) Log Message: ----------- Implemented merge logic after yield proccessing. Modified Paths: -------------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-14 05:27:42 UTC (rev 171) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-14 06:15:44 UTC (rev 172) @@ -127,12 +127,38 @@ # def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block) - queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options) + # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino + if logger.debug? + logger.debug("url_options: ") + logger.debug(url_options.inspect) + logger.debug("async_params: ") + logger.debug(async_params.inspect) + logger.debug("rm_options: ") + logger.debug(rm_options.inspect) + end + # TODO: clone it, 2006/10/16 shino + url_options ||= {} + url_options[:controller] ||= self.controller_path.gsub("/", ".") + rm_options = @@default_rm_options.merge(rm_options || {}) + + # Only async_params is not cloned. options and rm_options are cloned before now. + # This is a current contract between this class and converter classes. + converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self) + logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"} + + queue_name = __get_queue_name(url_options, rm_options) + queue_message = converter.make_params + queue_headers = converter.make_rm_options + if block_given? message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers) + yield message_builder - #TODO __after_block_evaluation, merge message_builder to queue_*, 2007/5/11 kato-k + + queue_name = message_builder.queue_name + queue_message = queue_message.merge(message_builder.queue_message) + queue_headers = queue_headers.merge(message_builder.queue_headers) end if Thread.current[:use_saf] @@ -152,30 +178,6 @@ end private - def __before_block_evaluation(url_options, async_params, rm_options) - # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino - if logger.debug? - logger.debug("url_options: ") - logger.debug(url_options.inspect) - logger.debug("async_params: ") - logger.debug(async_params.inspect) - logger.debug("rm_options: ") - logger.debug(rm_options.inspect) - end - - # TODO: clone it, 2006/10/16 shino - url_options ||= {} - url_options[:controller] ||= self.controller_path.gsub("/", ".") - rm_options = @@default_rm_options.merge(rm_options || {}) - - # Only async_params is not cloned. options and rm_options are cloned before now. - # This is a current contract between this class and converter classes. - converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self) - logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"} - - return __get_queue_name(url_options, rm_options), converter.make_params, converter.make_rm_options - end - def __queue_put(queue_name, queue_message, queue_headers) # TODO: can use a Queue instance repeatedly? 2007/05/02 by shino q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI) Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-14 05:27:42 UTC (rev 171) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-14 06:15:44 UTC (rev 172) @@ -3,6 +3,9 @@ # Licence:: MIT Licence module Ap4r + + # This class has +method_missing+. + # Scope of application should be limited ? class MessageBuilder def initialize(queue_name, queue_message, queue_headers) From shino at rubyforge.org Thu May 17 01:39:43 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 01:39:43 -0400 (EDT) Subject: [ap4r-devel] [173] trunk/ap4r/test/unit/dispatcher_base_spec.rb: Add a spec file for Ap4r::Dispatchers::Base#modify_message. Message-ID: <20070517053943.4C4B85240B1E@rubyforge.org> Revision: 173 Author: shino Date: 2007-05-17 01:39:41 -0400 (Thu, 17 May 2007) Log Message: ----------- Add a spec file for Ap4r::Dispatchers::Base#modify_message. Now it has rather trivial specs only. RSpec is 0.9.4 in my gem repository. Added Paths: ----------- trunk/ap4r/test/unit/dispatcher_base_spec.rb Added: trunk/ap4r/test/unit/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/test/unit/dispatcher_base_spec.rb (rev 0) +++ trunk/ap4r/test/unit/dispatcher_base_spec.rb 2007-05-17 05:39:41 UTC (rev 173) @@ -0,0 +1,25 @@ +require File.join(File.dirname(__FILE__), "../test_helper") + +require "reliable-msg" +require "ap4r/dispatcher" + +describe "Ap4r::Dispatchers::Base message modification with no configuration" do + before(:each) do + @headers = {:target_url => "http://www.sample.org:8888/aaa/bbb" } + @body = "body" + @message = ReliableMsg::Message.new(1, @headers.clone, @body.clone) + @conf = {} + @dispatcher = Ap4r::Dispatchers::Base.new(:message, @conf) + @dispatcher.modify_message + end + + it "should not change headers" do + @message.headers == @headers.should + end + + it "should not change body" do + @message.object.should == @body + end + + +end From shino at rubyforge.org Thu May 17 02:09:16 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 02:09:16 -0400 (EDT) Subject: [ap4r-devel] [174] trunk/ap4r: add test helper file Message-ID: <20070517060916.E182CA970002@rubyforge.org> Revision: 174 Author: shino Date: 2007-05-17 02:09:16 -0400 (Thu, 17 May 2007) Log Message: ----------- add test helper file Modified Paths: -------------- trunk/ap4r/Rakefile Added Paths: ----------- trunk/ap4r/test/test_helper.rb Modified: trunk/ap4r/Rakefile =================================================================== --- trunk/ap4r/Rakefile 2007-05-17 05:39:41 UTC (rev 173) +++ trunk/ap4r/Rakefile 2007-05-17 06:09:16 UTC (rev 174) @@ -94,6 +94,14 @@ rdoc.rdoc_files.include('rails_plugin/**/*.rb') } +# Test tasks ---------------------------------------------------------------- +require 'spec/rake/spectask' + +desc "Run unit specs" +Spec::Rake::SpecTask.new('unit_specs') do |t| + t.spec_files = FileList['spec/unit/**/*.rb'] +end + # AP4R release ---------------------------------------------------------------- desc "Make gem" Added: trunk/ap4r/test/test_helper.rb =================================================================== --- trunk/ap4r/test/test_helper.rb (rev 0) +++ trunk/ap4r/test/test_helper.rb 2007-05-17 06:09:16 UTC (rev 174) @@ -0,0 +1 @@ +$:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) From shino at rubyforge.org Thu May 17 02:13:18 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 02:13:18 -0400 (EDT) Subject: [ap4r-devel] [175] trunk/ap4r: change directory name, "test" to "spec" Message-ID: <20070517061318.17EAB5240AD3@rubyforge.org> Revision: 175 Author: shino Date: 2007-05-17 02:13:17 -0400 (Thu, 17 May 2007) Log Message: ----------- change directory name, "test" to "spec" Added Paths: ----------- trunk/ap4r/spec/ trunk/ap4r/spec/test_helper.rb trunk/ap4r/spec/unit/ Removed Paths: ------------- trunk/ap4r/spec/unit/ trunk/ap4r/test/ Copied: trunk/ap4r/spec (from rev 172, trunk/ap4r/test) Copied: trunk/ap4r/spec/test_helper.rb (from rev 174, trunk/ap4r/test/test_helper.rb) =================================================================== --- trunk/ap4r/spec/test_helper.rb (rev 0) +++ trunk/ap4r/spec/test_helper.rb 2007-05-17 06:13:17 UTC (rev 175) @@ -0,0 +1 @@ +$:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) Copied: trunk/ap4r/spec/unit (from rev 174, trunk/ap4r/test/unit) From shino at rubyforge.org Thu May 17 02:13:55 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 02:13:55 -0400 (EDT) Subject: [ap4r-devel] [176] trunk/ap4r/spec: change file name, "test_helper" to "spec_helper" Message-ID: <20070517061355.580855240AD3@rubyforge.org> Revision: 176 Author: shino Date: 2007-05-17 02:13:54 -0400 (Thu, 17 May 2007) Log Message: ----------- change file name, "test_helper" to "spec_helper" Added Paths: ----------- trunk/ap4r/spec/spec_helper.rb Removed Paths: ------------- trunk/ap4r/spec/test_helper.rb Copied: trunk/ap4r/spec/spec_helper.rb (from rev 175, trunk/ap4r/spec/test_helper.rb) =================================================================== --- trunk/ap4r/spec/spec_helper.rb (rev 0) +++ trunk/ap4r/spec/spec_helper.rb 2007-05-17 06:13:54 UTC (rev 176) @@ -0,0 +1 @@ +$:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) Deleted: trunk/ap4r/spec/test_helper.rb =================================================================== --- trunk/ap4r/spec/test_helper.rb 2007-05-17 06:13:17 UTC (rev 175) +++ trunk/ap4r/spec/test_helper.rb 2007-05-17 06:13:54 UTC (rev 176) @@ -1 +0,0 @@ -$:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) From shino at rubyforge.org Thu May 17 02:18:20 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 02:18:20 -0400 (EDT) Subject: [ap4r-devel] [177] trunk/ap4r/spec: change direcotry name, "unit" to "local". Message-ID: <20070517061820.605DC5240B21@rubyforge.org> Revision: 177 Author: shino Date: 2007-05-17 02:18:19 -0400 (Thu, 17 May 2007) Log Message: ----------- change direcotry name, "unit" to "local". I intend specs in this dir run in one process. And other sibling dirs like "with_reliable_msg" or "with_rails", etc. will be born. Added Paths: ----------- trunk/ap4r/spec/local/ Removed Paths: ------------- trunk/ap4r/spec/unit/ Copied: trunk/ap4r/spec/local (from rev 175, trunk/ap4r/spec/unit) From shino at rubyforge.org Thu May 17 02:20:01 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 02:20:01 -0400 (EDT) Subject: [ap4r-devel] [178] trunk/ap4r/spec/local/dispatcher_base_spec.rb: modification associated with renaming. Message-ID: <20070517062001.8F48B5240AD3@rubyforge.org> Revision: 178 Author: shino Date: 2007-05-17 02:20:01 -0400 (Thu, 17 May 2007) Log Message: ----------- modification associated with renaming. Modified Paths: -------------- trunk/ap4r/spec/local/dispatcher_base_spec.rb Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 06:18:19 UTC (rev 177) +++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 06:20:01 UTC (rev 178) @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), "../test_helper") +require File.join(File.dirname(__FILE__), "../spec_helper") require "reliable-msg" require "ap4r/dispatcher" From shino at rubyforge.org Thu May 17 02:22:58 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 02:22:58 -0400 (EDT) Subject: [ap4r-devel] [179] trunk/ap4r/Rakefile: made rake task for specs on local Message-ID: <20070517062258.343B35240ACC@rubyforge.org> Revision: 179 Author: shino Date: 2007-05-17 02:22:57 -0400 (Thu, 17 May 2007) Log Message: ----------- made rake task for specs on local Modified Paths: -------------- trunk/ap4r/Rakefile Modified: trunk/ap4r/Rakefile =================================================================== --- trunk/ap4r/Rakefile 2007-05-17 06:20:01 UTC (rev 178) +++ trunk/ap4r/Rakefile 2007-05-17 06:22:57 UTC (rev 179) @@ -98,8 +98,10 @@ require 'spec/rake/spectask' desc "Run unit specs" -Spec::Rake::SpecTask.new('unit_specs') do |t| - t.spec_files = FileList['spec/unit/**/*.rb'] +namespace :spec do + Spec::Rake::SpecTask.new(:local) do |t| + t.spec_files = FileList['spec/local/**/*.rb'] + end end # AP4R release ---------------------------------------------------------------- From shino at rubyforge.org Thu May 17 03:53:31 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 03:53:31 -0400 (EDT) Subject: [ap4r-devel] [180] trunk/ap4r: add some specs associated with url rewrite Message-ID: <20070517075331.4A6525240A96@rubyforge.org> Revision: 180 Author: shino Date: 2007-05-17 03:53:30 -0400 (Thu, 17 May 2007) Log Message: ----------- add some specs associated with url rewrite Modified Paths: -------------- trunk/ap4r/Rakefile trunk/ap4r/spec/local/dispatcher_base_spec.rb Modified: trunk/ap4r/Rakefile =================================================================== --- trunk/ap4r/Rakefile 2007-05-17 06:22:57 UTC (rev 179) +++ trunk/ap4r/Rakefile 2007-05-17 07:53:30 UTC (rev 180) @@ -97,8 +97,8 @@ # Test tasks ---------------------------------------------------------------- require 'spec/rake/spectask' -desc "Run unit specs" namespace :spec do + desc "Run specs running in only one process" Spec::Rake::SpecTask.new(:local) do |t| t.spec_files = FileList['spec/local/**/*.rb'] end Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 06:22:57 UTC (rev 179) +++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 07:53:30 UTC (rev 180) @@ -3,13 +3,13 @@ require "reliable-msg" require "ap4r/dispatcher" -describe "Ap4r::Dispatchers::Base message modification with no configuration" do +describe Ap4r::Dispatchers::Base, " message modification with no configuration" do before(:each) do @headers = {:target_url => "http://www.sample.org:8888/aaa/bbb" } @body = "body" @message = ReliableMsg::Message.new(1, @headers.clone, @body.clone) @conf = {} - @dispatcher = Ap4r::Dispatchers::Base.new(:message, @conf) + @dispatcher = Ap4r::Dispatchers::Base.new(@message, @conf) @dispatcher.modify_message end @@ -21,5 +21,29 @@ @message.object.should == @body end - end + +describe Ap4r::Dispatchers::Base, " message modification with url rewrite" do + before(:each) do + @headers = {:target_url => "http://www.sample.org:8888/aaa/bbb" } + @body = "body" + @message = ReliableMsg::Message.new(1, @headers.clone, @body.clone) + @conf = {"modify_rules" => {"url" => "proc{|url| url.port = url.port + 11}" }} + @dispatcher = Ap4r::Dispatchers::Base.new(@message, @conf) + @dispatcher.modify_message + end + + it "should not change headers except :target_url" do + @message.headers[:target_url] = @headers[:target_url] + @message.headers.should == @headers + end + + it "should change :target_url as ruled" do + @message.headers[:target_url].should == "http://www.sample.org:8899/aaa/bbb" + end + + it "should not change body" do + @message.object.should == @body + end + +end From shino at rubyforge.org Thu May 17 03:54:22 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 03:54:22 -0400 (EDT) Subject: [ap4r-devel] [181] trunk/ap4r/ap4r-devel-test.txt: remove a file to test ap4r-devel mailing list Message-ID: <20070517075422.229D25240A96@rubyforge.org> Revision: 181 Author: shino Date: 2007-05-17 03:54:21 -0400 (Thu, 17 May 2007) Log Message: ----------- remove a file to test ap4r-devel mailing list Removed Paths: ------------- trunk/ap4r/ap4r-devel-test.txt Deleted: trunk/ap4r/ap4r-devel-test.txt =================================================================== --- trunk/ap4r/ap4r-devel-test.txt 2007-05-17 07:53:30 UTC (rev 180) +++ trunk/ap4r/ap4r-devel-test.txt 2007-05-17 07:54:21 UTC (rev 181) @@ -1,3 +0,0 @@ -test -test2 -test3 From shino at rubyforge.org Thu May 17 05:22:02 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 17 May 2007 05:22:02 -0400 (EDT) Subject: [ap4r-devel] [182] trunk/ap4r: add specs of validations of response Message-ID: <20070517092202.DFFE55240846@rubyforge.org> Revision: 182 Author: shino Date: 2007-05-17 05:22:01 -0400 (Thu, 17 May 2007) Log Message: ----------- add specs of validations of response Modified Paths: -------------- trunk/ap4r/lib/ap4r/dispatcher.rb trunk/ap4r/spec/local/dispatcher_base_spec.rb Modified: trunk/ap4r/lib/ap4r/dispatcher.rb =================================================================== --- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-17 07:54:21 UTC (rev 181) +++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-17 09:22:01 UTC (rev 182) @@ -133,7 +133,7 @@ # is mandatory and others are optional (no operations by default). # * +modify_message+ to preprocess a message, e.g. rewirte URL or discard message. # * +invoke+ to execute main logic, e.g. HTTP POST call. *mandatory* - # * +varidate_response+ to judge whether +invoke+ finished successfully. + # * +validate_response+ to judge whether +invoke+ finished successfully. # * +response+ to return the result of +invoke+ process. class Base @@ -154,7 +154,7 @@ self.modify_message logger.debug{"Ap4r::Dispatcher after modification\n#{@message.to_yaml}"} self.invoke - self.varidate_response + self.validate_response self.response end @@ -169,7 +169,7 @@ raise 'must be implemented in subclasses' end - def varidate_response + def validate_response # nop end @@ -212,15 +212,15 @@ @message.object) end - def varidate_response + def validate_response logger.debug{"response status [#{@response.code} #{@response.message}]"} - varidate_response_status(Net::HTTPOK) - varidate_response_body(/true/) + validate_response_status(Net::HTTPOK) + validate_response_body(/true/) end # Checks whether the response status is a kind of +status_kind+. # +status_kind+ should be one of Net::HTTPRespose's subclasses. - def varidate_response_status(status_kind) + def validate_response_status(status_kind) #TODO: make the difinition of success variable, 2006/10/13 shino unless @response.kind_of?(status_kind) error_message = "HTTP Response FAILURE, " + @@ -234,7 +234,7 @@ # Checks whether the response body includes +pattern+. # +pattern+ should be a regular expression. - def varidate_response_body(pattern) + def validate_response_body(pattern) unless @response.body =~ pattern error_message = "HTTP Response FAILURE, status" + " [#{@response.code} #{@response.message}], body [#{@response.body}]" @@ -257,7 +257,7 @@ @success, @response = client.call2(@message[:target_action], @message.object) end - def varidate_response + def validate_response raise @response unless @success end end Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 07:54:21 UTC (rev 181) +++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 09:22:01 UTC (rev 182) @@ -3,6 +3,14 @@ require "reliable-msg" require "ap4r/dispatcher" +class Ap4r::ResponseMock + attr_accessor :body +end + +class Ap4r::Dispatchers::Base + attr_accessor :response +end + describe Ap4r::Dispatchers::Base, " message modification with no configuration" do before(:each) do @headers = {:target_url => "http://www.sample.org:8888/aaa/bbb" } @@ -47,3 +55,58 @@ end end + +describe Ap4r::Dispatchers::Http, " validation of response status" do + before(:each) do + @message = nil + @conf = nil + @dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf) + end + + it "should accept 200 status" do + @dispatcher.response = Net::HTTPOK.new(nil, 200, nil) + proc{ @dispatcher.validate_response_status(Net::HTTPOK) }.should_not raise_error + end + + it "should repel 201 status" do + @dispatcher.response = Net::HTTPCreated.new(nil, 201, nil) + proc{ @dispatcher.validate_response_status(Net::HTTPOK) }.should raise_error + end + + it "should repel 301 status" do + @dispatcher.response = Net::HTTPMovedPermanently.new(nil, 301, nil) + proc{ @dispatcher.validate_response_status(Net::HTTPOK) }.should raise_error + end + +end + +describe Ap4r::Dispatchers::Http, " validation of response body" do + before(:each) do + @message = nil + @conf = nil + @dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf) + @response = Ap4r::ResponseMock.new + @dispatcher.response = @response + end + + it 'should accept just text "true"' do + @response.body = "true" + proc{ @dispatcher.validate_response_body(/true/) }.should_not raise_error + end + + it 'should accept text including "true"' do + @response.body = "first line is not important\nsome words true and more\nand also third line is useless." + proc{ @dispatcher.validate_response_body(/true/) }.should_not raise_error + end + + it 'should repel empty text' do + @response.body = "" + proc{ @dispatcher.validate_response_body(/true/) }.should raise_error + end + + it 'should repel long text without "true"' do + @response.body = "first line is not important\nsome words, more and more\nand also third line is useless." + proc{ @dispatcher.validate_response_body(/true/) }.should raise_error + end + +end From shino at rubyforge.org Fri May 18 01:47:57 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Fri, 18 May 2007 01:47:57 -0400 (EDT) Subject: [ap4r-devel] [183] trunk/ap4r/spec/local/dispatcher_base_spec.rb: test spec failure Message-ID: <20070518054757.396DB5240B5E@rubyforge.org> Revision: 183 Author: shino Date: 2007-05-18 01:47:56 -0400 (Fri, 18 May 2007) Log Message: ----------- test spec failure Modified Paths: -------------- trunk/ap4r/spec/local/dispatcher_base_spec.rb Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 09:22:01 UTC (rev 182) +++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-18 05:47:56 UTC (rev 183) @@ -110,3 +110,9 @@ end end + +describe "test for spec failuer" do + it "should fail" do + 1.should == 0 + end +end From shino at rubyforge.org Fri May 18 02:23:28 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Fri, 18 May 2007 02:23:28 -0400 (EDT) Subject: [ap4r-devel] [184] trunk/ap4r/spec/local/dispatcher_base_spec.rb: remove a spec to emulate build failure Message-ID: <20070518062328.4FD125240B6C@rubyforge.org> Revision: 184 Author: shino Date: 2007-05-18 02:23:27 -0400 (Fri, 18 May 2007) Log Message: ----------- remove a spec to emulate build failure Modified Paths: -------------- trunk/ap4r/spec/local/dispatcher_base_spec.rb Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-18 05:47:56 UTC (rev 183) +++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-18 06:23:27 UTC (rev 184) @@ -110,9 +110,3 @@ end end - -describe "test for spec failuer" do - it "should fail" do - 1.should == 0 - end -end From kato-k at rubyforge.org Fri May 18 06:16:19 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 18 May 2007 06:16:19 -0400 (EDT) Subject: [ap4r-devel] [185] trunk: Support block argument for async_to method.\n Support ActiveRecord object for async parameter. Message-ID: <20070518101619.2A6545240AB4@rubyforge.org> Revision: 185 Author: kato-k Date: 2007-05-18 06:16:17 -0400 (Fri, 18 May 2007) Log Message: ----------- Support block argument for async_to method.\n Support ActiveRecord object for async parameter. \n Support xml over http protocol. Modified Paths: -------------- trunk/ap4r/lib/ap4r/dispatcher.rb trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb Modified: trunk/ap4r/lib/ap4r/dispatcher.rb =================================================================== --- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-18 06:23:27 UTC (rev 184) +++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-18 10:16:17 UTC (rev 185) @@ -208,10 +208,25 @@ # TODO: should be added some request headers 2006/10/12 shino # e.g. X-Ap4r-Version, Accept(need it?) # TODO: Now supports POST only, 2006/10/12 shino - @response = Net::HTTP.post_form(URI.parse(@message[:target_url]), - @message.object) + @response = nil + uri = URI.parse(@message[:target_url]) + headers = make_header + + Net::HTTP.start(uri.host, uri.port) do |http| + @response, = http.post(uri.path, @message.object, headers) + end end + def make_header + headers = { } + @message.headers.map do |k,v| + s = StringScanner.new(k.to_s) + s.scan(/\Ahttp_header_/) + headers[s.post_match] = v if s.post_match + end + headers + end + def validate_response logger.debug{"response status [#{@response.code} #{@response.message}]"} validate_response_status(Net::HTTPOK) Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-18 06:23:27 UTC (rev 184) +++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-18 10:16:17 UTC (rev 185) @@ -19,51 +19,32 @@ def execute_with_block write('Hello') - # TODO: should change first argument like the following sample, 2007/5/10 kato-k - # e.g. - # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...) - # - # TODO: should support more flexible description in a block, 2007/5/10 kato-k - ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do |b| + ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}) do - # message body - # basically, use block argumennt - b.hoge1 = "hoge1" - b[:hoge2] = "hoge2" + # basic + #body :hoge, "hoge" + #header :priority, 2 - b.hoge3 "hoge3" # this pattern is possible, but unrecommend - b.id = 1 # method "id" is also available. + # AR object + #body :sm, Ap4r::StoredMessage.find(:first), :except => :id - # TODO: should support ActiveRecord object, 2007/5/11 kato-k - b.order = @order #? + # by xml/http + body :hoge, "hoge" + body :sm, Ap4r::StoredMessage.find(:first), :except => :id + format :xml - # message header - b.headers[:target_url] = "http://localhost:3000/async_world/execute_via_http" - b.headers[:priority] = 2 - b.headers[:druby_url] = "druby://:6438" + # ..or explicit setting for http header + #body :hoge, "hoge" + #body :sm, Ap4r::StoredMessage.find(:first), :except => :id + #http_header "Content-type", "application/x-xml" - # TODO: should support http headers, 2007/5/11 kato-k - #b.http_headers[:accept] = "text/plain" - #b.http_headers["content-type"] = "application/json" - #b.headers[:http_header_accept] = "text/plain" + # directly dealing with xml message + #body_as_xml Ap4r::StoredMessage.find(:first).to_xml(:except => :id) - #tricky pattern, but definition in method arguments is necessary. - req[:_num] = rand(100) - req[:_str] = "World" - req[:_hash] = {:a => 1, :b => 2} - req[:_array] = [0, 1, 2] - - - # TODO: should support various request formats such as xml and json, 2007/5/11 kato-k - #b.queue_message = @order, :include => :details, :format => :json - #b.queue_message = @order, :include => :details, :format => :xml - - - # contents of message are referable - p b.queue_name - p b.queue_message - p b.queue_headers - + # TODO: referable, but should change longer and unique name?, 2007/5/17 kato-k + # p @queue_name + # p @queue_message + # p @queue_headers end render :nothing => true Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-18 06:23:27 UTC (rev 184) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-18 10:16:17 UTC (rev 185) @@ -19,9 +19,5 @@ alias :async_to :async_dispatch alias :transaction :transaction_with_saf - def message - @message ||= {} - end - end end Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-18 06:23:27 UTC (rev 184) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-18 10:16:17 UTC (rev 185) @@ -125,7 +125,7 @@ # Object of argumemts (async_params, options and rm_options) will not be modified. # Implementors (of this class and converters) should not modify them. # - def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block) + def async_dispatch(url_options = {}, async_params = {}, rm_options = {}, &block) # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino if logger.debug? @@ -151,30 +151,28 @@ queue_message = converter.make_params queue_headers = converter.make_rm_options + message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers) if block_given? - message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers) - - yield message_builder - - queue_name = message_builder.queue_name - queue_message = queue_message.merge(message_builder.queue_message) - queue_headers = queue_headers.merge(message_builder.queue_headers) + message_builder.instance_eval(&block) end + queue_name = message_builder.queue_name + formatted_queue_message = message_builder.format_queue_message + queue_headers = message_builder.queue_headers if Thread.current[:use_saf] - stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers) + stored_message = ::Ap4r::StoredMessage.store(queue_name, formatted_queue_message, queue_headers) Thread.current[:stored_messages].store( stored_message.id, { - :queue_message => queue_message, + :queue_message => formatted_queue_message, :queue_name => queue_name, :queue_headers => queue_headers } ) return stored_message.id end - __queue_put(queue_name, queue_message, queue_headers) + __queue_put(queue_name, formatted_queue_message, queue_headers) end private Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-18 06:23:27 UTC (rev 184) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-18 10:16:17 UTC (rev 185) @@ -2,41 +2,112 @@ # Copyright:: Copyright (c) 2007 Future Architect Inc. # Licence:: MIT Licence +require 'active_record' + module Ap4r - # This class has +method_missing+. - # Scope of application should be limited ? class MessageBuilder def initialize(queue_name, queue_message, queue_headers) @queue_name = queue_name @queue_message = queue_message @queue_headers = queue_headers + @format = :urlencode + @xml_encoded_body = nil + @to_xml_options = {:root => "root"} end attr_accessor :queue_name, :queue_message, :queue_headers + attr_reader :xml_encoded_body, :format, :to_xml_options - # +Ap4r::Client#async_to+ method has block argument and message header and body and so on - # are defined in a block. - # This +method_missing+ is for picking up defined parameters in a block.. - def method_missing(method_name, *args) - if method_name == :[]= - @queue_message[args[0]] = args[1] - elsif method_name == :headers - return @queue_headers - elsif method_name == :http_headers - #TODO implementation, 2007/5/11 kato-k - return {} + def body(k, v, options = { }) + k ||= v.class + if v.kind_of? ActiveRecord::Base + @queue_message[k.to_sym] = v.attributes + @to_xml_options = @to_xml_options.merge(options) else - @queue_message[remove_equal_mark_from(method_name)] = args[0] + @queue_message[k.to_sym] = v end + end + def body_as_xml(xml_message) + @xml_encoded_body = xml_message + end + + def body_as_text(text_message) + # TODO: implementation + end + + def body_as_yaml(yaml_message) + # TODO: implementation + end + + def body_as_json(json_message) + # TODO: implementation + end + + def header(k, v) + @queue_headers[k.to_sym] = v + end + + def http_header(k, v) + @queue_headers["http_header_#{k}".to_sym] = v + end + + def format(v) + case @format = v + when :xml + http_header('Content-type', 'application/x-xml') + else + http_header('Content-type', 'application/x-www-form-urlencoded') + end + end + + def format_queue_message + return @xml_encoded_body if @xml_encoded_body + + case @format + when :xml + return @queue_message.to_xml @to_xml_options + else + return query_string(@queue_message) + end + end + + def query_string(hash) + build_query_string(hash, nil, nil) + end + private - def remove_equal_mark_from symbol - return symbol unless /=$/ =~ symbol.to_s - return symbol.to_s.chop.to_sym + def build_query_string(hash, query = nil, top = nil) + query ||= [] + top ||= "" + + _top = top.dup + + hash.each do |k,v| + top = _top + top += top == "" ? "#{urlencode(k.to_s)}" : "[#{urlencode(k.to_s)}]" + if v.kind_of? Hash + build_query_string(v, query, top) + elsif v.kind_of? Array + v.each do |e| + query << "#{top}[]=#{urlencode(e.to_s)}" + end + else + query << "#{top}=#{urlencode(v.to_s)}" + end + end + query.join('&') end + def simple_url_encoded_form_data params, sep = '&' + params.map {|k,v| "#{urlencode(k.to_s)}=#{urlencode(v.to_s)}" }.join(sep) + end + + def urlencode(str) + str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0]) } + end end end From shino at rubyforge.org Mon May 21 01:01:43 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 21 May 2007 01:01:43 -0400 (EDT) Subject: [ap4r-devel] [186] trunk/ap4r/spec/local/dispatcher_base_spec.rb: Fix typo. Message-ID: <20070521050143.D18695240C9B@rubyforge.org> Revision: 186 Author: shino Date: 2007-05-21 01:01:43 -0400 (Mon, 21 May 2007) Log Message: ----------- Fix typo. Mock is NOT stub Modified Paths: -------------- trunk/ap4r/spec/local/dispatcher_base_spec.rb Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-18 10:16:17 UTC (rev 185) +++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-21 05:01:43 UTC (rev 186) @@ -3,7 +3,7 @@ require "reliable-msg" require "ap4r/dispatcher" -class Ap4r::ResponseMock +class Ap4r::ResponseStub attr_accessor :body end @@ -85,7 +85,7 @@ @message = nil @conf = nil @dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf) - @response = Ap4r::ResponseMock.new + @response = Ap4r::ResponseStub.new @dispatcher.response = @response end From shino at rubyforge.org Mon May 21 02:16:22 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 21 May 2007 02:16:22 -0400 (EDT) Subject: [ap4r-devel] [187] trunk/ap4r/Rakefile: add rake task to execute RSpec with Rcov Message-ID: <20070521061622.B93085240C9D@rubyforge.org> Revision: 187 Author: shino Date: 2007-05-21 02:16:21 -0400 (Mon, 21 May 2007) Log Message: ----------- add rake task to execute RSpec with Rcov Modified Paths: -------------- trunk/ap4r/Rakefile Modified: trunk/ap4r/Rakefile =================================================================== --- trunk/ap4r/Rakefile 2007-05-21 05:01:43 UTC (rev 186) +++ trunk/ap4r/Rakefile 2007-05-21 06:16:21 UTC (rev 187) @@ -94,13 +94,28 @@ rdoc.rdoc_files.include('rails_plugin/**/*.rb') } -# Test tasks ---------------------------------------------------------------- +# Spec tasks ---------------------------------------------------------------- require 'spec/rake/spectask' namespace :spec do - desc "Run specs running in only one process" - Spec::Rake::SpecTask.new(:local) do |t| - t.spec_files = FileList['spec/local/**/*.rb'] + %w(local).each do |flavor| + desc "Run #{flavor} examples" + Spec::Rake::SpecTask.new(flavor) do |t| + t.spec_files = FileList["spec/#{flavor}/**/*.rb"] + end + + namespace :coverage do + desc "Run #{flavor} examples with RCov" + Spec::Rake::SpecTask.new(flavor) do |t| + t.spec_files = FileList["spec/#{flavor}/**/*.rb"] + t.rcov = true + excludes = %w(^spec\/) + if ENV['GEM_HOME'] + excludes << Regexp.escape(ENV['GEM_HOME']) + end + t.rcov_opts = ["--exclude" , excludes.join(",")] + end + end end end From kato-k at rubyforge.org Mon May 21 04:58:08 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 21 May 2007 04:58:08 -0400 (EDT) Subject: [ap4r-devel] [188] trunk/samples/HelloWorld/vendor/plugins/ap4r/lib: Refactoring: changed meshods name and add comments. Message-ID: <20070521085808.62AD652409B4@rubyforge.org> Revision: 188 Author: kato-k Date: 2007-05-21 04:58:07 -0400 (Mon, 21 May 2007) Log Message: ----------- Refactoring: changed meshods name and add comments. Modified Paths: -------------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-21 06:16:21 UTC (rev 187) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-21 08:58:07 UTC (rev 188) @@ -156,23 +156,23 @@ message_builder.instance_eval(&block) end queue_name = message_builder.queue_name - formatted_queue_message = message_builder.format_queue_message - queue_headers = message_builder.queue_headers + queue_message = message_builder.format_message_body + queue_headers = message_builder.message_headers if Thread.current[:use_saf] - stored_message = ::Ap4r::StoredMessage.store(queue_name, formatted_queue_message, queue_headers) + stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers) Thread.current[:stored_messages].store( stored_message.id, { - :queue_message => formatted_queue_message, + :queue_message => queue_message, :queue_name => queue_name, :queue_headers => queue_headers } ) return stored_message.id end - __queue_put(queue_name, formatted_queue_message, queue_headers) + __queue_put(queue_name, queue_message, queue_headers) end private Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-21 06:16:21 UTC (rev 187) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-21 08:58:07 UTC (rev 188) @@ -6,72 +6,99 @@ module Ap4r + # This +MessageBuilder+ is the class for formatting message body. + # Current support formats are text, xml, json and yaml, + # and the formatted messages are sent over HTTP. + # + # Using +format+ method, this class automatically changes the format of + # the given message body and adds appropriate +Content-type+ to http header. + # Or using +body_as_*+ methods, you can directly assign formatted message body. class MessageBuilder def initialize(queue_name, queue_message, queue_headers) @queue_name = queue_name - @queue_message = queue_message - @queue_headers = queue_headers - @format = :urlencode - @xml_encoded_body = nil + @message_body = queue_message + @message_headers = queue_headers + @format = nil + @message_body_with_format = nil @to_xml_options = {:root => "root"} end - attr_accessor :queue_name, :queue_message, :queue_headers - attr_reader :xml_encoded_body, :format, :to_xml_options + attr_accessor :queue_name, :message_body, :message_headers + attr_reader :format, :to_xml_options def body(k, v, options = { }) k ||= v.class if v.kind_of? ActiveRecord::Base - @queue_message[k.to_sym] = v.attributes + @message_body[k.to_sym] = v @to_xml_options = @to_xml_options.merge(options) else - @queue_message[k.to_sym] = v + @message_body[k.to_sym] = v end - end - def body_as_xml(xml_message) - @xml_encoded_body = xml_message + def header(k, v) + @message_headers[k.to_sym] = v end - def body_as_text(text_message) - # TODO: implementation + def http_header(k, v) + @message_headers["http_header_#{k}".to_sym] = v end - def body_as_yaml(yaml_message) - # TODO: implementation + def format(v) + case @format = v + when :text + set_content_type("text/plain") + when :xml + set_content_type("text/xml application/x-xml") + when :json + set_content_type("application/json") + when :yaml + set_content_type("text/plain text/yaml") + else + set_content_type("application/x-www-form-urlencoded") + end end - def body_as_json(json_message) - # TODO: implementation + def body_as_text(text) + @message_body_with_format = text + format :text end - def header(k, v) - @queue_headers[k.to_sym] = v + def body_as_xml(xml) + @message_body_with_format = xml + format :xml end - def http_header(k, v) - @queue_headers["http_header_#{k}".to_sym] = v + def body_as_json(json) + @message_body_with_format = json + format :json end - def format(v) - case @format = v - when :xml - http_header('Content-type', 'application/x-xml') - else - http_header('Content-type', 'application/x-www-form-urlencoded') - end + def body_as_yaml(yaml) + @message_body_with_format = yaml + format :yaml end - def format_queue_message - return @xml_encoded_body if @xml_encoded_body + def format_message_body + return @message_body_with_format if @message_body_with_format case @format + when :text + return @message_budy.to_s when :xml - return @queue_message.to_xml @to_xml_options + return @message_body.to_xml @to_xml_options + when :json + return @message_body.to_json + when :yaml + return @message_body.to_yaml else - return query_string(@queue_message) + @message_body.each do |k,v| + if v.kind_of? ActiveRecord::Base + @message_body[k] = v.attributes + end + end + return query_string(@message_body) end end @@ -102,12 +129,16 @@ query.join('&') end - def simple_url_encoded_form_data params, sep = '&' + def simple_url_encoded_form_data(params, sep = '&') params.map {|k,v| "#{urlencode(k.to_s)}=#{urlencode(v.to_s)}" }.join(sep) end def urlencode(str) str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0]) } end + + def set_content_type(type) + http_header("Content-type", type) + end end end From shino at rubyforge.org Tue May 22 03:25:38 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 22 May 2007 03:25:38 -0400 (EDT) Subject: [ap4r-devel] [189] trunk/ap4r: add code statistics task Message-ID: <20070522072538.B87F85240CB3@rubyforge.org> Revision: 189 Author: shino Date: 2007-05-22 03:25:38 -0400 (Tue, 22 May 2007) Log Message: ----------- add code statistics task Modified Paths: -------------- trunk/ap4r/Rakefile Removed Paths: ------------- trunk/ap4r/lib/ap4r/util/loc.rb Modified: trunk/ap4r/Rakefile =================================================================== --- trunk/ap4r/Rakefile 2007-05-21 08:58:07 UTC (rev 188) +++ trunk/ap4r/Rakefile 2007-05-22 07:25:38 UTC (rev 189) @@ -113,7 +113,8 @@ if ENV['GEM_HOME'] excludes << Regexp.escape(ENV['GEM_HOME']) end - t.rcov_opts = ["--exclude" , excludes.join(",")] + t.rcov_opts = ["--exclude" , excludes.join(","), + "--text-summary"] end end end @@ -182,3 +183,18 @@ } end +# AP4R misc tools ---------------------------------------------------------------- + +desc "display code statistics" +task :stats do + require 'rubygems' + require 'active_support' + require 'code_statistics' + CodeStatistics::TEST_TYPES.concat(["Local specs"]) + CodeStatistics.new( + ["Core Sources", "lib"], + ["Rails plugin", "rails_plugin"], + ["Scripts", "script"], + ["Local specs", "spec/local"] + ).to_s +end Deleted: trunk/ap4r/lib/ap4r/util/loc.rb =================================================================== --- trunk/ap4r/lib/ap4r/util/loc.rb 2007-05-21 08:58:07 UTC (rev 188) +++ trunk/ap4r/lib/ap4r/util/loc.rb 2007-05-22 07:25:38 UTC (rev 189) @@ -1,13 +0,0 @@ -# Author:: Shunichi Shinohara -# Copyright:: Copyright (c) 2007 Future Architect Inc. -# Licence:: MIT Licence - -require 'rubygems' -require 'active_support' -require 'code_statistics' - -CodeStatistics.new( - ["Core Sources", "lib"], - ["Rails plugin", "rails_plugin"], - ["Scripts", "script"] -).to_s From shino at rubyforge.org Tue May 22 04:25:47 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 22 May 2007 04:25:47 -0400 (EDT) Subject: [ap4r-devel] [190] trunk/ap4r/spec/local/dispatcher_base_spec.rb: refactoring: change stub into mock provided by RSpec Message-ID: <20070522082548.395B55240CB5@rubyforge.org> Revision: 190 Author: shino Date: 2007-05-22 04:25:46 -0400 (Tue, 22 May 2007) Log Message: ----------- refactoring: change stub into mock provided by RSpec Modified Paths: -------------- trunk/ap4r/spec/local/dispatcher_base_spec.rb Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-22 07:25:38 UTC (rev 189) +++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-22 08:25:46 UTC (rev 190) @@ -3,10 +3,6 @@ require "reliable-msg" require "ap4r/dispatcher" -class Ap4r::ResponseStub - attr_accessor :body -end - class Ap4r::Dispatchers::Base attr_accessor :response end @@ -85,27 +81,29 @@ @message = nil @conf = nil @dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf) - @response = Ap4r::ResponseStub.new + @response = mock("response") @dispatcher.response = @response end it 'should accept just text "true"' do - @response.body = "true" + @response.should_receive(:body).once.and_return("true") proc{ @dispatcher.validate_response_body(/true/) }.should_not raise_error end it 'should accept text including "true"' do - @response.body = "first line is not important\nsome words true and more\nand also third line is useless." + @response.should_receive(:body).and_return{ + "first line is not important\nsome words true and more\nand also third line is useless." } proc{ @dispatcher.validate_response_body(/true/) }.should_not raise_error end it 'should repel empty text' do - @response.body = "" + @response.should_receive(:body).and_return("") proc{ @dispatcher.validate_response_body(/true/) }.should raise_error end it 'should repel long text without "true"' do - @response.body = "first line is not important\nsome words, more and more\nand also third line is useless." + @response.should_receive(:body).and_return{ + "first line is not important\nsome words, more and more\nand also third line is useless." } proc{ @dispatcher.validate_response_body(/true/) }.should raise_error end From kato-k at rubyforge.org Tue May 22 04:40:55 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Tue, 22 May 2007 04:40:55 -0400 (EDT) Subject: [ap4r-devel] [191] trunk/samples/HelloWorld/vendor/plugins/ap4r/lib: Added comments about api usage. Message-ID: <20070522084055.2F9FE5240957@rubyforge.org> Revision: 191 Author: kato-k Date: 2007-05-22 04:40:54 -0400 (Tue, 22 May 2007) Log Message: ----------- Added comments about api usage. Modified Paths: -------------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-22 08:25:46 UTC (rev 190) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-22 08:40:54 UTC (rev 191) @@ -16,7 +16,10 @@ def_delegators :@controller, :logger, :url_for + # Alias for ::Ap4r::AsyncHelper::Base.async_dispatch alias :async_to :async_dispatch + + # Alias for ::Ap4r::AsyncHelper::Base.transaction_with_saf alias :transaction :transaction_with_saf end Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-22 08:25:46 UTC (rev 190) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-22 08:40:54 UTC (rev 191) @@ -125,6 +125,58 @@ # Object of argumemts (async_params, options and rm_options) will not be modified. # Implementors (of this class and converters) should not modify them. # + # Examples: the most simple + # + # async_dispatch({:controller => 'next_controller', :action => 'next_action'}, + # {:world_id => 1, :message => "World"}) + # + # + # Examples: taking block + # + # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do + # body :world_id, 1 + # body :message, "World" + # end + # + # + # Examples: transmitting ActiveRecord object + # + # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do + # body :world, World.find(1) + # body :message, "World" + # end + # + # + # Examples: transmitting with xml format over http (now support text, json and yaml format). + # + # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do + # body :world, World.find(1) + # body :message, "World" + # format :xml + # end + # + # + # Examples: direct assignment for formatted message body + # + # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do + # world = World.find(1).to_xml :except => ... + # body_as_xml world + # end + # + # + # Examples: setting message header + # + # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do + # body :world_id, 1 + # body :message, "World" + # + # header :priority, 1 + # http_header "Content-type", ... + # end + # + # + # This method is aliased as ::Ap4r::Client#async_to + # def async_dispatch(url_options = {}, async_params = {}, rm_options = {}, &block) # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino From shino at rubyforge.org Tue May 22 05:03:30 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 22 May 2007 05:03:30 -0400 (EDT) Subject: [ap4r-devel] [192] trunk/ap4r/spec/local/dispatcher_base_spec.rb: add specs as validation of HTTP response status Message-ID: <20070522090330.32FB75240990@rubyforge.org> Revision: 192 Author: shino Date: 2007-05-22 05:03:29 -0400 (Tue, 22 May 2007) Log Message: ----------- add specs as validation of HTTP response status Modified Paths: -------------- trunk/ap4r/spec/local/dispatcher_base_spec.rb Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb =================================================================== --- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-22 08:40:54 UTC (rev 191) +++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-22 09:03:29 UTC (rev 192) @@ -52,11 +52,9 @@ end -describe Ap4r::Dispatchers::Http, " validation of response status" do +describe Ap4r::Dispatchers::Http, " validation of response status as HTTP OK" do before(:each) do - @message = nil - @conf = nil - @dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf) + @dispatcher = Ap4r::Dispatchers::Http.new(@message = nil, @conf = nil) end it "should accept 200 status" do @@ -76,6 +74,28 @@ end +describe Ap4r::Dispatchers::Http, " validation of response status as 2xx" do + before(:each) do + @dispatcher = Ap4r::Dispatchers::Http.new(@message = nil, @conf = nil) + end + + it "should accept 200 status" do + @dispatcher.response = Net::HTTPOK.new(nil, 200, nil) + proc{ @dispatcher.validate_response_status(Net::HTTPSuccess) }.should_not raise_error + end + + it "should accept 201 status" do + @dispatcher.response = Net::HTTPCreated.new(nil, 201, nil) + proc{ @dispatcher.validate_response_status(Net::HTTPSuccess) }.should_not raise_error + end + + it "should repel 301 status" do + @dispatcher.response = Net::HTTPMovedPermanently.new(nil, 301, nil) + proc{ @dispatcher.validate_response_status(Net::HTTPSuccess) }.should raise_error + end + +end + describe Ap4r::Dispatchers::Http, " validation of response body" do before(:each) do @message = nil From shino at rubyforge.org Tue May 22 05:14:18 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 22 May 2007 05:14:18 -0400 (EDT) Subject: [ap4r-devel] [193] trunk/ap4r/spec/spec_helper.rb: add stub logic for coverage report Message-ID: <20070522091418.B87BD524097B@rubyforge.org> Revision: 193 Author: shino Date: 2007-05-22 05:14:18 -0400 (Tue, 22 May 2007) Log Message: ----------- add stub logic for coverage report Modified Paths: -------------- trunk/ap4r/spec/spec_helper.rb Modified: trunk/ap4r/spec/spec_helper.rb =================================================================== --- trunk/ap4r/spec/spec_helper.rb 2007-05-22 09:03:29 UTC (rev 192) +++ trunk/ap4r/spec/spec_helper.rb 2007-05-22 09:14:18 UTC (rev 193) @@ -1 +1,7 @@ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib")) + +# TODO: stub logic to take files with no specs in coverage report 2007/05/22 by shino +%w(carrier message_store_ext multi_queue + queue_manager_ext store_and_forward).each{|f| + require "ap4r/#{f}" +} From shino at rubyforge.org Mon May 28 04:55:51 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 04:55:51 -0400 (EDT) Subject: [ap4r-devel] [194] trunk/ap4r/lib/ap4r/dispatcher.rb: make sleep interval to class variable (ad-hoc) Message-ID: <20070528085551.71E0D5240AC4@rubyforge.org> Revision: 194 Author: shino Date: 2007-05-28 04:55:50 -0400 (Mon, 28 May 2007) Log Message: ----------- make sleep interval to class variable (ad-hoc) Modified Paths: -------------- trunk/ap4r/lib/ap4r/dispatcher.rb Modified: trunk/ap4r/lib/ap4r/dispatcher.rb =================================================================== --- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-22 09:14:18 UTC (rev 193) +++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-28 08:55:50 UTC (rev 194) @@ -21,6 +21,8 @@ # - calls a Dispatchers::Base's instance. class Dispatchers + @@sleep_inverval = 0.1 + @@logger = nil def self.logger @@logger @@ -102,7 +104,7 @@ logger.info{ "start dispatcher: targets= #{mq}, index= #{index})" } until Thread.current[:dying] # TODO: change sleep interval depending on last result? 2007/05/09 by shino - sleep 0.1 + sleep @@sleep_inverval # logger.debug{ "try dispatch #{mq} #{mq.name}" } # TODO: needs timeout?, 2006/10/16 shino begin From shino at rubyforge.org Mon May 28 04:56:46 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 04:56:46 -0400 (EDT) Subject: [ap4r-devel] [195] trunk/ap4r/lib/ap4r/mongrel.rb: remove warning message, because it's noisy Message-ID: <20070528085646.2FDA65240AEB@rubyforge.org> Revision: 195 Author: shino Date: 2007-05-28 04:56:45 -0400 (Mon, 28 May 2007) Log Message: ----------- remove warning message, because it's noisy Modified Paths: -------------- trunk/ap4r/lib/ap4r/mongrel.rb Modified: trunk/ap4r/lib/ap4r/mongrel.rb =================================================================== --- trunk/ap4r/lib/ap4r/mongrel.rb 2007-05-28 08:55:50 UTC (rev 194) +++ trunk/ap4r/lib/ap4r/mongrel.rb 2007-05-28 08:56:45 UTC (rev 195) @@ -47,7 +47,6 @@ # TODO not yet implemented 2007/04/09 by shino # class Ap4rHandler < ::Mongrel::HttpHandler - STDERR.puts "CAUTION! This script is rather experimental." attr_reader :files @@file_only_methods = ["GET","HEAD"] From shino at rubyforge.org Mon May 28 05:04:07 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 05:04:07 -0400 (EDT) Subject: [ap4r-devel] [196] trunk/samples/HelloWorld: second trial to make rails integration test with ap4r Message-ID: <20070528090407.355265240A9C@rubyforge.org> Revision: 196 Author: shino Date: 2007-05-28 05:04:06 -0400 (Mon, 28 May 2007) Log Message: ----------- second trial to make rails integration test with ap4r Added Paths: ----------- trunk/samples/HelloWorld/config/ap4r.yml.sample trunk/samples/HelloWorld/test/ap4r_test_helper.rb trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb Added: trunk/samples/HelloWorld/config/ap4r.yml.sample =================================================================== --- trunk/samples/HelloWorld/config/ap4r.yml.sample (rev 0) +++ trunk/samples/HelloWorld/config/ap4r.yml.sample 2007-05-28 09:04:06 UTC (rev 196) @@ -0,0 +1,10 @@ +--- +# need development? or production? +# or consider proper structure for these +development: + +test: + root_dir: ~/work/ap4r_project + config_file: config/queues_disk.cfg + +production: Added: trunk/samples/HelloWorld/test/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/ap4r_test_helper.rb (rev 0) +++ trunk/samples/HelloWorld/test/ap4r_test_helper.rb 2007-05-28 09:04:06 UTC (rev 196) @@ -0,0 +1,81 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'erb' +require 'yaml' +require 'reliable-msg' +require 'ap4r' + +class Ap4rTestHelper + + def initialize(config_file = RAILS_ROOT + "/config/ap4r.yml") + raise "please create config/ap4r.yml to configure ap4r service." unless File.exist?(config_file) + + config = {} + File.open(config_file, "r") do |input| + YAML.load_documents(ERB.new(input.read).result) do |doc| + config.merge! doc + end + end + @test_config = config["test"] + @root_dir = @test_config["root_dir"] + @config_file = @test_config["config_file"] + @test_server_config = ReliableMsg::Config.new(File.join(@root_dir, @config_file)) + raise "config file #{@test_server_config.path} NOT exist!" unless @test_server_config.exist? + @test_server_config.load_no_create + end + + # Starts ap4r service. + def start_service(wait_until_started = true) + + command = "ruby #{@test_config["start_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + + "start -d -c #{@root_dir} -A #{@config_file}" + print "executing command: #{command} ..." + system(command) + puts + + @qm = DRbObject.new