From 1be3e32c8fa30dc0c990efbb0cee829546733a22 Mon Sep 17 00:00:00 2001 From: Jesse Lewis Date: Wed, 22 Aug 2012 16:06:01 -0500 Subject: [PATCH] Add a simple API for returning XML or JSON of problems --- Gemfile | 2 ++ Gemfile.lock | 12 ++++++++++++ app/controllers/api/v1/problems_controller.rb | 13 +++++++++++++ app/models/problem.rb | 5 +++++ app/views/api/v1/problems/index.rabl | 11 +++++++++++ config/initializers/rabl.rb | 20 ++++++++++++++++++++ config/routes.rb | 6 ++++++ spec/controllers/api/v1/problems_controller_spec.rb | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 127 insertions(+), 0 deletions(-) create mode 100644 app/controllers/api/v1/problems_controller.rb create mode 100644 app/views/api/v1/problems/index.rabl create mode 100644 config/initializers/rabl.rb create mode 100644 spec/controllers/api/v1/problems_controller_spec.rb diff --git a/Gemfile b/Gemfile index e81b7ea..88d8a4a 100644 --- a/Gemfile +++ b/Gemfile @@ -38,6 +38,7 @@ platform :ruby do end gem 'ri_cal' +gem 'rabl' gem 'yajl-ruby' group :development, :test do @@ -46,6 +47,7 @@ group :development, :test do unless ENV["CI"] gem 'ruby-debug', :platform => :mri_18 gem 'debugger', :platform => :mri_19 + gem 'pry' end # gem 'rpm_contrib' # gem 'newrelic_rpm' diff --git a/Gemfile.lock b/Gemfile.lock index d90ee44..ab2383b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -55,6 +55,7 @@ GEM xpath (~> 0.1.4) childprocess (0.3.5) ffi (~> 1.0, >= 1.0.6) + coderay (1.0.6) columnize (0.3.6) crack (0.3.1) css_parser (1.2.6) @@ -127,6 +128,7 @@ GEM i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) + method_source (0.7.1) mime-types (1.19) mongo (1.6.2) bson (~> 1.6.2) @@ -187,6 +189,13 @@ GEM premailer (1.7.3) css_parser (>= 1.1.9) htmlentities (>= 4.0.0) + pry (0.9.9.6) + coderay (~> 1.0.5) + method_source (~> 0.7.1) + slop (>= 2.4.4, < 3) + rabl (0.6.13) + activesupport (>= 2.3.14) + multi_json (~> 1.0) rack (1.4.1) rack-cache (1.2) rack (>= 0.4) @@ -248,6 +257,7 @@ GEM libwebsocket (~> 0.1.3) multi_json (~> 1.0) rubyzip + slop (2.4.4) sprockets (2.1.3) hike (~> 1.2) rack (~> 1.0) @@ -314,6 +324,8 @@ DEPENDENCIES omniauth-github oruen_redmine_client pivotal-tracker + pry + rabl rack-ssl-enforcer rails (= 3.2.6) rails_autolink (~> 1.0.9) diff --git a/app/controllers/api/v1/problems_controller.rb b/app/controllers/api/v1/problems_controller.rb new file mode 100644 index 0000000..8012bec --- /dev/null +++ b/app/controllers/api/v1/problems_controller.rb @@ -0,0 +1,13 @@ +class Api::V1::ProblemsController < ApplicationController + + def index + if params.key?(:start_date) && params.key?(:end_date) + start_date = Date.parse(params[:start_date]) + end_date = Date.parse(params[:end_date]) + @problems = Problem.in_date_range(start_date..end_date) + else + @problems = Problem.all + end + end + +end diff --git a/app/models/problem.rb b/app/models/problem.rb index 22561f4..5b7df8e 100644 --- a/app/models/problem.rb +++ b/app/models/problem.rb @@ -32,6 +32,7 @@ class Problem index :last_notice_at index :first_notice_at index :last_deploy_at + index :resolved_at index :notices_count belongs_to :app @@ -106,6 +107,10 @@ class Problem else raise("\"#{sort}\" is not a recognized sort") end end + + def self.in_date_range(date_range) + where(:first_notice_at.lte => date_range.end).where("$or" => [{:resolved_at => nil}, {:resolved_at.gte => date_range.begin}]) + end def reset_cached_attributes diff --git a/app/views/api/v1/problems/index.rabl b/app/views/api/v1/problems/index.rabl new file mode 100644 index 0000000..eff1642 --- /dev/null +++ b/app/views/api/v1/problems/index.rabl @@ -0,0 +1,11 @@ +collection @problems + +attributes :app_id, + :app_name, + :environment, + :message, + :where, + :first_notice_at, + :last_notice_at, + :resolved_at, + :notice_count diff --git a/config/initializers/rabl.rb b/config/initializers/rabl.rb new file mode 100644 index 0000000..0b89116 --- /dev/null +++ b/config/initializers/rabl.rb @@ -0,0 +1,20 @@ +Rabl.configure do |config| + # Commented as these are defaults + # config.cache_all_output = false + # config.cache_sources = Rails.env != 'development' # Defaults to false + # config.cache_engine = Rabl::CacheEngine.new # Defaults to Rails cache + # config.escape_all_output = false + # config.json_engine = nil # Any multi\_json engines + # config.msgpack_engine = nil # Defaults to ::MessagePack + # config.bson_engine = nil # Defaults to ::BSON + # config.plist_engine = nil # Defaults to ::Plist::Emit + # config.include_json_root = true + # config.include_msgpack_root = true + # config.include_bson_root = true + # config.include_plist_root = true + # config.include_xml_root = false + # config.include_child_root = true + # config.enable_json_callbacks = false + # config.xml_options = { :dasherize => true, :skip_types => false } + # config.view_paths = [] +end diff --git a/config/routes.rb b/config/routes.rb index 1e56004..5c5f5be 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -41,6 +41,12 @@ Errbit::Application.routes.draw do resources :deploys, :only => [:index] end + namespace :api do + namespace :v1 do + resources :problems, :only => [:index] + end + end + root :to => 'apps#index' end diff --git a/spec/controllers/api/v1/problems_controller_spec.rb b/spec/controllers/api/v1/problems_controller_spec.rb new file mode 100644 index 0000000..15f797d --- /dev/null +++ b/spec/controllers/api/v1/problems_controller_spec.rb @@ -0,0 +1,58 @@ +require 'spec_helper' + +describe Api::V1::ProblemsController do + + context "when logged in" do + before do + @user = Fabricate(:user) + end + + describe "GET /api/v1/problems" do + before do + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 01), resolved_at: Date.new(2012, 8, 02)) + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 01), resolved_at: Date.new(2012, 8, 21)) + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 21)) + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 30)) + end + + + + it "should return JSON if JSON is requested" do + get :index, auth_token: @user.authentication_token, format: "json" + lambda { JSON.load(response.body) }.should_not raise_error(JSON::ParserError) + end + + it "should return XML if XML is requested" do + get :index, auth_token: @user.authentication_token, format: "xml" + lambda { XML::Parser.string(response.body).parse }.should_not raise_error + end + + it "should return JSON by default" do + get :index, auth_token: @user.authentication_token + lambda { JSON.load(response.body) }.should_not raise_error(JSON::ParserError) + end + + + + describe "given a date range" do + + it "should return only the problems open during the date range" do + get :index, {auth_token: @user.authentication_token, start_date: "2012-08-20", end_date: "2012-08-27"} + response.should be_success + problems = JSON.load response.body + problems.length.should == 2 + end + + end + + it "should return all problems" do + get :index, {auth_token: @user.authentication_token} + response.should be_success + problems = JSON.load response.body + problems.length.should == 4 + end + + end + end + +end -- libgit2 0.21.2