Skip to content


Enterprise Ruby on Rails: Update

Fortunately for me, nobody actually reads this blog. Oddly enough I’ve spent more (much more) time working with Ruby. It turns out that I may have been being overly harsh in my post Enterprise Rails: Why I Canat Use Rails in My Enterprise; Ruby, and Rails, is quite adept at web services and transactions.

I recently got an application working which uses transactions and web services. First transactions: I think ActiveRecord is pretty dang cool. Doing transactions across multiple tables (a.k.a. models), in the same database, works pretty well, you just wrap the code you want in a transaction in a transaction do ... end.

Here’s my experience with web services. First install soap4r as a gem:

sudo gem install soap4r --source http://dev.ctor.org/download/

Now to connect do this:

wsdl2ruby.rb --wsdl http://localhost:8080/myservice/service?wsdl --type client

and you’ll have a client. There will be for files generated:

  • default.rb – Contains the models
  • defaultDriver.rb – This is the stub; it’s what you instantiate and call methods on
  • defaultMappingRegistry.rb – This maps the models (in default.rb) to types specified in the WSDL.
  • MyServiceClient.rb – An example client.

Good enough, unless you’re in my situation. I needed to connect to two web services in the same application. Both web services are over https and one of them requires basic authentication. I started mucking about the internet trying to find some answers when I happened upon a post called SOAP + Basic Authentication in Ruby. He links to this thread on the soap4r Google Group. The short of it is:

  • install the newest version of soap4r (already done, above).
  • install the newest version of http-access2, which understands basic authentication.
  • use the client generated by wsdl2ruby.rb
  • set the header like so:
    soap = SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driver
    soap.options["protocol.http.basic_auth"] << [WSDL_URL, "user", "password"]
    result = soap.WebService('arg1','arg2','arg3')

The http-access2 library install is straight forward, just download it, extract it, run the install.rb. Once I did that, *poof* my web service was working. Yay!

At this point I feel like I've got a pretty good hold on things. I'm able to run transactions through the web service I'm developing on my local machine. Then I try to generate the client for the other web service, and promptly run into this:

FATAL -- app: Detected an exception. Stopping ... certificate verify failed (OpenSSL::SSL::SSLError)

Beautiful, I know. The most useful page I can find, is a post titled Using SSL with Ruby http-access2 by Greg Houston. The only problem with this approach is I'm not creating the connection, soap4r is. I didn't figure that out until I already registered to get the certificate from Verisign (because I don't have a Windoze computer -- at all), for future reference, here's the link to that page: http://www.verisign.com/support/roots.html.

After digging around in the code for the Ruby API, http-access2, and soap4r for a few hours, then doing some more Google searches I came across the page which finally pulled it all together: Testing PayPal Web Services With Ruby soap4r. I was totally psyched when I found this little tidbit:

client.options['protocol.http.ssl_config.ca_file'] = 'api_cert_chain.crt'

Only to have my dreams shattered. When I modified it for my app this is the error I received:

/usr/local/lib/ruby/gems/1.8/gems/soap4r-1.5.5.20061022/lib/soap/property.rb:269:in `check_lock': cannot add any key to locked property (TypeError)

Thankfully the line right above the 'ca_file' one yields a clue:

client.options['protocol.http.ssl_config.verify_mode'] = OpenSSL::SSL::VERIFY_PEER

Combine that with lines 82-85 of .../ruby/1.8/net/https.rb:

: verify_mode, verify_mode=((|mode|))
    Sets the flags for server the certification verification at
    begining of SSL/TLS session.
    OpenSSL::SSL::VERIFY_NONE or OpenSSL::SSL::VERIFY_PEER is acceptable.

And now we know how to tell OpenSSL not to verify the certificate. Of course I would feel better if the cert was being verified, but, this is an internal app, and will only run on one server with limited access. At least it's working, and that's the important thing.

So in closing, with a little time and effort, Ruby, and Rails, can do transactions and web services. The lack of encryption, however, is still a major stumbling block.

Posted in Ruby, Software Development.


One Response

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. eric berry says

    this is great info.. Im glad im not the only one struggling with soap and ruby



Some HTML is OK

or, reply to this post via trackback.