Commit 526e1e74 authored by John E. Vincent's avatar John E. Vincent

final 1.0 API for applications and configurations

parent 1941fd0c
......@@ -82,6 +82,32 @@ module Noah
r.to_json
end
def add_config_to_app(appname, config_hash)
begin
config = Noah::Configuration.find_or_create(config_hash)
if config.valid?
dep_action = config.is_new? ? "create" : "update"
else
raise "#{format_errors(config)}"
end
app = Noah::Application.find_or_create(:name => appname)
if app.valid?
action = app.is_new? ? "create" : "update"
app.configurations << config
r = {"result" => "success", "id" => "#{app.id}", "name" => "#{app.name}", "action" => action, "configuration" => {"action" => dep_action, "id" => "#{config.id}", "item" => "#{config.name}"}}
r.to_json
else
raise "#{format_errors(app)}"
end
rescue Exception => e
e.message
ensure
# Clean up partial objects
app.delete if app.valid? == false
config.delete if config.valid? == false
end
end
def application(opts = {})
Noah::Application.find(opts).first
end
......
......@@ -20,7 +20,8 @@ module Noah
configurations.sort.each do |cfg|
cfg_hash["#{cfg.name}"] = {:format => cfg.to_hash[:format], :body => cfg.to_hash[:body]}
end
{name => {:id => id, :created_at => created_at, :updated_at => updated_at, :configurations => cfg_hash}}
res_hash = {:name => name, :created_at => created_at, :updated_at => updated_at, :configurations => cfg_hash}
super.merge(res_hash)
end
class << self
......@@ -43,8 +44,7 @@ module Noah
def self.all(options = {})
app_hash = Hash.new
options.empty? ? apps=Application.all.sort : apps=Application.find(options).sort
#apps.each {|x| app_hash["#{x.name}"] = x.to_hash.reject {|k,v| k == :name} }
apps.each {|x| app_hash.merge!(x.to_hash) }
apps.each {|x| app_hash["#{x.name}"] = x.to_hash.reject {|k,v| k == :name} }
app_hash
end
end
......
......@@ -44,9 +44,13 @@ module Noah
class << self
def find_or_create(opts={})
begin
find(opts).first.nil? ? (obj = new(opts)) : (obj = find(opts).first)
if obj.valid?
find(:name => opts[:name]).first.nil? ? (obj = new(opts)) : (obj = find(:name => opts[:name]).first)
if obj.valid? && obj.new?
obj.save
else
obj.format = opts[:format]
obj.body = opts[:body]
obj.save if obj.valid?
end
obj
rescue Exception => e
......
class Noah::App
# Application URIs
get '/applications/:appname/:config/?' do |appname, config|
get '/applications/:appname/configurations/:config/?' do |appname, config|
app = Noah::Application.find(:name => appname).first
(halt 404) if app.nil?
c = app.configurations.find(:name => config).first
c.to_json
request.path_info = "/configurations/#{config}"
pass
end
get '/applications/:appname/?' do |appname|
......@@ -37,6 +37,14 @@ class Noah::App
a.to_json
end
put '/applications/:appname/configurations/:configname/?' do |appname, configname|
required_params = ["format", "body"]
raise "Missing Parameters" if request.body.nil?
data = JSON.parse(request.body.read)
raise "Missing Parameters" if data.keys.sort != required_params.sort
add_config_to_app(appname, {:name => configname, :format => data['format'], :body => data['body']})
end
put '/applications/:appname/?' do |appname|
required_params = ["name"]
data = JSON.parse(request.body.read)
......@@ -64,6 +72,17 @@ class Noah::App
end
delete '/applications/:appname/configurations/:configname/?' do |appname, configname|
app = Noah::Application.find(:name => appname).first
(halt 404) if app.nil?
config = Noah::Configuration.find(:name => configname).first
(halt 404) if config.nil?
if app.configurations.member?(config)
app.configurations.delete(config)
r = {"result" => "success", "action" => "delete", "id" => "#{app.id}", "name" => "#{app.name}", "configuration" => "#{config.name}"}
r.to_json
else
halt 404
end
end
get '/applications/?' do
......
......@@ -5,19 +5,17 @@ class Noah::App
:xml => "text/xml",
:string => "text/plain"
}
# GET the raw data of a configuration object
get '/configurations/:configname/data/?' do |configname|
get '/configurations/:configname/?', :provides => :json do |configname|
c = Noah::Configuration.find(:name => configname).first
(halt 404) if c.nil?
content_type content_type_mapping[c.format.to_sym] if content_type_mapping[c.format.to_sym]
response.headers['Content-Disposition'] = "attachment; filename=#{configname}"
c.body
c.to_json
end
# GET the JSON representation of a configuration object
get '/configurations/:configname/?' do |configname|
c = Noah::Configuration.find(:name => configname).first
(halt 404) if c.nil?
c.to_json
content_type content_type_mapping[c.format.to_sym] if content_type_mapping[c.format.to_sym]
#response.headers['Content-Disposition'] = "attachment; filename=#{configname}"
c.body
end
# GET all configurations
get '/configurations/?' do
......
......@@ -2,7 +2,9 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
describe "Using the Application API", :reset_redis => false do
before(:all) do
Ohm.redis.flushdb
@a = Noah::Application.create(:name => 'rspec_sample_app')
@b = Noah::Application.create(:name => 'rspec_sample_app_2')
@c = Noah::Configuration.create(:name => 'rspec_config', :format => 'string', :body => 'rspec is great')
@a.configurations << @c
@a.save
......@@ -15,30 +17,39 @@ describe "Using the Application API", :reset_redis => false do
last_response.should be_ok
response = last_response.should return_json
response.is_a?(Hash).should == true
response.size.should == 2
end
it "named application should work" do
get '/applications/rspec_sample_app'
last_response.should be_ok
response = last_response.should return_json
response.has_key?(@a.name).should == true
response[@a.name].class.to_s.should == 'Hash'
response[@a.name]["id"].should == @a.id.to_s
response[@a.name].has_key?("configurations").should == true
c = response[@a.name]["configurations"]
response["id"].should == @a.id.to_s
response["name"].should == @a.name
response.has_key?("configurations").should == true
c = response["configurations"]
c.has_key?(@c.name).should == true
c["#{@c.name}"]["format"].should == "#{@c.format}"
c["#{@c.name}"]["body"].should == "#{@c.body}"
end
it "named configuration for application should work" do
get "/applications/#{@a.name}/#{@c.name}"
it "named configuration for application should work as JSON" do
header "Accept", "application/json"
get "/applications/#{@a.name}/configurations/#{@c.name}"
last_response.should be_ok
response = last_response.should return_json
response["id"].should == @c.id
response["name"].should == @c.name
response["format"].should == @c.format
response["body"].should == @c.body
end
it "named configuration for application should work as raw" do
header "Accept", "application/octet"
get "/applications/#{@a.name}/configurations/#{@c.name}"
last_response.should be_ok
headers = last_response.headers
body = last_response.body
headers["Content-Type"].should == 'text/plain;charset=utf-8'
body.should == @c.body
end
it "invalid application should not work" do
get "/applications/should_not_exist"
last_response.should be_missing
......@@ -64,6 +75,7 @@ describe "Using the Application API", :reset_redis => false do
Noah::Application.find(:name => @appdata[:name]).size.should == 1
Noah::Application.find(:name => @appdata[:name]).first.is_new?.should == true
end
it "new application with new configuration should work"
it "new application with missing name should not work" do
put "/applications/should_not_work", '{"foo":"bar"}', "CONTENT_TYPE" => "application/json"
last_response.should be_invalid
......@@ -80,7 +92,9 @@ describe "Using the Application API", :reset_redis => false do
response["action"].should == "update"
Noah::Application.find(:name => @appdata[:name]).size.should == 1
Noah::Application.find(:name => @appdata[:name]).first.is_new?.should == false
end
end
it "existing application with new configuration"
it "existing application with existing configuration"
end
describe "DELETE" do
......
......@@ -41,7 +41,8 @@ describe "Using the Configuration API", :reset_redis => true, :populate_sample_d
end
end
end
it "named configuration should work" do
it "named configuration should work as JSON" do
header "Accept", "application/json"
get '/configurations/redis_url'
last_response.should be_ok
response = last_response.should return_json
......@@ -55,7 +56,7 @@ describe "Using the Configuration API", :reset_redis => true, :populate_sample_d
end
it "named configuration should work with mime-type" do
require 'yaml'
get '/configurations/yaml_config/data'
get '/configurations/yaml_config'
last_response.should be_ok
last_response.headers["Content-Type"].should == "text/x-yaml;charset=utf-8"
response = YAML.load(last_response.body)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment