Commit 1be3e32c8fa30dc0c990efbb0cee829546733a22

Authored by Jesse Lewis
Committed by Robert Lail
1 parent 6a9f6310
Exists in master and in 1 other branch production

Add a simple API for returning XML or JSON of problems

- Use RABL to render response
- Use Devise's token authentication
Gemfile
... ... @@ -38,6 +38,7 @@ platform :ruby do
38 38 end
39 39  
40 40 gem 'ri_cal'
  41 +gem 'rabl'
41 42 gem 'yajl-ruby'
42 43  
43 44 group :development, :test do
... ... @@ -46,6 +47,7 @@ group :development, :test do
46 47 unless ENV["CI"]
47 48 gem 'ruby-debug', :platform => :mri_18
48 49 gem 'debugger', :platform => :mri_19
  50 + gem 'pry'
49 51 end
50 52 # gem 'rpm_contrib'
51 53 # gem 'newrelic_rpm'
... ...
Gemfile.lock
... ... @@ -55,6 +55,7 @@ GEM
55 55 xpath (~> 0.1.4)
56 56 childprocess (0.3.5)
57 57 ffi (~> 1.0, >= 1.0.6)
  58 + coderay (1.0.6)
58 59 columnize (0.3.6)
59 60 crack (0.3.1)
60 61 css_parser (1.2.6)
... ... @@ -127,6 +128,7 @@ GEM
127 128 i18n (>= 0.4.0)
128 129 mime-types (~> 1.16)
129 130 treetop (~> 1.4.8)
  131 + method_source (0.7.1)
130 132 mime-types (1.19)
131 133 mongo (1.6.2)
132 134 bson (~> 1.6.2)
... ... @@ -187,6 +189,13 @@ GEM
187 189 premailer (1.7.3)
188 190 css_parser (>= 1.1.9)
189 191 htmlentities (>= 4.0.0)
  192 + pry (0.9.9.6)
  193 + coderay (~> 1.0.5)
  194 + method_source (~> 0.7.1)
  195 + slop (>= 2.4.4, < 3)
  196 + rabl (0.6.13)
  197 + activesupport (>= 2.3.14)
  198 + multi_json (~> 1.0)
190 199 rack (1.4.1)
191 200 rack-cache (1.2)
192 201 rack (>= 0.4)
... ... @@ -248,6 +257,7 @@ GEM
248 257 libwebsocket (~> 0.1.3)
249 258 multi_json (~> 1.0)
250 259 rubyzip
  260 + slop (2.4.4)
251 261 sprockets (2.1.3)
252 262 hike (~> 1.2)
253 263 rack (~> 1.0)
... ... @@ -314,6 +324,8 @@ DEPENDENCIES
314 324 omniauth-github
315 325 oruen_redmine_client
316 326 pivotal-tracker
  327 + pry
  328 + rabl
317 329 rack-ssl-enforcer
318 330 rails (= 3.2.6)
319 331 rails_autolink (~> 1.0.9)
... ...
app/controllers/api/v1/problems_controller.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class Api::V1::ProblemsController < ApplicationController
  2 +
  3 + def index
  4 + if params.key?(:start_date) && params.key?(:end_date)
  5 + start_date = Date.parse(params[:start_date])
  6 + end_date = Date.parse(params[:end_date])
  7 + @problems = Problem.in_date_range(start_date..end_date)
  8 + else
  9 + @problems = Problem.all
  10 + end
  11 + end
  12 +
  13 +end
... ...
app/models/problem.rb
... ... @@ -32,6 +32,7 @@ class Problem
32 32 index :last_notice_at
33 33 index :first_notice_at
34 34 index :last_deploy_at
  35 + index :resolved_at
35 36 index :notices_count
36 37  
37 38 belongs_to :app
... ... @@ -106,6 +107,10 @@ class Problem
106 107 else raise("\"#{sort}\" is not a recognized sort")
107 108 end
108 109 end
  110 +
  111 + def self.in_date_range(date_range)
  112 + where(:first_notice_at.lte => date_range.end).where("$or" => [{:resolved_at => nil}, {:resolved_at.gte => date_range.begin}])
  113 + end
109 114  
110 115  
111 116 def reset_cached_attributes
... ...
app/views/api/v1/problems/index.rabl 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +collection @problems
  2 +
  3 +attributes :app_id,
  4 + :app_name,
  5 + :environment,
  6 + :message,
  7 + :where,
  8 + :first_notice_at,
  9 + :last_notice_at,
  10 + :resolved_at,
  11 + :notice_count
... ...
config/initializers/rabl.rb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +Rabl.configure do |config|
  2 + # Commented as these are defaults
  3 + # config.cache_all_output = false
  4 + # config.cache_sources = Rails.env != 'development' # Defaults to false
  5 + # config.cache_engine = Rabl::CacheEngine.new # Defaults to Rails cache
  6 + # config.escape_all_output = false
  7 + # config.json_engine = nil # Any multi\_json engines
  8 + # config.msgpack_engine = nil # Defaults to ::MessagePack
  9 + # config.bson_engine = nil # Defaults to ::BSON
  10 + # config.plist_engine = nil # Defaults to ::Plist::Emit
  11 + # config.include_json_root = true
  12 + # config.include_msgpack_root = true
  13 + # config.include_bson_root = true
  14 + # config.include_plist_root = true
  15 + # config.include_xml_root = false
  16 + # config.include_child_root = true
  17 + # config.enable_json_callbacks = false
  18 + # config.xml_options = { :dasherize => true, :skip_types => false }
  19 + # config.view_paths = []
  20 +end
... ...
config/routes.rb
... ... @@ -41,6 +41,12 @@ Errbit::Application.routes.draw do
41 41 resources :deploys, :only => [:index]
42 42 end
43 43  
  44 + namespace :api do
  45 + namespace :v1 do
  46 + resources :problems, :only => [:index]
  47 + end
  48 + end
  49 +
44 50 root :to => 'apps#index'
45 51  
46 52 end
... ...
spec/controllers/api/v1/problems_controller_spec.rb 0 → 100644
... ... @@ -0,0 +1,58 @@
  1 +require 'spec_helper'
  2 +
  3 +describe Api::V1::ProblemsController do
  4 +
  5 + context "when logged in" do
  6 + before do
  7 + @user = Fabricate(:user)
  8 + end
  9 +
  10 + describe "GET /api/v1/problems" do
  11 + before do
  12 + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 01), resolved_at: Date.new(2012, 8, 02))
  13 + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 01), resolved_at: Date.new(2012, 8, 21))
  14 + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 21))
  15 + Fabricate(:problem, first_notice_at: Date.new(2012, 8, 30))
  16 + end
  17 +
  18 +
  19 +
  20 + it "should return JSON if JSON is requested" do
  21 + get :index, auth_token: @user.authentication_token, format: "json"
  22 + lambda { JSON.load(response.body) }.should_not raise_error(JSON::ParserError)
  23 + end
  24 +
  25 + it "should return XML if XML is requested" do
  26 + get :index, auth_token: @user.authentication_token, format: "xml"
  27 + lambda { XML::Parser.string(response.body).parse }.should_not raise_error
  28 + end
  29 +
  30 + it "should return JSON by default" do
  31 + get :index, auth_token: @user.authentication_token
  32 + lambda { JSON.load(response.body) }.should_not raise_error(JSON::ParserError)
  33 + end
  34 +
  35 +
  36 +
  37 + describe "given a date range" do
  38 +
  39 + it "should return only the problems open during the date range" do
  40 + get :index, {auth_token: @user.authentication_token, start_date: "2012-08-20", end_date: "2012-08-27"}
  41 + response.should be_success
  42 + problems = JSON.load response.body
  43 + problems.length.should == 2
  44 + end
  45 +
  46 + end
  47 +
  48 + it "should return all problems" do
  49 + get :index, {auth_token: @user.authentication_token}
  50 + response.should be_success
  51 + problems = JSON.load response.body
  52 + problems.length.should == 4
  53 + end
  54 +
  55 + end
  56 + end
  57 +
  58 +end
... ...