ben robison
when only more words will do
Model Driven Architecture [part 1]
Model Driven Architecture (MDA) is one of many buzzwords you’ll hear in software development circles. It’s actually more than one word, but nobody ever says buzzphrase, we’re much more excited by buzzwords. This article is by no means meant to be a comprehensive resource, it simply represents my attempt to wrap my head around the concept.
Model driven architecture is an attempt to focus information systems on business problems rather than on the technology itself. The idea is that by defining our data and our processes in a certain way, that applications can be written by computers instead of programmers.
The models we are talking about here are significantly more complex than a class diagram or a sequence diagram, but at heart are really providing some of the same information. You can define the types of data your application must represent and you can define how different entities in your system should interact. Then if you define everything properly, a super special computer program can actually generate a functioning application for you.
The main standards behind MDA are mostly developed by the Object Management Group (OMG) which they seem to produce at an astonishing rate (see this list if you want to be impressed). In reality, these computer generated applications are probably better used as a starting point rather than a polished final product, but a good deal of the time investment in creating a new application can be done for you.
Principles
There are a few principles that underpin the model driven architecture. From an IBM article on the subject:
- Models expressed in a well-defined notation are a cornerstone to understanding systems for enterprise-scale solutions.
- The building of systems can be organized around a set of models by imposing a series of transformations between models, organized into an architectural framework of layers and transformations.
- A formal underpinning for describing models in a set of metamodels facilitates meaningful integration and transformation among models, and is the basis for automation through tools.
- Acceptance and broad adoption of this model-based approach requires industry standards to provide openness to consumers, and foster competition among vendors.
If that made any sense, then good on you. Here’s the benrobb version.
- Defining your data makes it easier to understand, especially when there’s lots of it.
- Our really cool MDA tool lets you turn your model into different types of applications in different languages.
- This will get even cooler if we can get lots of people to do it.
Value Proposition
The main value I see is that it allows you to seperate the design from the architecture, the business from the technology, or in the words of CARE Technologies (OptimalJ creator), the “what” from the “how.”
Compuware (OlivaNovA creator) lays out these values:
- accelerate productivity—cut development time by 40 percent or more
- enhance maintainability—simplify maintenance and refactoring tasks, reducing time and cost
- increase flexibility—respond rapidly to business and technology change
- ensure quality—promote and enforce best practices and industry-proven code standards
- streamline integration—leverage and optimize existing technology investments
- synchronize requirements with code—trace business requirements to application code implementation
We all know that technology changes faster than most business processes, and MDA provides a way to allow you to keep your business processes, but also keep up to date on your technology.
Vendors
OMG maintains a list of vendors of MDA products. Of the vendors on this list, I’ve actually heard of a few:
- CARE Technologies - OlivaNOVA The Programming Machine
- Compuware - OptimalJ
- IBM - Rational
- TenFold - BusinessTransformation & TechnologyTransfer
Criticisms
These are simply coming from Wikipedia, but there are a few that I think are important to mention here.
Vendor Lock-in: Although the idea behind MDA is to free you from the worry of technology and code, using it does lock you into a specific vendor, because at this point in time, none of them are interoperable.
Incomplete standards: some of the technical standards involved have yet to be implemented in standard way, and some have not even been defined yet.
Expertise scarcity: Modellers/MDA Architects are in much scarcer supply than your average (or even above average) developer.
Conclusions
Well, that’s all the time I’ve got now since the baby needs her shower. Part 1 has really focused on what MDA is, what it does, and who is doing it, but in Part 2 we’ll take a look at some of the things you might want to take a look at if you (or your organization) is looking into doing something with MDA.
Rails & MemcacheD
Well, after spending a few frustrated hours on Saturday, I’ve got a working application that uses memcached. And when I use the word application, I use it very loosely. It’s basically a page that sets the current time into the session.
Now originally I followed this tutorial and installed the necessary gems in order to cache the ActiveRecord objects into memcached. I followed all instructions exactly as instructed, but starting the memcached server in verbose mode, revealed no object calls to and from the cache. If I loaded up the application console, I could access the cache directly and put things in on my own, but the functionality provided by cached_model was not working on my machine for whatever reason.
Being somewhat of a nuby anyway when it comes to Rails, I turned to an alternate solution rather than hopelessly debugging the current problem. I found another tutorial that had instructions on how to cache sessions into memcached. I used the memcache-client client rather than the Ruby-memcache client going for the speed and the ease of setup. It works like a charm.
Now rather than just leaving it there, I’ll tell you what I’v discovered over and above what Elliott discovered over at townx. The ongoing development of memcache-client has apparently made some advancements to the point where it matches the application stability of Ruby-memcache when the memcache server is turned off.
At the time of the post, Elliott observed that when using memcache-client the whole application fell over when the connection to the memcache server was lost, while Ruby-memcache kept the application running with irretrievably broken sessions. He then wrote a plug-in that monitored the memcache servers and when they came back online would begin using them again (rather than having to restart the application). My observation as of today is that memcache-client now has both of those functionalities built in.
When the connection to the memcache server is lost, then the sessions are broken, any data stored is inaccessible, however when the memcache servers some back online, the application recognizes that and begins using the sessions again. If the memcache server was turned off, then any data in them is gone as well, but if the memcache server itself was still running and it was just the connection lost, then the session data should still be available in the memcache servers.
As a sidenote, over at Nuby on Rails, they noted that the the memcached server available on Macs through Darwinports is broken. I verified this; the calls I made to the cache directly from the console did indeed take 5 seconds to push through. However,when running it from my Ubuntu box even over the internet (Sundance to Orem) the application response was pretty snappy. Not to shabby considering the quality of the internet in Sundance.
Memcached
I’ve been doing some research lately looking into memcached. Memcached is a system for distributing a memory cache across multiple machines. If you’re using a single server, then it probably won’t do much for you, but as you start to scale up, it becomes a real life saver. It is able to dramatically reduce database hits, meaning that your disks can take a little rest, and your server doesn’t have to work so hard.
The list of people using memcached is long and impressive including such sites as Slashdot, Digg, Wikipedia, LiveJournal, and more. It was actually developed for LiveJournal and grew up from there (in much the same way that MediaWiki grew out of Wikipedia or Rails grew out of BaseCamp). There are actually a lot of Rails folks starting to look into it now that Mongrel allows excellent scaling.
As I began to research memcached it became apparent that in order to get any sense of what it was capable of, I was going to have to dive in and get it running on my own. There are only one or two decent articles on the web about it, despite it’s apparent popularity, and so I began to look into it on my own.
My heart sank when I saw that it came distributed as source code. My recent experience with Gentoo has given me enough source compiling to last awhile, so I was pleased to see that it was listed in the both the DarwinPorts (now MacPorts) and Ubuntu repositories.
So far I’ve got the software installed on the lappy and the virtual server. I’ve started up the memcached daemon in both places and it seems to work well. Since Rails is obviously my development platform of choice, I’ve also installed the memcache-client RubyGem and apparently, I’m ready to go. Now for buliding a website.
Cannot Map {objType} to SOAP/OM
This was a strange exception that I struggled with for several hours this evening, but I have finally prevailed.
The Background
For my Information Architecture class, we’ve got to create a web service provider and a web service requester, this provided the initial impetus for my recent push into web services and the last few posts dedicated to the topic. Now our professor has published a web service that basically dumps his database out into an array of complex data types.
His database is a weather reporting database that has zip code, temperature, humidity, etc. The databse is small (currently 3 entries) and populated with completely fabricated data, this is a learning experience not an accurate forecaster.
Our task is to subscribe to his web service, and publish our own that will accept a string parameter as the zip code and return the single weather report for just that zip code. I decided that I’d just subscribe to his web service in my controller, find the appropriate weather report, create my own Struct for my web service, and push it out to my subscribers.
The Problem
Once I had received my professor’s SOAP object back, I stepped into it to retrieve the zip codes from each entry. When I found the matching zip code, I mapped his keys and values to my own with a line of code like this:
return WeatherReport.new(:cityzip => row.cityzip, :temperature => row.temperature, :etc => ad naseum)
There are ten different attributes that my object must return to my subscribers, so it was slightly tedious to put all these things together. I prevailed.
When subscribing to my own web service via WSDL, however, I received the following exception:
Exception: Cannot map WeatherReport to SOAP/OM
WeatherReport is the name of the Struct that I was using as my return type. I began meticulously checking all my code. I had already written code to subscribe directly to my professor’s web service, so I checked the SOAP object coming back from that. I used a copy of the same code to subscribe in my own web service and could not figure out what was going on (hours pass).
I finally ran across this email archive that had a fix, but not an answer.
The Fix
I had to change my code to this:
return WeatherReport.new(:cityzip => "#{row.cityzip}", :temperature => "#{row.temperature}", :etc => "#{ad naseum}")
The “#{row.cityzip}” means that the object inside the {} should be interpreted as a variable and it’s value should appear in the string instead of the variable name. It’s just a shorthand way of concatenating strings with the values stored in string variables (and in case you were wondering, yes, you must use double quotes or it won’t work).
Now the most interesting thing about this error is that row.cityzip == "#{row.cityzip}", meaning that the expression evalutates to true. For all intents and purposes, these two strings are exactly the same.
Peter (the guy with the fix) speculates on what might be the cause, but he was also using the a Struct (via SOAP4R), so I assume that the problem’s source may lie in that class. Given the dearth of readily available information on the topic, I hope you find this useful.
WSDL, Rails, & Complex Data Types
This could also be considered part three of my HowTo: Put WSDL on Rails series, but it’s not really a HowTo in the strictest sense of the word. Therefore, this article is more of a monologue than a set of instructions.
If you’ve stuck with me this far you’ve probably figured out that I’m discovering things on my own shortly before I spew them all out here. In Howto: Put WSDL on Rails we built a simple web service that would accept a string parameter, modify it, and send the modified version back to the user. In Part 2, we subscribed to (and used) that same web service using only the WSDL. At the time I thought I was done, but as I’ve played around a bit more, I realized that there was another major part of web services. So now we’ll cover dealing with complex data types.
I began by wondering what kinds of things besides [:string] you could pass as parameters to and from a web service. I finally happened upon the Ruby on Rails manual that somehow I had not discovered up to this point. Why don’t these pages come up higher in the Google search results? Rails uses ActionWebService to interact with web services of all kinds and you can find the beginning of the manual here. You can find the specific answers to my questions here and here.
After reading this and mulling it over a bit, everything was pretty clear except for the so-called Structured Type parameters. I set out to gain a better understanding of this, and this is what I accomplished. First off, you’ll want to read up an something called a Struct. In essence an ActionWebService::Struct is a special kind of object that can be used for web services, but doesn’t have any ties to a database like an ActiveRecord::Base object.
I first defined a new struct in app/models/weather_report.rb of my WebServiceProvider.
class WeatherReport < ActionWebService::Struct
member :zip, :int
member :temp, :int
member :wind_speed, :int
member :wind_direction, :string
end
I then created the proper method in my API at app/apis/weather_api.rb:
api_method :get_weather, :expects => [:string], :returns => [WeatherReport]
And since I was really just curious to see how this works, I defined a very dynamic method in app/controllers/weather_controller.rb:
def get_weather(zip_code)
return WeatherReport.new(:zip => 84097, :temp => 55, :wind_speed => 5, :wind_direction => 'SW')
end
And that’s really all there is to it. If you’ve got a database driven application you could simply pass in one of the models that corresponds to a table on your database. So instead of an ActionWebService::Struct you could just pass in an ActiveRecord::Base object with the exact same syntax.
Now to see what comes out on the other end. In another application, I subscribed to my web service and in my view put <%= debug @result %> with @result being the result of my GetWeather call to the web service.
The debugged results came out like this.
#<soap::mapping::object:0x14868c6 {}zip="84097" {}wind_direction="SW" {}wind_speed="5" {}temp="55">
Carrying this logical line one step further, if a web service required a complex data type as input, we could build an ActionWebService::Struct object or use an appropriate ActiveRecord::Base object to pass into a third party web service. I see the struct option being much more useful ona day to day basis, but in a B2B environment, you can start to see a place for some real hard-core service interactions passing full-blown database-drive object types around between systems.
As I began to play around with web services, I thought they were pretty neat, but I’m beginning to see the how powerful they could be given the right set of circumstances.
Subscribe to RSS