Friday, July 6, 2007

Ruby on Rails + SOAP4R server

And I thought it would be hard! After scouring the web and finding nothing on how to integrate the SOAP4r stub code onto rails (to create a SOAP server on top of the rails framework), I finally figured out a way to do it. The trick was in the server/servant files that are generated by wsdl2ruby; by diving down into the class definitions I was able to pull out the atomic components of the servant and stick them in a rails project. Here's the breakdown:

First, I created an empty rails project using the scaffold generator. I set it up with a base rails class that will act as a router to grab the post data and pass it through to the SOAP router and parser. What we are interested in is the 'create' method in the applicationController that rails generates (which using the REST architecture is where the HTTP POST command is captured.) I'll walk through the raw code first, but keep in mind that I plan to wrap all of this into a helper class for cleanliness.

def create
  @router = ::SOAP::RPC::Router.new('rubynode')
  servant = NetworkNodePortType2.new
  res = ''
  req = request

@router is the SOAP4R router that takes an input post dump and parses it using the type definitions created by WSDL2RUBY. The 'servant' is an instance of the basic class generated by the WSDL2RUBY script. The servant class contains the application logic for generating the return data from the parameters in the request message (this class is dummy generated by the WSDL2RUBY script, and must be filled in; check out the doc/literal example in the soap4r install folder for the specific example.) The 'res' variable will be used to hold the SOAP response message, but for now is nilled out, and the 'req' variable is a copy of the rails generated 'request' data structure that contains the raw POST dump and other HTTP header info needed later on.

  NetworkNodePortType2::Methods.each do definitions
    opt = definitions.last
    if opt[:request_style] == :document
      @router.add_document_operation(servant, *definitions)
    else
      @router.add_rpc_operation(servant, *definitions)
    end
  end

The above section of code is the intialization stub taken from the generated server app class. This simply initializes the operation definitions from the WSDL and binds them to the servant methods through the router. That is, the 'definitions' include the input and output message types and bindings for each operation defined in the WSDL. This code sets up the path to the application logic (in the servant class) when a defined message is recieved.

  conn_data = ::SOAP::StreamHandler::ConnectionData.new
  setup_req(conn_data, req)
  @router.external_ces = nil
  conn_data = @router.route(conn_data)
  input = setup_res(conn_data, req, res)

  respond_to do |format|
    format.xml { render :xml => input }
  end
end

def setup_req(conn_data, req)
  conn_data.receive_string = req.raw_post
  conn_data.receive_contenttype = req.content_type
  conn_data.soapaction = nil
end

def setup_res(conn_data, req, res)
  res = conn_data.send_string
end

Here's the meat of the code. First, the 'conn_data' variable contains the streamhandler connection data type, which is used to house the raw POST dump and the HTTP header info. Next, we map the 'request' information into the 'conn_data' structure and then pass it into the router. We then grab the response from the conn_data structure and pass it to rails XML handler to be returned.

And there you go: a decent first shot at integrating the SOAP4R library/generated stub code into a working Ruby on Rails web service implementation. Incidentally, a wrapper class using these basic tools would be a perfect place to put the MTOM hooks: all that would need to be done is grab the raw SOAP response message and run a transform on the 'base64encoded' parts.

2 comments:

Anonymous said...

Hello,

When ever I surf on web I never forget to visit this website[url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips].[/url]Plenty of useful information on mtom4ruby.blogspot.com. Frankly speaking we really do not pay attention towards our health. Are you really serious about your weight?. Recent Scientific Research presents that about 70% of all United States grownups are either fat or weighty[url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips].[/url] Hence if you're one of these individuals, you're not alone. Its true that we all can't be like Brad Pitt, Angelina Jolie, Megan Fox, and have sexy and perfect six pack abs. Now the question is how you are planning to have quick weight loss? [url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips]Quick weight loss[/url] is really not as tough as you think. If you improve some of your daily diet habbits then, its like piece of cake to quickly lose weight.

About me: I am blogger of [url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips]Quick weight loss tips[/url]. I am also health trainer who can help you lose weight quickly. If you do not want to go under painful training program than you may also try [url=http://www.weightrapidloss.com/acai-berry-for-quick-weight-loss]Acai Berry[/url] or [url=http://www.weightrapidloss.com/colon-cleanse-for-weight-loss]Colon Cleansing[/url] for effortless weight loss.

Anonymous said...

I love mtom4ruby.blogspot.com! Here I always find a lot of helpful information for myself. Thanks you for your work.
Webmaster of http://loveepicentre.com and http://movieszone.eu
Best regards