ocean-rails 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +72 -0
- data/Rakefile +38 -0
- data/lib/generators/ocean_scaffold/USAGE +8 -0
- data/lib/generators/ocean_scaffold/ocean_scaffold_generator.rb +76 -0
- data/lib/generators/ocean_scaffold/templates/controller_specs/create_spec.rb +71 -0
- data/lib/generators/ocean_scaffold/templates/controller_specs/delete_spec.rb +47 -0
- data/lib/generators/ocean_scaffold/templates/controller_specs/index_spec.rb +45 -0
- data/lib/generators/ocean_scaffold/templates/controller_specs/show_spec.rb +43 -0
- data/lib/generators/ocean_scaffold/templates/controller_specs/update_spec.rb +85 -0
- data/lib/generators/ocean_scaffold/templates/model_spec.rb +76 -0
- data/lib/generators/ocean_scaffold/templates/resource_routing_spec.rb +27 -0
- data/lib/generators/ocean_scaffold/templates/view_specs/_resource_spec.rb +55 -0
- data/lib/generators/ocean_scaffold/templates/views/_resource.json.jbuilder +8 -0
- data/lib/generators/ocean_setup/USAGE +8 -0
- data/lib/generators/ocean_setup/ocean_setup_generator.rb +93 -0
- data/lib/generators/ocean_setup/templates/Gemfile +19 -0
- data/lib/generators/ocean_setup/templates/alive_controller.rb +18 -0
- data/lib/generators/ocean_setup/templates/alive_routing_spec.rb +11 -0
- data/lib/generators/ocean_setup/templates/alive_spec.rb +12 -0
- data/lib/generators/ocean_setup/templates/api_constants.rb +19 -0
- data/lib/generators/ocean_setup/templates/application_controller.rb +8 -0
- data/lib/generators/ocean_setup/templates/application_helper.rb +34 -0
- data/lib/generators/ocean_setup/templates/config.yml.example +57 -0
- data/lib/generators/ocean_setup/templates/errors_controller.rb +14 -0
- data/lib/generators/ocean_setup/templates/gitignore +37 -0
- data/lib/generators/ocean_setup/templates/hyperlinks.rb +22 -0
- data/lib/generators/ocean_setup/templates/ocean_constants.rb +36 -0
- data/lib/generators/ocean_setup/templates/routes.rb +8 -0
- data/lib/generators/ocean_setup/templates/spec_helper.rb +47 -0
- data/lib/generators/ocean_setup/templates/zeromq_logger.rb +15 -0
- data/lib/ocean-rails.rb +38 -0
- data/lib/ocean/api.rb +263 -0
- data/lib/ocean/api_resource.rb +135 -0
- data/lib/ocean/flooding.rb +29 -0
- data/lib/ocean/ocean_application_controller.rb +214 -0
- data/lib/ocean/ocean_resource_controller.rb +76 -0
- data/lib/ocean/ocean_resource_model.rb +61 -0
- data/lib/ocean/selective_rack_logger.rb +33 -0
- data/lib/ocean/version.rb +3 -0
- data/lib/ocean/zero_log.rb +184 -0
- data/lib/ocean/zeromq_logger.rb +42 -0
- data/lib/tasks/ocean_tasks.rake +4 -0
- data/lib/template.rb +31 -0
- data/lib/templates/rails/scaffold_controller/controller.rb +91 -0
- metadata +267 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe <%= class_name %> do
|
4
|
+
|
5
|
+
|
6
|
+
describe "attributes" do
|
7
|
+
|
8
|
+
it "should have a name" do
|
9
|
+
create(:<%= singular_name %>).name.should be_a String
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should have a description" do
|
13
|
+
create(:<%= singular_name %>).description.should be_a String
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have a creation time" do
|
17
|
+
create(:<%= singular_name %>).created_at.should be_a Time
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should have an update time" do
|
21
|
+
create(:<%= singular_name %>).updated_at.should be_a Time
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should have a creator" do
|
25
|
+
create(:<%= singular_name %>).created_by.should be_an Integer
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have an updater" do
|
29
|
+
create(:<%= singular_name %>).updated_by.should be_an Integer
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
describe "relations" do
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
describe "search" do
|
42
|
+
|
43
|
+
describe ".collection" do
|
44
|
+
|
45
|
+
before :each do
|
46
|
+
create :<%= singular_name %>, name: 'foo', description: "The Foo object"
|
47
|
+
create :<%= singular_name %>, name: 'bar', description: "The Bar object"
|
48
|
+
create :<%= singular_name %>, name: 'baz', description: "The Baz object"
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
it "should return an array of <%= class_name %> instances" do
|
53
|
+
ix = <%= class_name %>.collection
|
54
|
+
ix.length.should == 3
|
55
|
+
ix[0].should be_a <%= class_name %>
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should allow matches on name" do
|
59
|
+
<%= class_name %>.collection(name: 'NOWAI').length.should == 0
|
60
|
+
<%= class_name %>.collection(name: 'bar').length.should == 1
|
61
|
+
<%= class_name %>.collection(name: 'baz').length.should == 1
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should allow searches on description" do
|
65
|
+
<%= class_name %>.collection(search: 'a').length.should == 2
|
66
|
+
<%= class_name %>.collection(search: 'object').length.should == 3
|
67
|
+
end
|
68
|
+
|
69
|
+
it "key/value pairs not in the index_only array should quietly be ignored" do
|
70
|
+
<%= class_name %>.collection(name: 'bar', aardvark: 12).length.should == 1
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe <%= class_name.pluralize %>Controller do
|
4
|
+
describe "routing" do
|
5
|
+
|
6
|
+
it "routes to #index" do
|
7
|
+
get("/v1/<%= plural_name %>").should route_to("<%= plural_name %>#index")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "routes to #show" do
|
11
|
+
get("/v1/<%= plural_name %>/1").should route_to("<%= plural_name %>#show", id: "1")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "routes to #create" do
|
15
|
+
post("/v1/<%= plural_name %>").should route_to("<%= plural_name %>#create")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "routes to #update" do
|
19
|
+
put("/v1/<%= plural_name %>/1").should route_to("<%= plural_name %>#update", id: "1")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "routes to #destroy" do
|
23
|
+
delete("/v1/<%= plural_name %>/1").should route_to("<%= plural_name %>#destroy", id: "1")
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "<%= plural_name %>/_<%= singular_name %>" do
|
4
|
+
|
5
|
+
before :each do # Must be :each (:all causes all tests to fail)
|
6
|
+
render partial: "<%= plural_name %>/<%= singular_name %>", locals: {<%= singular_name %>: create(:<%= singular_name %>)}
|
7
|
+
@json = JSON.parse(rendered)
|
8
|
+
@u = @json['<%= singular_name %>']
|
9
|
+
@links = @u['_links'] rescue {}
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
it "has a named root" do
|
14
|
+
@u.should_not == nil
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
it "should have three hyperlinks" do
|
19
|
+
@links.size.should == 3
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have a self hyperlink" do
|
23
|
+
@links.should be_hyperlinked('self', /<%= plural_name %>/)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should have a creator hyperlink" do
|
27
|
+
@links.should be_hyperlinked('creator', /api_users/)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should have an updater hyperlink" do
|
31
|
+
@links.should be_hyperlinked('updater', /api_users/)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
it "should have a name" do
|
36
|
+
@u['name'].should be_a String
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should have a description" do
|
40
|
+
@u['description'].should be_a String
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should have a created_at time" do
|
44
|
+
@u['created_at'].should be_a String
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have an updated_at time" do
|
48
|
+
@u['updated_at'].should be_a String
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have a lock_version field" do
|
52
|
+
@u['lock_version'].should be_an Integer
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
json.<%= singular_name %> do |json|
|
2
|
+
json._links hyperlinks(self: <%= singular_name %>_url(<%= singular_name %>),
|
3
|
+
creator: api_user_url(<%= singular_name %>.created_by),
|
4
|
+
updater: api_user_url(<%= singular_name %>.updated_by))
|
5
|
+
json.(<%= singular_name %>, :lock_version, :name, :description)
|
6
|
+
json.created_at <%= singular_name %>.created_at.utc.iso8601
|
7
|
+
json.updated_at <%= singular_name %>.updated_at.utc.iso8601
|
8
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
class OceanSetupGenerator < Rails::Generators::NamedBase #:nodoc: all
|
2
|
+
|
3
|
+
source_root File.expand_path('../templates', __FILE__)
|
4
|
+
|
5
|
+
def remove_unwanted_stuff
|
6
|
+
remove_file "#{Rails.root}/app/assets"
|
7
|
+
remove_file "#{Rails.root}/lib/assets"
|
8
|
+
remove_file "#{Rails.root}/app/views/layouts"
|
9
|
+
remove_file "#{Rails.root}/config/locales"
|
10
|
+
remove_file "#{Rails.root}/public"
|
11
|
+
remove_file "#{Rails.root}/config/initializers/session_store.rb"
|
12
|
+
#remove_file "#{Rails.root}/config/initializers/secret_token.rb"
|
13
|
+
remove_file "#{Rails.root}/test"
|
14
|
+
remove_file "#{Rails.root}/vendor/assets"
|
15
|
+
remove_file "#{Rails.root}/vendor/plugins"
|
16
|
+
remove_file "#{Rails.root}/tmp/cache/assets"
|
17
|
+
end
|
18
|
+
|
19
|
+
def install_application_controller
|
20
|
+
copy_file "application_controller.rb", "#{Rails.root}/app/controllers/application_controller.rb"
|
21
|
+
end
|
22
|
+
|
23
|
+
def install_application_helper
|
24
|
+
copy_file "application_helper.rb", "#{Rails.root}/app/helpers/application_helper.rb"
|
25
|
+
end
|
26
|
+
|
27
|
+
def install_spec_helper_and_support_files
|
28
|
+
copy_file "spec_helper.rb", "#{Rails.root}/spec/spec_helper.rb"
|
29
|
+
copy_file "hyperlinks.rb", "#{Rails.root}/spec/support/hyperlinks.rb"
|
30
|
+
end
|
31
|
+
|
32
|
+
def install_routes_file
|
33
|
+
template "routes.rb", "#{Rails.root}/config/routes.rb"
|
34
|
+
end
|
35
|
+
|
36
|
+
def install_alive_controller_and_specs
|
37
|
+
copy_file "alive_controller.rb", "#{Rails.root}/app/controllers/alive_controller.rb"
|
38
|
+
route 'get "/alive" => "alive#index"'
|
39
|
+
copy_file "alive_routing_spec.rb", "#{Rails.root}/spec/routing/alive_routing_spec.rb"
|
40
|
+
copy_file "alive_spec.rb", "#{Rails.root}/spec/requests/alive_spec.rb"
|
41
|
+
end
|
42
|
+
|
43
|
+
def turn_off_asset_pipeline
|
44
|
+
application "# Disable the asset pipeline
|
45
|
+
config.assets.enabled = false
|
46
|
+
"
|
47
|
+
end
|
48
|
+
|
49
|
+
def install_error_handling_and_specs
|
50
|
+
application "# Handle our own exceptions internally, so we can return JSON error bodies
|
51
|
+
config.exceptions_app = ->(env) { ErrorsController.action(:show).call(env) }
|
52
|
+
"
|
53
|
+
copy_file "errors_controller.rb", "#{Rails.root}/app/controllers/errors_controller.rb"
|
54
|
+
end
|
55
|
+
|
56
|
+
def turn_off_sessions_and_cookies
|
57
|
+
application "# Turn off sessions
|
58
|
+
config.session_store :disabled
|
59
|
+
config.middleware.delete ActionDispatch::Cookies
|
60
|
+
"
|
61
|
+
end
|
62
|
+
|
63
|
+
def install_generator_defaults
|
64
|
+
application "# Defaults for generators
|
65
|
+
config.generators do |g|
|
66
|
+
g.assets false
|
67
|
+
g.stylesheets false
|
68
|
+
g.helper false
|
69
|
+
g.test_framework :rspec, :fixture => true
|
70
|
+
g.fixture_replacement :factory_girl
|
71
|
+
end
|
72
|
+
"
|
73
|
+
end
|
74
|
+
|
75
|
+
def install_initializers
|
76
|
+
copy_file "api_constants.rb", "#{Rails.root}/config/initializers/api_constants.rb"
|
77
|
+
template "config.yml.example", "#{Rails.root}/config/config.yml.example"
|
78
|
+
template "config.yml.example", "#{Rails.root}/config/config.yml"
|
79
|
+
copy_file "ocean_constants.rb", "#{Rails.root}/config/initializers/ocean_constants.rb"
|
80
|
+
copy_file "zeromq_logger.rb", "#{Rails.root}/config/initializers/zeromq_logger.rb"
|
81
|
+
end
|
82
|
+
|
83
|
+
def replace_gemfile
|
84
|
+
remove_file "#{Rails.root}/Gemfile"
|
85
|
+
copy_file "Gemfile", "#{Rails.root}/Gemfile"
|
86
|
+
end
|
87
|
+
|
88
|
+
def setup_git
|
89
|
+
copy_file "gitignore", "#{Rails.root}/.gitignore"
|
90
|
+
git :init
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem "ocean-rails", git: "git://github.com/OceanDev/ocean-rails.git"
|
4
|
+
gem "rails", "~> 4.0"
|
5
|
+
gem "mysql2"
|
6
|
+
gem "foreigner"
|
7
|
+
gem "jbuilder"
|
8
|
+
|
9
|
+
group :test, :development do
|
10
|
+
gem "sqlite3"
|
11
|
+
gem "memory_test_fix"
|
12
|
+
gem "rspec-rails", "~> 2.0"
|
13
|
+
gem "simplecov", require: false
|
14
|
+
gem "factory_girl_rails", "~> 4.0"
|
15
|
+
gem "immigrant"
|
16
|
+
gem "annotate", ">=2.5.0"
|
17
|
+
end
|
18
|
+
|
19
|
+
gem "protected_attributes"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# The path /alive is implemented solely for the benefit of Varnish,
|
3
|
+
# which is set up to use it for health checking. Due to the routing
|
4
|
+
# implemented in Varnish, /alive can never be reached from the outside.
|
5
|
+
#
|
6
|
+
|
7
|
+
class AliveController < ApplicationController
|
8
|
+
|
9
|
+
skip_before_action :require_x_api_token
|
10
|
+
skip_before_action :authorize_action
|
11
|
+
|
12
|
+
|
13
|
+
def index
|
14
|
+
# If there is a DB, call to it here to ensure it too is healthy
|
15
|
+
render text: "ALIVE", status: 200
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "/alive (for Varnish health checking)" do
|
4
|
+
|
5
|
+
it "should return a 200 with a body of OK" do
|
6
|
+
get "/alive", {}, {'HTTP_ACCEPT' => "application/json"}
|
7
|
+
response.status.should be(200)
|
8
|
+
response.body.should == "ALIVE"
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
f = File.join(Rails.root, "config/config.yml")
|
2
|
+
unless File.exists?(f)
|
3
|
+
puts
|
4
|
+
puts "-----------------------------------------------------------------------"
|
5
|
+
puts "Constant definition file missing. Please copy config/config.yml.example"
|
6
|
+
puts "to config/config.yml and tailor its contents to suit your dev setup."
|
7
|
+
puts
|
8
|
+
puts "NB: config.yml is excluded from git version control as it will contain"
|
9
|
+
puts " data private to your Ocean system."
|
10
|
+
puts "-----------------------------------------------------------------------"
|
11
|
+
puts
|
12
|
+
abort
|
13
|
+
end
|
14
|
+
cfg = YAML.load(File.read(f))
|
15
|
+
cfg.merge! cfg.fetch(Rails.env, {}) if cfg.fetch(Rails.env, {})
|
16
|
+
cfg.each do |k, v|
|
17
|
+
next if k =~ /[a-z]/
|
18
|
+
eval "#{k} = #{v.inspect}"
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ApplicationHelper
|
2
|
+
|
3
|
+
#
|
4
|
+
# Used in Jbuilder templates to build hyperlinks
|
5
|
+
#
|
6
|
+
def hyperlinks(links={})
|
7
|
+
result = {}
|
8
|
+
links.each do |qi, val|
|
9
|
+
result[qi.to_s] = {
|
10
|
+
"href" => val.kind_of?(String) ? val : val[:href],
|
11
|
+
"type" => val.kind_of?(String) ? "application/json" : val[:type]
|
12
|
+
}
|
13
|
+
end
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
#
|
19
|
+
# This is needed everywhere except inside the Auth service to render creator
|
20
|
+
# and updater links correctly.
|
21
|
+
#
|
22
|
+
def api_user_url(x)
|
23
|
+
if x.blank?
|
24
|
+
"#{OCEAN_API_URL}/#{Api.version_for :api_user}/api_users/0"
|
25
|
+
elsif x.is_a?(Integer)
|
26
|
+
"#{OCEAN_API_URL}/#{Api.version_for :api_user}/api_users/#{x}"
|
27
|
+
elsif x.is_a?(String)
|
28
|
+
x
|
29
|
+
else
|
30
|
+
raise "api_user_url takes an integer, a string, or nil"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
##########################################################################################
|
2
|
+
# In order for the application to work, a file named config/config.yml must exist.
|
3
|
+
# You can use this file as a template: simply copy it, rename it and tailor its
|
4
|
+
# contents. All data in this file will be used to define constants in your application
|
5
|
+
# namespace. NB: the Chef recipes used to deploy this to the production environment will
|
6
|
+
# replace the contents of config/config.yml with an auto-generated file.
|
7
|
+
##########################################################################################
|
8
|
+
|
9
|
+
|
10
|
+
# This is the application's name
|
11
|
+
APP_NAME: <%= name %>
|
12
|
+
|
13
|
+
# Authentication data to use when the app authenticates with the Auth service.
|
14
|
+
# You should substitute your own password. Passwords should not be identical
|
15
|
+
# between services. Use a unique password in each case.
|
16
|
+
API_USER: <%= name %>
|
17
|
+
API_PASSWORD: xxxxxxxxxx
|
18
|
+
|
19
|
+
# This is the base domain used for all Ocean calls.
|
20
|
+
BASE_DOMAIN: example.com
|
21
|
+
|
22
|
+
# This enumerates the latest versions of all resources in the system, not just the
|
23
|
+
# ones defined by this service. You should keep it updated at all times.
|
24
|
+
# The special key _default is used as a fallback.
|
25
|
+
API_VERSIONS:
|
26
|
+
_default: v1
|
27
|
+
|
28
|
+
# This is the list of IP numbers for the Varnish instances. (For PURGE and BAN.)
|
29
|
+
LOAD_BALANCERS: []
|
30
|
+
|
31
|
+
# This is the list of IP numbers for the ZeroMQ log hosts. (Only used in production.)
|
32
|
+
LOG_HOSTS: []
|
33
|
+
|
34
|
+
|
35
|
+
##########################################################################################
|
36
|
+
# This section allows you to specify values specific for a particular Rails
|
37
|
+
# environment. Values defined here will take precedence over the default values.
|
38
|
+
# Make sure the declarations in each section are indented properly.
|
39
|
+
# NB: these overrides only affect your local development environment (which may run
|
40
|
+
# in any of these three states). In deployment, a generated version of this file
|
41
|
+
# is used.
|
42
|
+
##########################################################################################
|
43
|
+
|
44
|
+
development:
|
45
|
+
|
46
|
+
|
47
|
+
test:
|
48
|
+
|
49
|
+
|
50
|
+
production:
|
51
|
+
LOAD_BALANCERS:
|
52
|
+
- 1.1.1.1
|
53
|
+
- 2.2.2.2
|
54
|
+
|
55
|
+
LOG_HOSTS:
|
56
|
+
- 3.3.3.3
|
57
|
+
- 4.4.4.4
|