Zack_C
December 9, 2006, 2:08am
1
I have some very simple action web service code that just doesn’t want
to work.
app/controllers/quickbooks_controller.rb
class QuickbooksController < ApplicationController
ssl_required :api
def authenticate(username, password)
[“”, “”]
end
end
app/apis/quickbooks_api.rb
class QuickbooksApi < ActionWebService::API::Base
api_method :authenticate,
:expects => [{:strUserName => :string},
{:strPassword => :string}],
:returns => [[:string]]
end
But when this SOAP message is posted…
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/ ”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance ”
xmlns:xsd=“http://www.w3.org/2001/XMLSchema ”>
soap:Body
test_username
abc123
</soap:Body>
</soap:Envelope>
… all hell breaks loose…
Processing QuickbooksController#api (for 123.456.789.213 at 2006-12-08
16:44:35) [POST]
Session ID: e021ad12268550b2e1e49b2241bb6456
Parameters: {“action”=>“api”, “controller”=>“quickbooks”}
Web Service Request: authenticate(“test_username”, “abc123”) Entrypoint:
api
<?xml version="1.0" encoding="utf-8"?><soap:Envelope
xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/ ”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance ”
xmlns:xsd=“http://www.w3.org/2001/XMLSchema ”>soap:Body test_usernameabc123</soap:Body></soap:Envelope>
ActionWebService::Dispatcher::DispatcherError (no such method
‘authenticate’ on API QuickbooksApi):
/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/abstract.rb:154:in
web_service_invocation' /vendor/rails/actionwebservice/lib/action_web_service/dispatcher/abstract.rb:17:in
invoke_web_service_request’
/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb:55:in
dispatch_web_service_request' /usr/local/lib/ruby/1.8/benchmark.rb:293:in
measure’
/vendor/rails/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb:53:in
dispatch_web_service_request' (eval):1:in
api’
/vendor/rails/actionpack/lib/action_controller/base.rb:982:in
perform_action_without_filters' /vendor/rails/actionpack/lib/action_controller/filters.rb:363:in
perform_action_without_benchmark’
/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in
perform_action_without_rescue' /usr/local/lib/ruby/1.8/benchmark.rb:293:in
measure’
/vendor/rails/actionpack/lib/action_controller/benchmarking.rb:66:in
perform_action_without_rescue' /vendor/rails/actionpack/lib/action_controller/rescue.rb:80:in
perform_action’
/vendor/rails/actionpack/lib/action_controller/base.rb:410:in
process_without_filters' /vendor/rails/actionpack/lib/action_controller/filters.rb:372:in
process_without_session_management_support’
/vendor/rails/actionpack/lib/action_controller/session_management.rb:114:in
process' /vendor/rails/actionpack/lib/action_controller/base.rb:321:in
process’
/vendor/rails/railties/lib/dispatcher.rb:41:in dispatch' /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel/rails.rb:73:in
process’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:551:in
process_client' /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:550:in
process_client’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:636:in
run' /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:636:in
run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:625:in
run' /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:956:in
run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel.rb:955:in
run' /usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:127:in
run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/lib/mongrel/command.rb:199:in
`run’
/usr/local/lib/ruby/gems/1.8/gems/mongrel-0.3.13.3/bin/mongrel_rails:235
/usr/local/bin/mongrel_rails:18
Any ideas?
–
Zack C.
http://depixelate.com
Zack_C
December 10, 2006, 3:16am
2
On 12/8/06, Zack C. [email protected] wrote:
You must register that QuickbooksController implements QuickbooksApi
like so:
class QuickbooksController
web_service_api QuickbooksApi
end
–
Kent
Zack_C
December 10, 2006, 8:13pm
3
On 12/9/06, Kent S. [email protected] wrote:
end
But when this SOAP message is posted…
Kent
http://www.datanoise.com
Kent,
Thanks for the help but I’m not sure if that is the problem.
According to the source ActionController will implicitly load an api
according to naming conventions. Here is the snip from the rdocs in
actionwebservice/lib/action_web_service/container/direct_container.rb
...
# A controller with a class name of GoogleSearchController will
# implicitly load <tt>app/apis/google_search_api.rb</tt>, and
expect the
# API definition class to be named GoogleSearchAPI or
# GoogleSearchApi.
…
def web_service_api(definition=nil)
…
end
My code follows these conventions. Even so I put in the call to test
it out and no luck.
Any other ideas out there?
–
Zack Chander
http://depixelate.com
http://trackplace.com
Zack_C
December 10, 2006, 10:08pm
4
On 12/10/06, Zack C. [email protected] wrote:
# API definition class to be named <tt>GoogleSearchAPI</tt> or
Yes, you are right. I didn’t read your original email carefully. As
for the problem,
I’ve noticed that you are using non-default namespace for your web
service. Make sure that
you are setting your namespace in the controller correctly:
class QuickbooksController < ApplicationController
wsdl_namespace “http://developer.intuit.com ”
…
end
–
Kent
Zack_C
December 11, 2006, 9:53pm
5
On 12/11/06, Zack C. [email protected] wrote:
puts qb.authenticate(‘foo’, ‘bar’)
<n1:Authenticate xmlns:n1="urn:ActionWebService"
env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<strUserName xsi:type="xsd:string">foo</strUserName>
<strPassword xsi:type="xsd:string">bar</strPassword>
</n1:Authenticate>
</env:Body>
</env:Envelope>
I’m at a loss here. Any other ideas? Or ideas on other ways to test?
That’s why you should act according to the WSDL which ActionWebService
generates for you. I suspect that you have to also specify SOAPAction
header when you use curl. The actual value of this header you can find
in WSDL.
–
Kent
Zack_C
December 11, 2006, 6:57pm
6
On 12/10/06, Kent S. [email protected] wrote:
# A controller with a class name of GoogleSearchController will
wsdl_namespace “http://developer.intuit.com ”
…
end
–
Kent
http://www.datanoise.com
I tried setting the wsdl namespace but this had no effect. I’m
actually not creating a client from wsdl so I doubt this will help.
The interesting thing is that everything works fine while testing. I
wrote a quick tester script:
lib/soap_test.rb
require File.expand_path(File.dirname(FILE ) +
“/…/config/environment”)
qb = ActionWebService::Client::Soap.new(QuickbooksApi,
‘http://www.localhost.com:3000/api/quickbooks/api ’)
puts qb.authenticate(‘foo’, ‘bar’)
This works fine although if you look at the source of
ActionWebService::Client::Soap you can see that the QuickbooksApi
methods are called directly and therefore the whole stack is not
exercised.
So then I thought I’d try using curl.
curl -H “Content-Type: text/xml” -d @msg -X POST
http://www.localhost.com:3000/api/quickbooks/api
where msg:
<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd=“http://www.w3.org/2001/XMLSchema ”
xmlns:env=“http://schemas.xmlsoap.org/soap/envelope/ ”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance ”>
env:Body
<n1:Authenticate xmlns:n1=“urn:ActionWebService”
env:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/ ”>
foo
bar
</n1:Authenticate>
</env:Body>
</env:Envelope>
This is the exact request soap message that the
ActionWebService::Client::Soap client used in the previous test.
However this barfs with:
RuntimeError (No valid method call - missing method name!):
/usr/local/lib/ruby/1.8/xmlrpc/parser.rb:476:in parseMethodCall' /usr/local/lib/ruby/1.8/xmlrpc/marshal.rb:63:in
load_call’
/usr/local/lib/ruby/1.8/xmlrpc/marshal.rb:32:in load_call' .//vendor/rails/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb:36:in
decode_request’
.//vendor/rails/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb:32:in
decode_action_pack_request' .//vendor/rails/actionwebservice/lib/action_web_service/protocol/discovery.rb:20:in
discover_web_service_request’
.//vendor/rails/actionwebservice/lib/action_web_service/protocol/discovery.rb:18:in
discover_web_service_request' .//vendor/rails/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb:46:in
dispatch_web_service_request’
(eval):1:in api' .//vendor/rails/actionpack/lib/action_controller/base.rb:982:in
perform_action_without_filters’
I’m at a loss here. Any other ideas? Or ideas on other ways to test?
–
Zack C.
http://depixelate.com
http://trackplace.com
Zack_C
December 12, 2006, 12:42am
7
On 12/11/06, Zack C. [email protected] wrote:
It turns out that the fact that authenticate is lower case crashes
AWS. I think that upper case is standard - I need to look into that.
I suppose this is a case of an screwed up web client. I’ll probably
monkey patch AWS to handle this or if I find out a SOAP method name
can be specified lowercase, I’ll submit a patch.
Thanks a ton for your help!
You don’t need to monkey-patch anything. When you define your API set
‘inflect_names’ to false, so AWS doesn’t camel-case your methods,
like:
class QuickbooksApi < ActionWebService::API::Base
inflect_names false
api_method :authenticate,
:expects => [{:strUserName => :string}, {:strPassword => :string}],
:returns => [[:string]]
end
–
Kent
Zack_C
December 12, 2006, 12:20am
8
On 12/11/06, Kent S. [email protected] wrote:
require File.expand_path(File.dirname(FILE ) + “/…/config/environment”)
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
http://www.datanoise.com
Kent,
I really do appreciate your help…
I basically figured out the problem. The SOAP client (the Quickbooks
Web Connector) sends the following message:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/ ”
xmlns:soapenc=“http://schemas.xmlsoap.org/soap/encoding/ ”
xmlns:tns=“http://developer.intuit.com ”
xmlns:types=“Intuit Developer ”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance ”
xmlns:xsd=“http://www.w3.org/2001/XMLSchema ”>
<soap:Body
soap:encodingStyle=“http://schemas.xmlsoap.org/soap/encoding/ ”>
<q1:authenticate xmlns:q1=“http://developer.intuit.com/ ”>
test_username
abc123
</q1:authenticate>
</soap:Body>
</soap:Envelope>
It turns out that the fact that authenticate is lower case crashes
AWS. I think that upper case is standard - I need to look into that.
I suppose this is a case of an screwed up web client. I’ll probably
monkey patch AWS to handle this or if I find out a SOAP method name
can be specified lowercase, I’ll submit a patch.
Thanks a ton for your help!
–
Zack C.
http://depixelate.com
http://trackplace.com
Zack_C
December 12, 2006, 12:46am
9
On 12/11/06, Kent S. [email protected] wrote:
:returns => [[:string]]
end
–
Kent
http://www.datanoise.com
Kent,
Yes - I found that out a few minutes after posting…
Thanks a ton for your help!
–
Zack C.
http://depixelate.com
http://trackplace.com