bumbleworks-api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +25 -0
  8. data/Rakefile +9 -0
  9. data/bumbleworks-api.gemspec +32 -0
  10. data/config.ru +13 -0
  11. data/lib/bumbleworks/api.rb +15 -0
  12. data/lib/bumbleworks/api/config/application.rb +10 -0
  13. data/lib/bumbleworks/api/config/routes.rb +34 -0
  14. data/lib/bumbleworks/api/controllers/application_controller.rb +6 -0
  15. data/lib/bumbleworks/api/controllers/entities_controller.rb +25 -0
  16. data/lib/bumbleworks/api/controllers/errors_controller.rb +32 -0
  17. data/lib/bumbleworks/api/controllers/expressions_controller.rb +29 -0
  18. data/lib/bumbleworks/api/controllers/processes_controller.rb +29 -0
  19. data/lib/bumbleworks/api/controllers/tasks_controller.rb +43 -0
  20. data/lib/bumbleworks/api/controllers/trackers_controller.rb +13 -0
  21. data/lib/bumbleworks/api/controllers/workers_controller.rb +51 -0
  22. data/lib/bumbleworks/api/lib/presenter.rb +32 -0
  23. data/lib/bumbleworks/api/lib/presenters/entity_class_presenter.rb +19 -0
  24. data/lib/bumbleworks/api/lib/presenters/entity_presenter.rb +13 -0
  25. data/lib/bumbleworks/api/lib/presenters/error_presenter.rb +15 -0
  26. data/lib/bumbleworks/api/lib/presenters/expression_presenter.rb +17 -0
  27. data/lib/bumbleworks/api/lib/presenters/process_presenter.rb +32 -0
  28. data/lib/bumbleworks/api/lib/presenters/task_presenter.rb +15 -0
  29. data/lib/bumbleworks/api/lib/presenters/tracker_presenter.rb +16 -0
  30. data/lib/bumbleworks/api/lib/presenters/worker_presenter.rb +30 -0
  31. data/lib/bumbleworks/api/lib/time_support.rb +23 -0
  32. data/lib/bumbleworks/api/version.rb +5 -0
  33. data/playground_setup.rb +30 -0
  34. data/spec/controllers/entities_controller_spec.rb +32 -0
  35. data/spec/controllers/errors_controller_spec.rb +42 -0
  36. data/spec/controllers/expressions_controller_spec.rb +40 -0
  37. data/spec/controllers/processes_controller_spec.rb +50 -0
  38. data/spec/controllers/tasks_controller_spec.rb +82 -0
  39. data/spec/controllers/trackers_controller_spec.rb +25 -0
  40. data/spec/controllers/workers_controller_spec.rb +113 -0
  41. data/spec/fixtures/bumbleworks_config.rb +10 -0
  42. data/spec/fixtures/entities/mock_entity.rb +38 -0
  43. data/spec/fixtures/entities/widget.rb +9 -0
  44. data/spec/fixtures/entities/widgety_fidget.rb +5 -0
  45. data/spec/fixtures/participants.rb +3 -0
  46. data/spec/fixtures/participants/naughty_participant.rb +16 -0
  47. data/spec/fixtures/processes/error_process.rb +3 -0
  48. data/spec/fixtures/processes/task_process.rb +9 -0
  49. data/spec/fixtures/processes/waiting_process.rb +8 -0
  50. data/spec/lib/presenter_spec.rb +29 -0
  51. data/spec/lib/presenters/entity_class_presenter_spec.rb +17 -0
  52. data/spec/lib/presenters/entity_presenter_spec.rb +15 -0
  53. data/spec/lib/presenters/error_presenter_spec.rb +18 -0
  54. data/spec/lib/presenters/expression_presenter_spec.rb +33 -0
  55. data/spec/lib/presenters/process_presenter_spec.rb +42 -0
  56. data/spec/lib/presenters/task_presenter_spec.rb +18 -0
  57. data/spec/lib/presenters/tracker_presenter_spec.rb +18 -0
  58. data/spec/lib/presenters/worker_presenter_spec.rb +30 -0
  59. data/spec/lib/time_support_spec.rb +42 -0
  60. data/spec/spec_helper.rb +39 -0
  61. data/spec/support/api_helper.rb +23 -0
  62. data/spec/support/process_helpers.rb +11 -0
  63. metadata +261 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d0f86f86051a2e621368a53a5c74af63db5a3154
4
+ data.tar.gz: 1fff121f914e737a55b21858229d2515006897a3
5
+ SHA512:
6
+ metadata.gz: d814b339c6da019a9f9186420d0e4936518056f5bbdd987e5cda210ef4f024a8970e8652c0e3006ba968b38e5ad748208d48e430bbefa7c8012cc11277726108
7
+ data.tar.gz: 7ae23252e73232a10f13667fe6bb6fe2122041c7cf9dd91afc8d1529da2d9f4da36d85f5c565b4c4c009f59138106a636459aabb02aed4352f50aeb0965be1f8
@@ -0,0 +1,10 @@
1
+ *.gem
2
+ .bundle
3
+ .config
4
+ .yardoc
5
+ Gemfile.lock
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ pkg
10
+ tmp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format=nested
3
+ --require spec_helper
@@ -0,0 +1 @@
1
+ 2.1.1
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Bumbleworks
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ # Bumbleworks::Api
2
+
3
+ A rack-based web API (using [Rory](http://github.com/screamingmuse/rory)) for your [Bumbleworks](http://github.com/bumbleworks/bumbleworks) instance.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'bumbleworks-api'
10
+
11
+ ## Usage
12
+
13
+ There are quite a few ways to use this - the most common, if you're using Bumbleworks in a Rails app, would probably be to mount Bumbleworks::Api::Application at some path in your Rails routing - see the [Rails routing guide](http://guides.rubyonrails.org/routing.html#routing-to-rack-applications) for more info.
14
+
15
+ Or you can run it standalone using a Rack server - basically, Bumbleworks just needs to be configured, and then you can `run Bumbleworks::Api::Application`.
16
+
17
+ Note that you can also use [bumbleworks-gui](http://github.com/bumbleworks/bumbleworks-gui), which wraps this API in a simple GUI.
18
+
19
+ ## Contributing
20
+
21
+ 1. Fork it
22
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
23
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
24
+ 4. Push to the branch (`git push origin my-new-feature`)
25
+ 5. Create new Pull Request
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => [:spec]
8
+
9
+ Rake::TaskManager.record_task_metadata = true
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bumbleworks/api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bumbleworks-api"
8
+ spec.version = Bumbleworks::Api::VERSION
9
+ spec.authors = ["Ravi Gadad"]
10
+ spec.email = ["ravi@renewfund.com"]
11
+ spec.description = %q{Bumbleworks JSON API}
12
+ spec.summary = %q{This gem implements a headless Rory application (mountable in your own app)
13
+ for interacting with a Bumbleworks instance.}
14
+ spec.homepage = ""
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_runtime_dependency "bumbleworks", ">= 0.0.91"
23
+ spec.add_runtime_dependency "rory", ">= 0.5.2"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.3"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency 'shotgun'
28
+ spec.add_development_dependency 'rspec'
29
+ spec.add_development_dependency 'capybara'
30
+ spec.add_development_dependency 'simplecov'
31
+ spec.add_development_dependency 'pry'
32
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'playground_setup'
2
+
3
+ if ENV['MOUNT_AT']
4
+ app = Rack::Builder.new do
5
+ map ENV['MOUNT_AT'] do
6
+ run Bumbleworks::Api::Application
7
+ end
8
+ end
9
+ run app
10
+ else
11
+ run Bumbleworks::Api::Application
12
+ end
13
+
@@ -0,0 +1,15 @@
1
+ require "rory"
2
+ require "rack"
3
+ require "bumbleworks"
4
+ require "json"
5
+ require_relative "api/version"
6
+ require_relative "api/controllers/application_controller"
7
+
8
+ Rufus::Json.detect_backend
9
+
10
+ module Bumbleworks
11
+ module Api
12
+ end
13
+ end
14
+
15
+ require_relative "api/config/application"
@@ -0,0 +1,10 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class Application < Rory::Application
4
+ end
5
+ end
6
+ end
7
+
8
+ Bumbleworks::Api::Application.root = File.expand_path('..', File.dirname(__FILE__))
9
+ Bumbleworks::Api::Application.auto_require_paths << 'lib'
10
+ Bumbleworks::Api::Application.require_all_files
@@ -0,0 +1,34 @@
1
+ Bumbleworks::Api::Application.set_routes do
2
+ scope :module => 'bumbleworks/api' do
3
+ match '/entities', :to => 'entities#types', :methods => [:get]
4
+ match '/entities/:type', :to => 'entities#index', :methods => [:get]
5
+ match '/entities/:type/:id', :to => 'entities#show', :methods => [:get]
6
+
7
+ match '/processes', :to => 'processes#index', :methods => [:get]
8
+ match '/processes/:id', :to => 'processes#show', :methods => [:get]
9
+
10
+ match '/tasks', :to => 'tasks#index', :methods => [:get]
11
+ match '/tasks/:id', :to => 'tasks#show', :methods => [:get]
12
+
13
+ match '/tasks/:id/claim', :to => 'tasks#claim', :methods => [:put]
14
+ match '/tasks/:id/release', :to => 'tasks#release', :methods => [:put]
15
+ match '/tasks/:id/complete', :to => 'tasks#complete', :methods => [:put]
16
+
17
+ match '/trackers', :to => 'trackers#index', :methods => [:get]
18
+ match '/trackers/:id', :to => 'trackers#show', :methods => [:get]
19
+
20
+ match '/errors', :to => 'errors#index', :methods => [:get]
21
+ match '/processes/:pid/expressions/:id/error', :to => 'errors#show', :methods => [:get]
22
+ match '/processes/:pid/expressions/:id/error/replay', :to => 'errors#replay', :methods => [:put]
23
+
24
+ match '/processes/:pid/expressions/:id', :to => 'expressions#show', :methods => [:get]
25
+ match '/processes/:pid/expressions/:id/cancel', :to => 'expressions#cancel', :methods => [:delete]
26
+ match '/processes/:pid/expressions/:id/kill', :to => 'expressions#kill', :methods => [:delete]
27
+
28
+ match '/workers', :to => 'workers#index', :methods => [:get]
29
+ match '/workers/prune', :to => 'workers#prune_stale_worker_info', :methods => [:delete]
30
+ match '/workers/command/:command', :to => 'workers#change_global_state', :methods => [:put]
31
+ match '/workers/:id', :to => 'workers#show', :methods => [:get]
32
+ match '/workers/:id/command/:command', :to => 'workers#change_state', :methods => [:put]
33
+ end
34
+ end
@@ -0,0 +1,6 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class ApplicationController < Rory::Controller
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,25 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class EntitiesController < ApplicationController
4
+ def types
5
+ render :json => EntityClassPresenter.present(Bumbleworks.entity_classes)
6
+ end
7
+
8
+ def index
9
+ render :json => EntityPresenter.present(entity_class.all)
10
+ end
11
+
12
+ def show
13
+ entity = entity_class.first_by_identifier(params[:id])
14
+ render :json => EntityPresenter.present(entity)
15
+ end
16
+
17
+ private
18
+
19
+ def entity_class
20
+ class_name = Bumbleworks::Support.camelize(params[:type])
21
+ entity_class = Bumbleworks::Support.constantize(class_name)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,32 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class ErrorsController < ApplicationController
4
+ def index
5
+ render :json => Bumbleworks::Api::ErrorPresenter.present(Bumbleworks.errors)
6
+ end
7
+
8
+ def show
9
+ render :json => Bumbleworks::Api::ErrorPresenter.present(error)
10
+ end
11
+
12
+ def replay
13
+ error.replay
14
+ render :json => { :status => 'replayed' }
15
+ end
16
+
17
+ private
18
+
19
+ def expression
20
+ process.expression_at_position(params[:id])
21
+ end
22
+
23
+ def error
24
+ expression.error
25
+ end
26
+
27
+ def process
28
+ Bumbleworks::Process.new(params[:pid])
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class ExpressionsController < ApplicationController
4
+ def show
5
+ render :json => Bumbleworks::Api::ExpressionPresenter.present(expression)
6
+ end
7
+
8
+ def cancel
9
+ expression.cancel!
10
+ render :json => { "status" => "cancelled" }
11
+ end
12
+
13
+ def kill
14
+ expression.kill!
15
+ render :json => { "status" => "killed" }
16
+ end
17
+
18
+ private
19
+
20
+ def expression
21
+ process.expression_at_position(params[:id])
22
+ end
23
+
24
+ def process
25
+ Bumbleworks::Process.new(params[:pid])
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class ProcessesController < ApplicationController
4
+ def index
5
+ processes = Bumbleworks::Process.all(:limit => limit, :offset => offset)
6
+ render :json => Bumbleworks::Api::ProcessPresenter.present(processes)
7
+ end
8
+
9
+ def show
10
+ process = Bumbleworks::Process.new(params[:id])
11
+ render :json => Bumbleworks::Api::ProcessPresenter.present(process)
12
+ end
13
+
14
+ private
15
+
16
+ def page
17
+ params.fetch(:page) { 1 }.to_i
18
+ end
19
+
20
+ def limit
21
+ params.fetch(:limit) { 10 }.to_i
22
+ end
23
+
24
+ def offset
25
+ (page - 1) * limit
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,43 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class TasksController < ApplicationController
4
+ def index
5
+ render :json => Bumbleworks::Api::TaskPresenter.present(Bumbleworks::Task.all)
6
+ end
7
+
8
+ def show
9
+ render :json => Bumbleworks::Api::TaskPresenter.present(task)
10
+ end
11
+
12
+ def claim
13
+ task.claim(params[:claimant])
14
+ render :json => Bumbleworks::Api::TaskPresenter.present(task)
15
+ end
16
+
17
+ def release
18
+ task.release
19
+ render :json => Bumbleworks::Api::TaskPresenter.present(task)
20
+ end
21
+
22
+ def complete
23
+ task.complete(params_without_id)
24
+ render :json => { :status => 'completed' }
25
+ rescue Bumbleworks::Task::NotCompletable => e
26
+ render :json => {
27
+ :status => 'not_completable',
28
+ :message => e.message
29
+ }, :status => 422
30
+ end
31
+
32
+ private
33
+
34
+ def task
35
+ Bumbleworks::Task.find_by_id(params[:id])
36
+ end
37
+
38
+ def params_without_id
39
+ params.reject { |k,v| k.to_s == "id" }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class TrackersController < ApplicationController
4
+ def index
5
+ render :json => Bumbleworks::Api::TrackerPresenter.present(Bumbleworks::Tracker.all)
6
+ end
7
+
8
+ def show
9
+ render :json => Bumbleworks::Api::TrackerPresenter.present(Bumbleworks::Tracker.new(params[:id]))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ module Bumbleworks
2
+ module Api
3
+ class WorkersController < ApplicationController
4
+ AllowedCommands = ["pause", "unpause", "shutdown"]
5
+
6
+ before_action :refresh_worker_info, :only => [:index, :show]
7
+
8
+ def index
9
+ worker_info = Bumbleworks::Worker::Info.all
10
+ render :json => Bumbleworks::Api::WorkerPresenter.present(worker_info)
11
+ end
12
+
13
+ def show
14
+ worker_info = Bumbleworks::Worker::Info[params[:id]]
15
+ render :json => Bumbleworks::Api::WorkerPresenter.present(worker_info)
16
+ end
17
+
18
+ def change_state
19
+ command = params[:command]
20
+ if AllowedCommands.include?(command.to_s)
21
+ worker_info = Bumbleworks::Worker::Info[params[:id]]
22
+ worker_info.send(command)
23
+ render :json => { "status" => "#{command} sent" }
24
+ else
25
+ render :json => { "error" => "not_found" }, :status => 404
26
+ end
27
+ end
28
+
29
+ def change_global_state
30
+ command = params[:command]
31
+ if AllowedCommands.include?(command.to_s)
32
+ Bumbleworks::Worker.send("#{command}_all")
33
+ render :json => { "status" => "#{command} sent" }
34
+ else
35
+ render :json => { "error" => "not_found" }, :status => 404
36
+ end
37
+ end
38
+
39
+ def prune_stale_worker_info
40
+ Bumbleworks::Worker::Info.purge_stale_worker_info
41
+ render :json => { "status" => "pruned_stale_worker_info" }
42
+ end
43
+
44
+ private
45
+
46
+ def refresh_worker_info
47
+ Bumbleworks::Worker.refresh_worker_info
48
+ end
49
+ end
50
+ end
51
+ end