Ruby as Enterprise Glue
Dynamic languages, formerly known as scripting or glue languages, always have been a valuable tool in every serious enterprise developer's toolbox. In the past, hordes of programmers have used Perl, Python, Tcl and the like to integrate disparate databases, message queues, LDAP repositories, Web services and so on. But, there's a new kid on the block called Ruby. In this article, I show how to solve common enterprise integration problems much more quickly and elegantly than with any other programming language available today.
To make things more tangible, let's solve a typical real-world problem. A provider of mobile telecom services wants to offer a new tariff based on the user's geographical position. People pay a lower fee when they use their cell phones within a radius of 500 meters around their home address.
To fulfill this requirement, the team developing the billing application needs a new HTTP service. The service gets a customer ID and should return the coordinates belonging to the customer's address in XML format. Our company already has a customer database, and it has access to a SOAP localization service. The target system architecture looks like Figure 1, and it's our task to build the new HTTP service.
Building it step by step, first we modify the customers database and build an access layer for it. Then, we implement a binding for the localization service, and finally, we hide all this behind a nice HTTP interface. As you might have guessed from the article's title, we use Ruby to do all of this.
Customers are stored in a MySQL database called customers. It basically consists of only two tables: customer and address (Listing 1). Every entry in the customer table refers to an entry in the address table and vice versa. Both tables have a primary key called id that is generated automatically by the database.
Listing 1. create_db.sql
drop table if exists customer; create table customer( id int unsigned not null auto_increment, forename varchar(64) not null, surname varchar(64) not null, created_on timestamp not null, primary key(id) ); drop table if exists address; create table address( id int unsigned not null auto_increment, customer_id int unsigned not null, street varchar(64), house_number varchar(16), postal_code varchar(16), city varchar(64), state char(2), primary key(id), foreign key (customer_id) references customer(id) on delete cascade );
Because we have to store the coordinates of every address, we add a new table called locations (Listing 2). It contains the longitude and latitude belonging to every address.
Listing 2. add_location.sql
drop table if exists locations; create table locations( id int unsigned not null auto_increment, address_id int unsigned not null, longitude double not null, latitude double not null, primary key(id), foreign key (address_id) references address(id) on delete cascade );
Alternatively, we could add longitude and latitude columns to the address table, but our solution is less invasive. Perhaps there are applications performing SQL statements such as select * from address, and we do not want to break them.
That's all we have to do on the database side for the moment. Now, we'll see how to access the tables in a Ruby program.
There are many ways to access relational databases. For example, you can use the database's native interface or an abstraction layer such as DBI. But in an object-oriented language like Ruby, an object-relational mapper (ORM) is by far the most convenient tool. ORMs map rows in a database table to objects and vice versa without a single SQL statement.
ActiveRecord is the most advanced ORM for Ruby and implements one of Martin Fowler's enterprise application patterns (see the on-line Resources). He defines it as follows: “[An active record is] an object that wraps a row in a database table or view, encapsulates the database access and adds domain logic on that data.” Simply put, an active record is a class that provides the typical CRUD methods (Create, Retrieve, Update, Delete) for a single row in a database table.
ActiveRecord is part of the famous Ruby on Rails project, but it's completely independent of the rest and can be obtained and installed separately. We'll use it to map our three tables to classes.
If you've worked with an ORM before, you probably expect some boring configuration files now. How do we map a table to a Ruby class? How do we map a column to an attribute? Don't be afraid! You don't need all this, because ActiveRecord prefers convention over configuration. The short program in Listing 3 is all you need to map the Customer, Address and Location classes to the according tables.
|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|
|Introduction to MapReduce with Hadoop on Linux||Jun 05, 2013|
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- New Products
- Validate an E-Mail Address with PHP, the Right Way
- RSS Feeds
- Introduction to MapReduce with Hadoop on Linux
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Help with Designing or Debugging CORBA Applications
- Returning Values from Bash Functions
- Linux Systems Administrator
- notifier shortcomings
22 min 51 sec ago
1 hour 59 min ago
- Android User
2 hours 1 min ago
- Reply to comment | Linux Journal
3 hours 54 min ago
6 hours 43 min ago
- This is a good post. This
11 hours 56 min ago
- Great, This is really amazing
11 hours 58 min ago
- These posts are really good
12 hours 25 sec ago
- It’s a really great site you
12 hours 2 min ago
- Beautiful ... I love your
12 hours 28 min ago
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?