Ruby as Enterprise Glue
Listing 8. servlet.rb
require 'rubygems'
require 'builder'
require 'database'
require 'loc_service'
require 'webrick'
include WEBrick
include WEBrick::HTTPServlet
class LocalizationServlet < AbstractServlet
def initialize(server, wsdl)
super(server)
@loc_service = LocalizationService.new(wsdl)
end
def do_GET(req, res)
customer_id = req.query['customer_id']
customer = Customer.find(customer_id)
address = customer.address
if address.location.nil?
lon, lat = @loc_service.locate(address)
address.location = Location.new(
:longitude => lon, :latitude => lat
)
customer.save
end
res['content-type'] = 'text/xml'
res.body = to_xml(address.location)
res.status = 200
end
def to_xml(location)
xml = ''
doc = Builder::XmlMarkup.new(
:target => xml, :indent => 2
)
doc.position(
:longitude => location.longitude,
:latitude => location.latitude
)
xml
end
end
We have derived our servlet from class AbstractServlet. The WEBrick server calls the do_GET method whenever it receives a GET request for a certain URL. Accordingly, it calls do_POST, do_PUT and so on for other HTTP request methods. WEBrick always passes a Request and a Response object to the method it calls. Request objects contain all query parameters and headers that were sent by the client. It's your task to fill the Response object with a body and all headers that should be sent back.
In our case, the servlet logic reads like a pseudo-code specification. We try to read the geographical position of the customer having the ID customer_id from the database. If we cannot find it, we localize the customer's address using the localization service and store the coordinates in the database, so we do not have to localize it again. Next, we turn the coordinates into an XML document. At the end of the method, we set the content type, the HTTP status code and the body.
You do not have to define an initialize method for a servlet, but if you do, it always gets the server instance as its first argument. In our case, we also expect the name of the WSDL to be used to initialize the localization service.
The to_xml method converts a location into an XML document. Too often, developers use raw strings to create XML documents. I recommend never doing that, even for apparently trivial documents. Creating XML documents never is as easy as it seems, because you have to care about difficult concepts, such as well-formedness and character set encodings. Hence, we use Jim Weirich's XmlBuilder class (see Resources) to create the result document.
Now we have a servlet that implements our main logic, but a servlet alone won't cut it. We still have to create an HTTP server that controls it. Listing 9 is everything we need. We specify the port on which the server is listening and map our LocalizationServlet to the path /. In addition, we make the server terminate whenever it receives a SIGINT or SIGTERM signal.
Listing 9. server.rb
require 'servlet'
server = HTTPServer.new(:Port => 4242)
server.mount(
'/', LocalizationServlet, 'loc_service.wsdl'
)
trap('INT') { server.shutdown }
trap('TERM') { server.shutdown }
server.start
It's time for a final test run. Point your favorite browser to http://localhost:4242/?customer_id=1 or use a command-line tool such as wget or curl to test our newly created service:
mschmidt:/tmp $ curl http://localhost:4242/?customer_id=1 <position longitude="97.03" latitude="32.9"/> mschmidt:/tmp $
That's exactly the result we have expected. We're done!
There's no doubt, regarding enterprise integration, Ruby is ready for prime time. Even in this short article, we were able to cover some of the most important enterprise technologies, such as relational databases, SOAP and HTTP. You also can integrate your existing Java code, access LDAP servers, create XML-RPC services or manipulate XML documents with ease.
Ruby cannot compete in many respects with platforms such as J2EE or .NET, but it doesn't have to, and it doesn't want to. Its strengths are flexibility, maintainability and speed of development. Although the Ruby platform might not be the biggest compared to other dynamic languages, it might well be the one that's growing fastest. And, most important, it's a lot of fun!
Resources for this article: /article/9018.
Maik Schmidt has worked as a software developer for more than a decade. He makes a living from creating complex solutions for mid-size enterprises. Besides his day job he writes book reviews and articles for computer science magazines and contributes code to open-source projects. Recently he has written his first book called Enterprise Integration with Ruby.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
| Speed Up Your Web Site with Varnish | Jun 19, 2013 |
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
- Speed Up Your Web Site with Varnish
- Containers—Not Virtual Machines—Are the Future Cloud
- Linux Systems Administrator
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Non-Linux FOSS: libnotify, OS X Style
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Android's Limits
- Reply to comment | Linux Journal
1 hour 42 min ago - Yeah, user namespaces are
2 hours 58 min ago - Cari Uang
6 hours 30 min ago - user namespaces
9 hours 23 min ago - yea
9 hours 49 min ago - One advantage with VMs
12 hours 18 min ago - about info
12 hours 51 min ago - info
12 hours 52 min ago - info
12 hours 53 min ago - info
12 hours 55 min ago
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
I too don't understand
I too don't understand why:
ERROR SOAP::WSDLDriverFactory::FactoryError: no ports have soap:address
/usr/lib/ruby/1.8/soap/wsdlDriver.rb:75:in `find_port'
/usr/lib/ruby/1.8/soap/wsdlDriver.rb:37:in `create_rpc_driver'
./loc_service.rb:6:in `initialize'
./servlet.rb:11:in `initialize'
/usr/lib/ruby/1.8/webrick/httpservlet/abstract.rb:23:in `get_instance'
/usr/lib/ruby/1.8/webrick/httpserver.rb:102:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
server.rb:8
Please say me why there wrong?
Thanks!
ERROR SOAP::WSDLDriverFactory
I get this error from my soap server (from listing 7) but I don't understand why:
ERROR SOAP::WSDLDriverFactory::FactoryError: no ports have soap:address
/usr/lib/ruby/1.8/soap/wsdlDriver.rb:75:in `find_port'
/usr/lib/ruby/1.8/soap/wsdlDriver.rb:37:in `create_rpc_driver'
./loc_service.rb:6:in `initialize'
./servlet.rb:11:in `initialize'
/usr/lib/ruby/1.8/webrick/httpservlet/abstract.rb:23:in `get_instance'
/usr/lib/ruby/1.8/webrick/httpserver.rb:102:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
server.rb:8
Thanks.
ERROR SOAP::WSDLDriverFactory
I get this error from my soap server (from listing 7) but I don't understand why:
ERROR SOAP::WSDLDriverFactory::FactoryError: no ports have soap:address
/usr/lib/ruby/1.8/soap/wsdlDriver.rb:75:in `find_port'
/usr/lib/ruby/1.8/soap/wsdlDriver.rb:37:in `create_rpc_driver'
./loc_service.rb:6:in `initialize'
./servlet.rb:11:in `initialize'
/usr/lib/ruby/1.8/webrick/httpservlet/abstract.rb:23:in `get_instance'
/usr/lib/ruby/1.8/webrick/httpserver.rb:102:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
server.rb:8
Thanks.
Don't know but probably this
Don't know but probably this can help you:
http://www.thescripts.com/forum/thread509677.html