actionservice 0.2.100 → 0.2.102

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,6 @@
1
1
  require 'xmlrpc/parser'
2
2
  require 'xmlrpc/utils'
3
+ require 'singleton'
3
4
 
4
5
  module ActionService
5
6
  module Protocol
@@ -10,86 +11,115 @@ module ActionService
10
11
  end
11
12
 
12
13
  class XmlRpcProtocol < AbstractProtocol
13
- include XMLRPC::ParserWriterChooseMixin
14
+ private
15
+ class Helper
16
+ include Singleton
17
+ include XMLRPC::ParserWriterChooseMixin
18
+
19
+ def get_parser
20
+ parser()
21
+ end
22
+
23
+ def get_create
24
+ create()
25
+ end
26
+ end
27
+
28
+ public
14
29
 
15
- def initialize(container_klass)
16
- @container_klass = container_klass
17
- @container_klass.write_inheritable_hash('default_system_exports', XmlRpcProtocol => method(:xmlrpc_default_system_handler))
30
+ def self.create_protocol_request(container_class, action_pack_request)
31
+ parser = Helper.instance.get_parser
32
+ service_name = action_pack_request.parameters['action']
33
+ methodname, params = parser.parseMethodCall(action_pack_request.raw_post)
34
+ protocol = XmlRpcProtocol.new(container_class)
35
+ content_type = action_pack_request.env['HTTP_CONTENT_TYPE']
36
+ content_type ||= 'text/xml'
37
+ request = ProtocolRequest.new(protocol,
38
+ action_pack_request.raw_post,
39
+ service_name.to_sym,
40
+ methodname,
41
+ content_type)
42
+ request.values = params
43
+ request
44
+ rescue
45
+ nil
18
46
  end
19
47
 
20
- def unmarshal_request(request_info, export_info, strict=true)
21
- expects = export_info[:expects]
22
- params = request_info.protocol_info[:xmlrpc][:params]
23
- if expects
24
- expects = array_types(expects)
25
- validate_types(request_info.public_method_name, expects, params, :in)
26
- params
48
+ def initialize(container_class)
49
+ super(container_class)
50
+ container_class.write_inheritable_hash('default_system_exports', XmlRpcProtocol => method(:xmlrpc_default_system_handler))
51
+ end
52
+
53
+ def unmarshal_request(protocol_request)
54
+ values = protocol_request.values
55
+ signature = protocol_request.signature
56
+ if signature
57
+ signature = array_types(signature)
58
+ protocol_request.check_parameter_types(values, signature)
59
+ values
27
60
  else
28
- strict ? [] : params
61
+ protocol_request.checked? ? [] : values
29
62
  end
30
63
  end
31
64
 
32
- def marshal_response(request_info, export_info, return_value, strict=true)
33
- returns = export_info[:returns]
34
- if returns
35
- returns = array_types(returns)
36
- validate_types(request_info.public_method_name, returns, [return_value], :out)
37
- raw_response = create().methodResponse(true, return_value)
65
+ def marshal_response(protocol_request, return_value)
66
+ create = Helper.instance.get_create
67
+ signature = protocol_request.return_signature
68
+ if signature
69
+ signature = array_types(signature)
70
+ protocol_request.check_parameter_types([return_value], signature)
71
+ return_value = fixup_values_for_return(return_value)
72
+ raw_response = create.methodResponse(true, return_value)
38
73
  else
39
74
  # XML-RPC doesn't have the concept of a void method, nor does it
40
75
  # support a nil return value, so return true if we would have returned
41
76
  # nil
42
- if strict
43
- raw_response = create().methodResponse(true, true)
77
+ if protocol_request.checked?
78
+ raw_response = create.methodResponse(true, true)
44
79
  else
45
80
  return_value = true if return_value.nil?
46
- raw_response = create().methodResponse(true, return_value)
81
+ raw_response = create.methodResponse(true, return_value)
47
82
  end
48
83
  end
49
- ServiceResponseInfo.new(raw_response, 'text/xml')
84
+ ProtocolResponse.new(self, raw_response, 'text/xml')
50
85
  end
51
86
 
52
87
  def marshal_exception(exception)
53
- raw_response = create().methodResponse(false, exception)
54
- ServiceResponseInfo.new(raw_response, 'text/xml')
55
- end
56
-
57
- def request_info
58
- @request_info
88
+ create = Helper.instance.get_create
89
+ raw_response = create.methodResponse(false, exception)
90
+ ProtocolResponse.new(self, raw_response, 'text/xml')
59
91
  end
60
92
 
61
- def request_supported?(request)
62
- begin
63
- service_name = request.parameters['action']
64
- methodname, params = parser().parseMethodCall(request.raw_post)
65
- @request_info = ServiceRequestInfo.new(service_name,
66
- methodname,
67
- request.raw_post,
68
- request.env['HTTP_CONTENT_TYPE'] || 'text/xml',
69
- :xmlrpc => { :params => params })
70
- true
71
- rescue
72
- false
73
- end
74
- end
75
-
76
93
  private
77
- def xmlrpc_default_system_handler(name, service_klass, *args)
94
+ def xmlrpc_default_system_handler(name, service_class, *args)
78
95
  case name
79
96
  when 'system.listMethods'
80
97
  methods = []
81
- service_klass.exports.each do |name, info|
82
- methods << service_klass.public_export_name(name)
98
+ service_class.exports.each do |name, info|
99
+ methods << service_class.public_export_name(name)
83
100
  end
84
101
  methods.sort
85
102
  else
86
- raise SystemExportNotHandledError
103
+ throw :try_default_export
87
104
  end
88
105
  end
89
106
 
90
107
  def array_types(signature)
91
108
  signature.map{|x| x.is_a?(Array) ? Array : x}
92
109
  end
110
+
111
+ def fixup_values_for_return(return_value)
112
+ if return_value.is_a?(Array)
113
+ (1..return_value.size).each do |i|
114
+ return_value[i-1] = fixup_values_for_return(return_value[i-1])
115
+ end
116
+ else
117
+ if return_value.is_a?(ActiveRecord::Base)
118
+ return_value = return_value.instance_variable_get('@attributes')
119
+ end
120
+ end
121
+ return_value
122
+ end
93
123
  end
94
124
 
95
125
  end
@@ -2,12 +2,23 @@ module ActionService
2
2
  module Router
3
3
  module ActionController
4
4
  def self.append_features(base)
5
+ base.add_export_definition_callback do |klass, export_name, export_info|
6
+ if klass.service_dispatching_mode == :direct && !klass.method_defined?(:api)
7
+ klass.class_eval <<-EOS
8
+ def api
9
+ process_action_service_request
10
+ end
11
+ EOS
12
+ end
13
+ end
5
14
  base.add_service_definition_callback do |klass, name, info|
6
- klass.class_eval <<-EOF
7
- def #{name}
8
- process_action_service_request
9
- end
10
- EOF
15
+ if klass.service_dispatching_mode == :delegated
16
+ klass.class_eval <<-EOS
17
+ def #{name}
18
+ process_action_service_request
19
+ end
20
+ EOS
21
+ end
11
22
  end
12
23
  base.send(:include, ActionService::Router::ActionController::InstanceMethods)
13
24
  end
@@ -15,54 +26,55 @@ module ActionService
15
26
  module InstanceMethods
16
27
  private
17
28
  def process_action_service_request
18
- protocol = nil
19
- request_info = nil
29
+ protocol_request = nil
20
30
  begin
21
- protocol = probe_request_protocol(self.request)
22
- request_info = protocol.request_info
23
- if request_info
24
- log_request request_info
25
- response_info = dispatch_service_invocation_request(protocol, request_info)
26
- log_response response_info
31
+ protocol_request = probe_request_protocol(self.request)
32
+ if protocol_request
33
+ log_request(protocol_request)
34
+ protocol_response = dispatch_service_request(protocol_request)
35
+ log_response(protocol_request)
27
36
  response_options = {
28
- :type => response_info.content_type,
37
+ :type => protocol_response.content_type,
29
38
  :disposition => 'inline'
30
39
  }
31
- send_data(response_info.raw_body, response_options)
40
+ send_data(protocol_response.raw_body, response_options)
32
41
  else
33
42
  logger.fatal "Invalid Action Service service or method requested"
34
- render_text '', "500 Invalid service/method"
43
+ render_text 'Internal protocol error', "500 Invalid service/method"
35
44
  end
36
45
  rescue Exception => e
37
46
  log_error e unless logger.nil?
38
- service_object = service_object(request_info.service_name)
47
+ service_object = service_object(protocol_request.service_name) rescue nil
39
48
  exc_response = nil
40
- if service_object.class.report_exceptions
41
- exc_response_info = protocol.marshal_exception(e) rescue nil
49
+ if service_object && service_object.class.report_exceptions
50
+ exc_response = protocol_request.protocol.marshal_exception(e) rescue nil
42
51
  end
43
- if exc_response_info
52
+ if exc_response
44
53
  response_options = {
45
- :type => exc_response_info.content_type,
54
+ :type => exc_response.content_type,
46
55
  :disposition => 'inline'
47
56
  }
48
- send_data(exc_response_info.raw_body, response_options)
57
+ send_data(exc_response.raw_body, response_options)
49
58
  else
50
- render_text '', "500 #{e.message}"
59
+ render_text 'Internal protocol error', "500 #{e.message}"
51
60
  end
52
61
  end
53
62
  end
54
63
 
55
- def log_request(request_info)
64
+ def log_request(protocol_request)
56
65
  unless logger.nil?
57
- logger.info "\nRaw Action Service Request:"
58
- logger.info request_info.raw_body
66
+ service_name = protocol_request.service_name
67
+ method_name = protocol_request.public_method_name
68
+ logger.info "\nProcessing Action Service Request: #{service_name}##{method_name}"
69
+ logger.info "Raw Request Body:"
70
+ logger.info protocol_request.raw_body
59
71
  end
60
72
  end
61
73
 
62
- def log_response(response_info)
74
+ def log_response(protocol_response)
63
75
  unless logger.nil?
64
- logger.info "\nRaw Action Service Response:"
65
- logger.info response_info.raw_body
76
+ logger.info "\nRaw Response Body:"
77
+ logger.info protocol_response.raw_body
66
78
  end
67
79
  end
68
80
  end
@@ -2,155 +2,190 @@ module ActionService
2
2
  module Router
3
3
  module Wsdl
4
4
  def self.append_features(base)
5
- base.extend(ClassMethods)
6
5
  base.send(:include, ActionService::Router::Wsdl::InstanceMethods)
7
6
  end
8
7
 
9
- module ClassMethods
8
+ module InstanceMethods
10
9
  XsdNs = 'http://www.w3.org/2001/XMLSchema'
11
10
  WsdlNs = 'http://schemas.xmlsoap.org/wsdl/'
12
11
  SoapNs = 'http://schemas.xmlsoap.org/wsdl/soap/'
13
12
  SoapEncodingNs = 'http://schemas.xmlsoap.org/soap/encoding/'
14
13
  SoapHttpTransport = 'http://schemas.xmlsoap.org/soap/http'
15
14
 
16
- def to_wsdl(container, uri, soap_action_base)
17
- wsdl = ""
18
-
19
- namespace = container.class.soap_mapper.custom_namespace
20
- wsdl_service_name = namespace.split(/:/)[1]
21
-
22
- mapper = ActionService::Protocol::Soap::SoapMapper.new(namespace)
23
- services = {}
24
- mapper.map_container_services(container) do |name, klass, exports|
25
- services[name] = [klass, exports]
15
+ def wsdl
16
+ case @request.method
17
+ when :get
18
+ begin
19
+ host_name = @request.env['HTTP_HOST']||@request.env['SERVER_NAME']
20
+ uri = "http://#{host_name}/#{controller_name}/"
21
+ soap_action_base = "/#{controller_name}"
22
+ xml = to_wsdl(self, uri, soap_action_base)
23
+ send_data(xml, :type => 'text/xml', :disposition => 'inline')
24
+ rescue Exception => e
25
+ log_error e unless logger.nil?
26
+ render_text('', "500 #{e.message}")
27
+ end
28
+ when :post
29
+ render_text('', "500 POST not supported")
26
30
  end
27
- custom_types = mapper.custom_types
28
-
29
-
30
- xm = Builder::XmlMarkup.new(:target => wsdl, :indent => 2)
31
- xm.instruct!
32
-
33
- xm.definitions('name' => wsdl_service_name,
34
- 'targetNamespace' => namespace,
35
- 'xmlns:typens' => namespace,
36
- 'xmlns:xsd' => XsdNs,
37
- 'xmlns:soap' => SoapNs,
38
- 'xmlns:soapenc' => SoapEncodingNs,
39
- 'xmlns:wsdl' => WsdlNs,
40
- 'xmlns' => WsdlNs) do
31
+ end
41
32
 
42
- # Custom type XSD generation
43
- if custom_types.size > 0
44
- xm.types do
45
- xm.xsd(:schema, 'xmlns' => XsdNs, 'targetNamespace' => namespace) do
46
- custom_types.each do |klass, mapping|
47
- case
48
- when mapping.is_a?(ActionService::Protocol::Soap::SoapArrayMapping)
49
- xm.xsd(:complexType, 'name' => mapping.type_name) do
50
- xm.xsd(:complexContent) do
51
- xm.xsd(:restriction, 'base' => 'soapenc:Array') do
52
- xm.xsd(:attribute, 'ref' => 'soapenc:arrayType',
53
- 'wsdl:arrayType' => mapping.element_mapping.qualified_type_name + '[]')
33
+ private
34
+ def to_wsdl(container, uri, soap_action_base)
35
+ wsdl = ""
36
+
37
+ service_dispatching_mode = container.service_dispatching_mode
38
+ mapper = container.class.soap_mapper
39
+ namespace = mapper.custom_namespace
40
+ wsdl_service_name = namespace.split(/:/)[1]
41
+
42
+ services = {}
43
+ mapper.map_container_services(container) do |name, klass, exports|
44
+ services[name] = [klass, exports]
45
+ end
46
+ custom_types = mapper.custom_types
47
+
48
+
49
+ xm = Builder::XmlMarkup.new(:target => wsdl, :indent => 2)
50
+ xm.instruct!
51
+
52
+ xm.definitions('name' => wsdl_service_name,
53
+ 'targetNamespace' => namespace,
54
+ 'xmlns:typens' => namespace,
55
+ 'xmlns:xsd' => XsdNs,
56
+ 'xmlns:soap' => SoapNs,
57
+ 'xmlns:soapenc' => SoapEncodingNs,
58
+ 'xmlns:wsdl' => WsdlNs,
59
+ 'xmlns' => WsdlNs) do
60
+
61
+ # Custom type XSD generation
62
+ if custom_types.size > 0
63
+ xm.types do
64
+ xm.xsd(:schema, 'xmlns' => XsdNs, 'targetNamespace' => namespace) do
65
+ custom_types.each do |klass, mapping|
66
+ case
67
+ when mapping.is_a?(ActionService::Protocol::Soap::SoapArrayMapping)
68
+ xm.xsd(:complexType, 'name' => mapping.type_name) do
69
+ xm.xsd(:complexContent) do
70
+ xm.xsd(:restriction, 'base' => 'soapenc:Array') do
71
+ xm.xsd(:attribute, 'ref' => 'soapenc:arrayType',
72
+ 'wsdl:arrayType' => mapping.element_mapping.qualified_type_name + '[]')
73
+ end
54
74
  end
55
75
  end
56
- end
57
- when mapping.is_a?(ActionService::Protocol::Soap::SoapMapping)
58
- xm.xsd(:complexType, 'name' => mapping.type_name) do
59
- xm.xsd(:all) do
60
- mapping.each_attribute do |name, type_name|
61
- xm.xsd(:element, 'name' => name, 'type' => type_name)
76
+ when mapping.is_a?(ActionService::Protocol::Soap::SoapMapping)
77
+ xm.xsd(:complexType, 'name' => mapping.type_name) do
78
+ xm.xsd(:all) do
79
+ mapping.each_attribute do |name, type_name|
80
+ xm.xsd(:element, 'name' => name, 'type' => type_name)
81
+ end
62
82
  end
63
83
  end
84
+ else
85
+ raise(WsdlError, "unsupported mapping type #{mapping.class.name}")
64
86
  end
65
- else
66
- raise(WsdlError, "unsupported mapping type #{mapping.class.name}")
67
87
  end
68
88
  end
69
89
  end
70
90
  end
71
- end
72
-
73
- services.each do |service_name, service_values|
74
- service_klass, service_exports = service_values
75
- # Parameter list message definitions
76
- service_exports.each do |export_name, export_signature|
77
- gen = lambda do |msg_name, direction|
78
- xm.message('name' => msg_name) do
79
- sym = nil
80
- if direction == :out
81
- if export_signature[:returns]
82
- xm.part('name' => 'return', 'type' => export_signature[:returns][0].qualified_type_name)
91
+
92
+ services.each do |service_name, service_values|
93
+ service_klass, service_exports = service_values
94
+ # Parameter list message definitions
95
+ service_exports.each do |export_name, export_signature|
96
+ gen = lambda do |msg_name, direction|
97
+ xm.message('name' => msg_name) do
98
+ sym = nil
99
+ if direction == :out
100
+ if export_signature[:returns]
101
+ xm.part('name' => 'return', 'type' => export_signature[:returns][0].qualified_type_name)
102
+ end
103
+ else
104
+ mapping_list = export_signature[:expects]
105
+ i = 1
106
+ mapping_list.each do |mapping|
107
+ if mapping.is_a?(Hash)
108
+ param_name = mapping.keys.shift
109
+ mapping = mapping.values.shift
110
+ else
111
+ param_name = "param#{i}"
112
+ end
113
+ xm.part('name' => param_name, 'type' => mapping.qualified_type_name)
114
+ i += 1
115
+ end if mapping_list
83
116
  end
84
- else
85
- mapping_list = export_signature[:expects]
86
- i = 1
87
- mapping_list.each do |mapping|
88
- xm.part('name' => "param#{i}", 'type' => mapping.qualified_type_name)
89
- i += 1
90
- end if mapping_list
91
117
  end
92
118
  end
93
- end
94
- public_name = service_klass.public_export_name(export_name)
95
- gen.call(public_name, :in)
96
- gen.call("#{public_name}Response", :out)
97
- end
98
-
99
- # Declare the port
100
- port_name = port_name_for(wsdl_service_name, service_name)
101
- xm.portType('name' => port_name) do
102
- service_exports.each do |export_name, export_signature|
103
119
  public_name = service_klass.public_export_name(export_name)
104
- xm.operation('name' => public_name) do
105
- xm.input('message' => "typens:#{public_name}")
106
- xm.output('message' => "typens:#{public_name}Response")
107
- end
120
+ gen.call(public_name, :in)
121
+ gen.call("#{public_name}Response", :out)
108
122
  end
109
- end
110
-
111
- # Bind the port to SOAP
112
- binding_name = binding_name_for(wsdl_service_name, service_name)
113
- xm.binding('name' => binding_name, 'type' => "typens:#{port_name}") do
114
- xm.soap(:binding, 'style' => 'rpc', 'transport' => SoapHttpTransport)
115
- service_exports.each do |export_name, export_signature|
116
- public_name = service_klass.public_export_name(export_name)
117
- xm.operation('name' => public_name) do
118
- soap_action = soap_action_base \
119
- + "/" + service_name.to_s \
120
- + "/" + public_name
121
- xm.soap(:operation, 'soapAction' => soap_action)
122
- xm.input do
123
- xm.soap(:body,
124
- 'use' => 'encoded',
125
- 'namespace' => namespace,
126
- 'encodingStyle' => SoapEncodingNs)
123
+
124
+ # Declare the port
125
+ port_name = port_name_for(wsdl_service_name, service_name)
126
+ xm.portType('name' => port_name) do
127
+ service_exports.each do |export_name, export_signature|
128
+ public_name = service_klass.public_export_name(export_name)
129
+ xm.operation('name' => public_name) do
130
+ xm.input('message' => "typens:#{public_name}")
131
+ xm.output('message' => "typens:#{public_name}Response")
127
132
  end
128
- xm.output do
129
- xm.soap(:body,
130
- 'use' => 'encoded',
131
- 'namespace' => namespace,
132
- 'encodingStyle' => SoapEncodingNs)
133
+ end
134
+ end
135
+
136
+ # Bind the port to SOAP
137
+ binding_name = binding_name_for(wsdl_service_name, service_name)
138
+ xm.binding('name' => binding_name, 'type' => "typens:#{port_name}") do
139
+ xm.soap(:binding, 'style' => 'rpc', 'transport' => SoapHttpTransport)
140
+ service_exports.each do |export_name, export_signature|
141
+ public_name = service_klass.public_export_name(export_name)
142
+ xm.operation('name' => public_name) do
143
+ case service_dispatching_mode
144
+ when :direct
145
+ soap_action = soap_action_base + "/api/" + public_name
146
+ when :delegated
147
+ soap_action = soap_action_base \
148
+ + "/" + service_name.to_s \
149
+ + "/" + public_name
150
+ end
151
+ xm.soap(:operation, 'soapAction' => soap_action)
152
+ xm.input do
153
+ xm.soap(:body,
154
+ 'use' => 'encoded',
155
+ 'namespace' => namespace,
156
+ 'encodingStyle' => SoapEncodingNs)
157
+ end
158
+ xm.output do
159
+ xm.soap(:body,
160
+ 'use' => 'encoded',
161
+ 'namespace' => namespace,
162
+ 'encodingStyle' => SoapEncodingNs)
163
+ end
133
164
  end
134
165
  end
135
166
  end
136
167
  end
137
- end
138
-
139
- # Define the service
140
- xm.service('name' => "#{wsdl_service_name}Service") do
141
- services.each do |service_name, service_values|
142
- service_klass, service_exports = service_values
143
- port_name = port_name_for(wsdl_service_name, service_name)
144
- binding_name = binding_name_for(wsdl_service_name, service_name)
145
- xm.port('name' => port_name, 'binding' => "typens:#{binding_name}") do
146
- xm.soap(:address, 'location' => "#{uri}#{service_name.to_s}")
168
+
169
+ # Define the service
170
+ xm.service('name' => "#{wsdl_service_name}Service") do
171
+ services.each do |service_name, service_values|
172
+ service_klass, service_exports = service_values
173
+ port_name = port_name_for(wsdl_service_name, service_name)
174
+ binding_name = binding_name_for(wsdl_service_name, service_name)
175
+ case service_dispatching_mode
176
+ when :direct
177
+ binding_target = 'api'
178
+ when :delegated
179
+ binding_target = service_name.to_s
180
+ end
181
+ xm.port('name' => port_name, 'binding' => "typens:#{binding_name}") do
182
+ xm.soap(:address, 'location' => "#{uri}#{binding_target}")
183
+ end
147
184
  end
148
185
  end
149
186
  end
150
187
  end
151
- end
152
188
 
153
- private
154
189
  def port_name_for(wsdl_service_name, service_name)
155
190
  "#{wsdl_service_name}#{Inflector.camelize(service_name.to_s)}Port"
156
191
  end
@@ -159,24 +194,6 @@ module ActionService
159
194
  "#{wsdl_service_name}#{Inflector.camelize(service_name.to_s)}Binding"
160
195
  end
161
196
  end
162
-
163
- module InstanceMethods
164
- def wsdl
165
- case @request.method
166
- when :get
167
- begin
168
- uri = "http://#{@request.env['HTTP_HOST']||@request.env['SERVER_NAME']}/#{controller_name}/"
169
- soap_action_base = "/#{controller_name}"
170
- xml = self.class.to_wsdl(self, uri, soap_action_base)
171
- send_data(xml, :type => 'text/xml', :disposition => 'inline')
172
- rescue Exception => e
173
- render_text('', "500 #{e.message}")
174
- end
175
- when :post
176
- render_text('', "500 POST not supported")
177
- end
178
- end
179
- end
180
197
  end
181
198
  end
182
199
  end
@@ -23,14 +23,17 @@
23
23
 
24
24
  begin
25
25
  require 'action_controller'
26
+ require 'active_record'
26
27
  rescue LoadError
27
28
  require 'rubygems'
28
29
  require_gem 'actionpack', '>= 1.4.0'
30
+ require_gem 'activerecord', '>= 1.6.0'
29
31
  end
30
32
 
31
33
  $:.unshift(File.dirname(__FILE__))
32
34
 
33
35
  require 'action_service/base'
36
+ require 'action_service/exporting'
34
37
  require 'action_service/invocation'
35
38
  require 'action_service/struct'
36
39
  require 'action_service/container'
@@ -38,10 +41,12 @@ require 'action_service/protocol'
38
41
  require 'action_service/router'
39
42
 
40
43
  ActionService::Base.class_eval do
44
+ include ActionService::Exporting
41
45
  include ActionService::Invocation
42
46
  end
43
47
 
44
48
  ActionController::Base.class_eval do
49
+ include ActionService::Exporting
45
50
  include ActionService::Container
46
51
  include ActionService::Protocol::Registry
47
52
  include ActionService::Protocol::Soap