Re.Mark

Ruby Tuesday #14 : Creating an Authority

Posted in Architecture, Development, Ruby by remark on July 15, 2008

This week I decided to put my new-found Ruby knowledge to practical use.  Marc has embarked on a micro quest to build a game in WPF.  I’m going to contribute to the project along the way – the first contribution was to write basic save and load routines for maps.  The next step is to enhance that to support SQL Server Data Services – (I’ll blog about the non-Ruby elements to this another time.)  SQL Server Data Services (SSDS) uses an authority as the highest level of storage.  Authorities contain containers, which in turn contain entities.  The first step, then, is to create an authority.  This step is a one-off operation, so it lends itself to an administrative script – I figured Ruby would be a good choice for this task.

As it turns out, someone else must also figure Ruby is a good choice because there’s documentation on MSDN about how to create an authority using Ruby here.  In fact, it looks like there’s Ruby samples for all of the REST interface to SSDS.  Instead of just copying the code and creating the authority, I thought I’d take some of the code I’d written for the Twitter client and re-use it (copy and paste style) for this task.  I wanted the code to be as simple as possible and I ended up with this:

require 'net/https'
require 'rexml/document'

username = 'your user name goes here'
password = 'your password goes here'
authority_id = 'and here is where you put your authority id';

req_xml = "<s:Authority xmlns:s='http://schemas.microsoft.com/sitka/2008/03/'><s:Id>#{authority_id}</s:Id></s:Authority>";

response = ""

http = Net::HTTP.new('data.beta.mssds.com', 443)
http.use_ssl = true
http.start do |http|
  request = Net::HTTP::Post.new("/v1/")
  request.basic_auth(username, password)
  request['Content-Type'] = 'application/xml'
  request['Content-Length'] = req_xml.to_s.size.to_s
  request.basic_auth(username, password)
  response = http.request(request, req_xml)
end

case response
when Net::HTTPSuccess then
  puts authority_id + ' created'
  error = false
when Net::HTTPForbidden then
  puts "SSDS Access denied"
  error = true
when Net::HTTPBadRequest then
  puts "Request is not valid"
  error = true
when Net::HTTPConflict then
  puts "SSDS Authority already exists"
  error = true
else
  puts "Unexpected Error"
  error = true
end
if(error)
  # process the http response body
  xml = REXML::Document.new(response.body)
  puts "Error: #{xml.root().elements[1].name} => #{xml.root().elements[1].text}"
  puts "Error: #{xml.root().elements[2].name} => #{xml.root().elements[2].text}"
end

The big difference between this and the Twitter code is the use of SSL.  That’s led to a few differences in the use of the Net::HTTP library.  The code in the MSDN example can also handle proxies, which my code can’t, so it’s worth a look at how that’s accomplished.  The code works and I now have a freshly minted authority – I fell foul of the naming rules a couple of times (e.g. authorities can only contain lowercase characters, numbers and hyphens – more info here), but the error reporting is great at pointing out exactly what you’ve done wrong.  And with the code for creating an authority complete, creating a container should be straightforward.

Leave a Reply