[ap4r-devel] [185] trunk: Support block argument for async_to method.\n Support ActiveRecord object for async parameter.
kato-k at rubyforge.org
kato-k at rubyforge.org
Fri May 18 06:16:19 EDT 2007
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
More information about the ap4r-devel
mailing list