naf 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +16 -0
- data/.rspec +1 -0
- data/.travis.yml +17 -0
- data/Gemfile +17 -0
- data/LICENSE +2 -0
- data/README.rdoc +22 -0
- data/RELEASE_NOTES.rdoc +18 -0
- data/Rakefile +43 -0
- data/app/assets/images/bg-grad.png +0 -0
- data/app/assets/images/clock.png +0 -0
- data/app/assets/images/control_play_blue.png +0 -0
- data/app/assets/images/down_arrow.gif +0 -0
- data/app/assets/images/papertrail_job.png +0 -0
- data/app/assets/images/papertrail_machine.png +0 -0
- data/app/assets/images/papertrail_machine_runner.png +0 -0
- data/app/assets/images/terminate.png +0 -0
- data/app/assets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/app/assets/images/ui-bg_flat_0_ffffff_40x100.png +0 -0
- data/app/assets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/app/assets/images/ui-bg_glass_0_f4f4f4_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_65_f4f4f4_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_75_f4f4f4_1x400.png +0 -0
- data/app/assets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/app/assets/images/ui-bg_highlight-soft_0_f4f4f4_1x100.png +0 -0
- data/app/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/app/assets/images/ui-icons_222222_256x240.png +0 -0
- data/app/assets/images/ui-icons_2e83ff_256x240.png +0 -0
- data/app/assets/images/ui-icons_454545_256x240.png +0 -0
- data/app/assets/images/ui-icons_888888_256x240.png +0 -0
- data/app/assets/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/app/assets/images/up_arrow.gif +0 -0
- data/app/assets/javascripts/dataTablesTemplates/applications.js +94 -0
- data/app/assets/javascripts/dataTablesTemplates/jobs.js +163 -0
- data/app/assets/javascripts/dataTablesTemplates/machine_runner_invocations.js +60 -0
- data/app/assets/javascripts/dataTablesTemplates/machine_runners.js +82 -0
- data/app/assets/javascripts/dataTablesTemplates/machines.js +93 -0
- data/app/assets/javascripts/date.js +104 -0
- data/app/assets/javascripts/iso8601.js +41 -0
- data/app/assets/javascripts/jquery.dataTables.custom.js +62 -0
- data/app/assets/javascripts/jquery.dataTables.js +6862 -0
- data/app/assets/javascripts/naf.js +30 -0
- data/app/assets/javascripts/underscore.js +713 -0
- data/app/assets/stylesheets/jquery_ui/jquery-ui-1.8.5.custom.css.erb +572 -0
- data/app/assets/stylesheets/min_naf.css +14 -0
- data/app/assets/stylesheets/min_naf/layout.css.scss +355 -0
- data/app/assets/stylesheets/naf.css +14 -0
- data/app/assets/stylesheets/naf/layout.css.scss +497 -0
- data/app/controllers/naf/affinities_controller.rb +61 -0
- data/app/controllers/naf/application_controller.rb +43 -0
- data/app/controllers/naf/application_schedule_affinity_tabs_controller.rb +75 -0
- data/app/controllers/naf/applications_controller.rb +153 -0
- data/app/controllers/naf/historical_job_affinity_tabs_controller.rb +65 -0
- data/app/controllers/naf/historical_jobs_controller.rb +159 -0
- data/app/controllers/naf/janitorial_assignments_controller.rb +77 -0
- data/app/controllers/naf/logger_names_controller.rb +58 -0
- data/app/controllers/naf/logger_styles_controller.rb +59 -0
- data/app/controllers/naf/machine_affinity_slots_controller.rb +69 -0
- data/app/controllers/naf/machine_runner_invocations_controller.rb +59 -0
- data/app/controllers/naf/machine_runners_controller.rb +26 -0
- data/app/controllers/naf/machines_controller.rb +95 -0
- data/app/helpers/naf/application_helper.rb +275 -0
- data/app/models/log4r/papertrail_outputter.rb +19 -0
- data/app/models/logical/naf/application.rb +183 -0
- data/app/models/logical/naf/construction_zone/ad_hoc_work_order.rb +22 -0
- data/app/models/logical/naf/construction_zone/application_schedule_work_order.rb +15 -0
- data/app/models/logical/naf/construction_zone/application_work_order.rb +25 -0
- data/app/models/logical/naf/construction_zone/boss.rb +123 -0
- data/app/models/logical/naf/construction_zone/foreman.rb +53 -0
- data/app/models/logical/naf/construction_zone/proletariat.rb +40 -0
- data/app/models/logical/naf/construction_zone/work_order.rb +100 -0
- data/app/models/logical/naf/create_infrastructure.rb +48 -0
- data/app/models/logical/naf/job.rb +357 -0
- data/app/models/logical/naf/job_creator.rb +155 -0
- data/app/models/logical/naf/job_fetcher.rb +167 -0
- data/app/models/logical/naf/job_statuses/errored.rb +27 -0
- data/app/models/logical/naf/job_statuses/finished.rb +26 -0
- data/app/models/logical/naf/job_statuses/finished_less_minute.rb +25 -0
- data/app/models/logical/naf/job_statuses/queued.rb +32 -0
- data/app/models/logical/naf/job_statuses/running.rb +34 -0
- data/app/models/logical/naf/job_statuses/terminated.rb +25 -0
- data/app/models/logical/naf/job_statuses/waiting.rb +43 -0
- data/app/models/logical/naf/machine.rb +85 -0
- data/app/models/logical/naf/machine_runner.rb +46 -0
- data/app/models/logical/naf/machine_runner_invocation.rb +50 -0
- data/app/models/logical/naf/pickler.rb +74 -0
- data/app/models/logical/naf/unpickler.rb +98 -0
- data/app/models/naf/affinity.rb +145 -0
- data/app/models/naf/affinity_classification.rb +44 -0
- data/app/models/naf/application.rb +100 -0
- data/app/models/naf/application_run_group_restriction.rb +39 -0
- data/app/models/naf/application_schedule.rb +181 -0
- data/app/models/naf/application_schedule_affinity_tab.rb +86 -0
- data/app/models/naf/application_schedule_prerequisite.rb +50 -0
- data/app/models/naf/application_type.rb +72 -0
- data/app/models/naf/by_historical_job_id.rb +86 -0
- data/app/models/naf/historical_job.rb +334 -0
- data/app/models/naf/historical_job_affinity_tab.rb +61 -0
- data/app/models/naf/historical_job_prerequisite.rb +19 -0
- data/app/models/naf/janitorial_archive_assignment.rb +36 -0
- data/app/models/naf/janitorial_assignment.rb +37 -0
- data/app/models/naf/janitorial_create_assignment.rb +36 -0
- data/app/models/naf/janitorial_drop_assignment.rb +36 -0
- data/app/models/naf/logger_level.rb +21 -0
- data/app/models/naf/logger_name.rb +23 -0
- data/app/models/naf/logger_style.rb +58 -0
- data/app/models/naf/logger_style_name.rb +28 -0
- data/app/models/naf/machine.rb +257 -0
- data/app/models/naf/machine_affinity_slot.rb +78 -0
- data/app/models/naf/machine_runner.rb +51 -0
- data/app/models/naf/machine_runner_invocation.rb +71 -0
- data/app/models/naf/naf_base.rb +9 -0
- data/app/models/naf/queued_job.rb +164 -0
- data/app/models/naf/running_job.rb +80 -0
- data/app/models/process/naf/application.rb +164 -0
- data/app/models/process/naf/janitor.rb +117 -0
- data/app/models/process/naf/machine_manager.rb +150 -0
- data/app/models/process/naf/machine_upgrader.rb +112 -0
- data/app/models/process/naf/runner.rb +539 -0
- data/app/views/naf/affinities/_form.html.erb +50 -0
- data/app/views/naf/affinities/edit.html.erb +11 -0
- data/app/views/naf/affinities/index.html.erb +57 -0
- data/app/views/naf/affinities/new.html.erb +15 -0
- data/app/views/naf/affinities/show.html.erb +48 -0
- data/app/views/naf/application_schedule_affinity_tabs/_form.html.erb +31 -0
- data/app/views/naf/application_schedule_affinity_tabs/edit.html.erb +12 -0
- data/app/views/naf/application_schedule_affinity_tabs/new.html.erb +11 -0
- data/app/views/naf/applications/_application_schedule.html.erb +80 -0
- data/app/views/naf/applications/_application_schedule_prerequisites.html.erb +14 -0
- data/app/views/naf/applications/_form.html.erb +109 -0
- data/app/views/naf/applications/_search_container.html.erb +94 -0
- data/app/views/naf/applications/_show.html.erb +34 -0
- data/app/views/naf/applications/edit.html.erb +11 -0
- data/app/views/naf/applications/index.html.erb +51 -0
- data/app/views/naf/applications/index.json.erb +11 -0
- data/app/views/naf/applications/new.html.erb +11 -0
- data/app/views/naf/applications/show.html.erb +203 -0
- data/app/views/naf/datatable.html.erb +49 -0
- data/app/views/naf/historical_job_affinity_tabs/_form.html.erb +36 -0
- data/app/views/naf/historical_job_affinity_tabs/edit.html.erb +11 -0
- data/app/views/naf/historical_job_affinity_tabs/new.html.erb +11 -0
- data/app/views/naf/historical_jobs/_form.html.erb +94 -0
- data/app/views/naf/historical_jobs/_runners.html.erb +22 -0
- data/app/views/naf/historical_jobs/_search_container.html.erb +140 -0
- data/app/views/naf/historical_jobs/edit.html.erb +11 -0
- data/app/views/naf/historical_jobs/index.html.erb +48 -0
- data/app/views/naf/historical_jobs/index.json.erb +26 -0
- data/app/views/naf/historical_jobs/new.html.erb +61 -0
- data/app/views/naf/historical_jobs/show.html.erb +201 -0
- data/app/views/naf/janitorial_assignments/_form.html.erb +38 -0
- data/app/views/naf/janitorial_assignments/_rows.html.erb +17 -0
- data/app/views/naf/janitorial_assignments/edit.html.erb +11 -0
- data/app/views/naf/janitorial_assignments/index.html.erb +56 -0
- data/app/views/naf/janitorial_assignments/index.js.erb +1 -0
- data/app/views/naf/janitorial_assignments/new.html.erb +11 -0
- data/app/views/naf/layouts/jquery_datatables.json.erb +6 -0
- data/app/views/naf/logger_names/_form.html.erb +18 -0
- data/app/views/naf/logger_names/edit.html.erb +11 -0
- data/app/views/naf/logger_names/new.html.erb +11 -0
- data/app/views/naf/logger_names/show.html.erb +44 -0
- data/app/views/naf/logger_styles/_form.html.erb +30 -0
- data/app/views/naf/logger_styles/_logger_style_names.html.erb +19 -0
- data/app/views/naf/logger_styles/edit.html.erb +11 -0
- data/app/views/naf/logger_styles/new.html.erb +11 -0
- data/app/views/naf/logger_styles/show.html.erb +48 -0
- data/app/views/naf/machine_affinity_slots/_form.html.erb +36 -0
- data/app/views/naf/machine_affinity_slots/edit.html.erb +11 -0
- data/app/views/naf/machine_affinity_slots/new.html.erb +11 -0
- data/app/views/naf/machine_runner_invocations/_filter.html.erb +21 -0
- data/app/views/naf/machine_runner_invocations/index.html.erb +36 -0
- data/app/views/naf/machine_runner_invocations/index.json.erb +16 -0
- data/app/views/naf/machine_runner_invocations/show.html.erb +91 -0
- data/app/views/naf/machine_runners/index.html.erb +82 -0
- data/app/views/naf/machine_runners/index.json.erb +16 -0
- data/app/views/naf/machine_runners/show.html.erb +113 -0
- data/app/views/naf/machines/_filter.html.erb +26 -0
- data/app/views/naf/machines/_form.html.erb +62 -0
- data/app/views/naf/machines/_show.html.erb +169 -0
- data/app/views/naf/machines/edit.html.erb +11 -0
- data/app/views/naf/machines/index.html.erb +51 -0
- data/app/views/naf/machines/index.json.erb +23 -0
- data/app/views/naf/machines/new.html.erb +11 -0
- data/app/views/naf/machines/show.html.erb +92 -0
- data/app/views/naf/record.html.erb +46 -0
- data/app/views/naf/shared/_application.html.erb +50 -0
- data/app/views/naf/shared/_information_container.html.erb +19 -0
- data/app/views/naf/shared/_select_per_page.html.erb +72 -0
- data/ci/test-build.sh +17 -0
- data/ci/travis.sh +26 -0
- data/config/initializers/naf.rb +3 -0
- data/config/routes.rb +38 -0
- data/db/migrate/20120820023848_naf_schema.rb +413 -0
- data/doc/README_FOR_APP +2 -0
- data/lib/generators/naf_generator.rb +45 -0
- data/lib/generators/templates/config/logging/af.yml +26 -0
- data/lib/generators/templates/config/logging/naf.yml +22 -0
- data/lib/generators/templates/config/logging/nafjob.yml +16 -0
- data/lib/generators/templates/config/logging/nafrunner.yml +17 -0
- data/lib/generators/templates/naf.rb +11 -0
- data/lib/generators/templates/naf_layout.html.erb +15 -0
- data/lib/naf.rb +48 -0
- data/lib/naf/configuration.rb +23 -0
- data/lib/naf/engine.rb +18 -0
- data/lib/naf/version.rb +3 -0
- data/lib/tasks/naf_tasks.rake +370 -0
- data/naf.gemspec +30 -0
- data/script/rails +10 -0
- data/spec/controllers/naf/affinities_controller_spec.rb +79 -0
- data/spec/controllers/naf/application_controller_spec.rb +10 -0
- data/spec/controllers/naf/application_schedule_affinity_tabs_controller_spec.rb +106 -0
- data/spec/controllers/naf/applications_controller_spec.rb +109 -0
- data/spec/controllers/naf/historical_job_affinity_tabs_controller_spec.rb +96 -0
- data/spec/controllers/naf/historical_jobs_controller_spec.rb +19 -0
- data/spec/controllers/naf/machine_affinity_slots_controller_spec.rb +109 -0
- data/spec/controllers/naf/machines_controller_spec.rb +74 -0
- data/spec/dummy/.gitignore +12 -0
- data/spec/dummy/README +19 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/stylesheets/application.css +14 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/my_script.rb +8 -0
- data/spec/dummy/app/models/other/base.rb.sample +10 -0
- data/spec/dummy/app/views/layouts/application.html.erb +15 -0
- data/spec/dummy/app/views/layouts/naf_layout.html.erb +15 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +62 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database-non_primary.yml +20 -0
- data/spec/dummy/config/database-primary.yml +16 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/naf.rb.non_primary +4 -0
- data/spec/dummy/config/initializers/naf.rb.primary +3 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/logging/af.yml +26 -0
- data/spec/dummy/config/logging/naf.yml +22 -0
- data/spec/dummy/config/logging/nafjob.yml +16 -0
- data/spec/dummy/config/logging/nafrunner.yml +17 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/db/.gitignore +2 -0
- data/spec/dummy/lib/tasks/dummy.rake +60 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/naf.rb +433 -0
- data/spec/helpers/naf/application_helper_spec.rb +0 -0
- data/spec/models/logical/naf/application_spec.rb +69 -0
- data/spec/models/logical/naf/job_creator_spec.rb +32 -0
- data/spec/models/logical/naf/job_fetcher_spec.rb +140 -0
- data/spec/models/logical/naf/job_spec.rb +282 -0
- data/spec/models/logical/naf/machine_spec.rb +61 -0
- data/spec/models/naf/affinity_classification_spec.rb +56 -0
- data/spec/models/naf/affinity_spec.rb +100 -0
- data/spec/models/naf/application_run_group_restriction_spec.rb +57 -0
- data/spec/models/naf/application_schedule_affinity_tab_spec.rb +85 -0
- data/spec/models/naf/application_schedule_prerequisite_spec.rb +35 -0
- data/spec/models/naf/application_schedule_spec.rb +166 -0
- data/spec/models/naf/application_spec.rb +128 -0
- data/spec/models/naf/application_type_spec.rb +104 -0
- data/spec/models/naf/historical_job_affinity_tab_spec.rb +59 -0
- data/spec/models/naf/historical_job_prerequisite_spec.rb +25 -0
- data/spec/models/naf/historical_job_spec.rb +334 -0
- data/spec/models/naf/logger_level_spec.rb +34 -0
- data/spec/models/naf/logger_name_spec.rb +35 -0
- data/spec/models/naf/logger_style_name_spec.rb +39 -0
- data/spec/models/naf/logger_style_spec.rb +89 -0
- data/spec/models/naf/machine_affinity_slot_spec.rb +77 -0
- data/spec/models/naf/machine_runner_invocation_spec.rb +38 -0
- data/spec/models/naf/machine_runner_spec.rb +37 -0
- data/spec/models/naf/machine_spec.rb +425 -0
- data/spec/models/naf/naf_base_spec.rb +14 -0
- data/spec/models/naf/queued_job_spec.rb +171 -0
- data/spec/models/naf/running_job_spec.rb +107 -0
- data/spec/models/process/naf/application_spec.rb +8 -0
- data/spec/models/process/naf/janitor_spec.rb +10 -0
- data/spec/models/process/naf/runner_spec.rb +10 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/engine_routing.rb +27 -0
- data/spec/support/script_spec_helper.rb +58 -0
- metadata +590 -0
data/doc/README_FOR_APP
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class NafGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
6
|
+
|
7
|
+
argument :schema_name, type: :string, default: "naf"
|
8
|
+
|
9
|
+
def add_configuration_files
|
10
|
+
filename = "naf.rb"
|
11
|
+
filepath = "config/initializers/#{filename}"
|
12
|
+
path = "#{Rails.root}/#{filepath}"
|
13
|
+
if File.exists?(path)
|
14
|
+
puts "Skipping #{filepath} creation, as file already exists!"
|
15
|
+
else
|
16
|
+
puts "Adding Naf initializer (#{filepath})..."
|
17
|
+
template filename, path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_log4r_configuration_files
|
22
|
+
directory "config"
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_layouts_file
|
26
|
+
filename = "naf_layout.html.erb"
|
27
|
+
filepath = "app/views/layouts/#{filename}"
|
28
|
+
path = "#{Rails.root}/#{filepath}"
|
29
|
+
if File.exists?(path)
|
30
|
+
puts "Skipping #{filepath} creation, as file already exists!"
|
31
|
+
else
|
32
|
+
puts "Adding naf_layout (#{filepath})..."
|
33
|
+
template filename, path
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def mount_engine
|
38
|
+
puts "Mounting Naf::Engine at \"/job_system\" in config/routes.rb..."
|
39
|
+
insert_into_file("#{Rails.root}/config/routes.rb", after: /routes.draw.do\n/) do
|
40
|
+
%Q{\n mount Naf::Engine, at: "/job_system"\n}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
log4r_config:
|
2
|
+
pre_config:
|
3
|
+
custom_levels:
|
4
|
+
- DEBUG
|
5
|
+
- DEBUG_FINE
|
6
|
+
- DEBUG_MEDIUM
|
7
|
+
- DEBUG_GROSS
|
8
|
+
- DETAIL
|
9
|
+
- INFO
|
10
|
+
- WARN
|
11
|
+
- ALARM
|
12
|
+
- ERROR
|
13
|
+
- FATAL
|
14
|
+
global:
|
15
|
+
level: ALL
|
16
|
+
root :
|
17
|
+
level: ALL
|
18
|
+
|
19
|
+
outputters:
|
20
|
+
- type : StdoutOutputter
|
21
|
+
name : stdout
|
22
|
+
level : DEBUG
|
23
|
+
formatter:
|
24
|
+
date_pattern: '%y%m%d %H:%M:%S.%L'
|
25
|
+
pattern : '%d %p %C %l %M'
|
26
|
+
type : PatternFormatter
|
@@ -0,0 +1,22 @@
|
|
1
|
+
log4r_config:
|
2
|
+
loggers:
|
3
|
+
- name : root
|
4
|
+
level : ALL
|
5
|
+
outputters:
|
6
|
+
- stdout
|
7
|
+
|
8
|
+
outputters:
|
9
|
+
- type : StdoutOutputter
|
10
|
+
name : stdout
|
11
|
+
formatter:
|
12
|
+
date_pattern: '%y%m%d %H:%M:%S.%L'
|
13
|
+
pattern : '%d pid=%p jid=%g %C %l %M'
|
14
|
+
type : PatternFormatter
|
15
|
+
|
16
|
+
- type: PapertrailOutputter
|
17
|
+
name: papertrail
|
18
|
+
port: 0 # XXX put your papertrail port here
|
19
|
+
program: naf_application
|
20
|
+
formatter:
|
21
|
+
pattern : 'pid=%p %C %l %M'
|
22
|
+
type : PatternFormatter
|
@@ -0,0 +1,16 @@
|
|
1
|
+
log4r_config:
|
2
|
+
outputters:
|
3
|
+
- type : StdoutOutputter
|
4
|
+
name : stdout
|
5
|
+
formatter:
|
6
|
+
date_pattern: '%y%m%d %H:%M:%S.%L'
|
7
|
+
pattern : '%d pid=%p jid=%g %C %l %M'
|
8
|
+
type : PatternFormatter
|
9
|
+
|
10
|
+
- type: PapertrailOutputter
|
11
|
+
name: papertrail
|
12
|
+
port: 0 # XXX put your papertrail port here
|
13
|
+
program: jid(%g)
|
14
|
+
formatter:
|
15
|
+
pattern : '%C %l %M'
|
16
|
+
type : PatternFormatter
|
@@ -0,0 +1,17 @@
|
|
1
|
+
log4r_config:
|
2
|
+
outputters:
|
3
|
+
- type : StdoutOutputter
|
4
|
+
name : stdout
|
5
|
+
level : DEBUG
|
6
|
+
formatter:
|
7
|
+
date_pattern: '%y%m%d %H:%M:%S.%L'
|
8
|
+
pattern : '%d runner_pid=%p %C %l %M'
|
9
|
+
type : PatternFormatter
|
10
|
+
|
11
|
+
- type: PapertrailOutputter
|
12
|
+
name: papertrail
|
13
|
+
port: 0 # XXX put your papertrail port here
|
14
|
+
program: runner
|
15
|
+
formatter:
|
16
|
+
pattern : '%C %l %M'
|
17
|
+
type : PatternFormatter
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= ::Naf.title %></title>
|
5
|
+
<%%= stylesheet_link_tag "naf", media: "all" %>
|
6
|
+
<%%= javascript_include_tag "naf" %>
|
7
|
+
<%%= yield :javascripts %>
|
8
|
+
<%%= csrf_meta_tags %>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
|
12
|
+
<%%= yield %>
|
13
|
+
|
14
|
+
</body>
|
15
|
+
</html>
|
data/lib/naf.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require "naf/engine"
|
2
|
+
require 'naf/configuration'
|
3
|
+
|
4
|
+
module Naf
|
5
|
+
class << self
|
6
|
+
attr_writer :configuration
|
7
|
+
|
8
|
+
def configure
|
9
|
+
yield(configuration)
|
10
|
+
end
|
11
|
+
|
12
|
+
def configuration
|
13
|
+
@configuration ||= Configuration.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def schema_name
|
17
|
+
configuration.schema_name
|
18
|
+
end
|
19
|
+
|
20
|
+
def model_class
|
21
|
+
configuration.model_class.constantize
|
22
|
+
end
|
23
|
+
|
24
|
+
def controller_class
|
25
|
+
configuration.controller_class.constantize
|
26
|
+
end
|
27
|
+
|
28
|
+
def title
|
29
|
+
configuration.title
|
30
|
+
end
|
31
|
+
|
32
|
+
def papertrail_group_id
|
33
|
+
configuration.papertrail_group_id
|
34
|
+
end
|
35
|
+
|
36
|
+
def papertrail_token
|
37
|
+
configuration.papertrail_token
|
38
|
+
end
|
39
|
+
|
40
|
+
def layout
|
41
|
+
configuration.layout
|
42
|
+
end
|
43
|
+
|
44
|
+
def using_another_database?
|
45
|
+
model_class != ActiveRecord::Base
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Naf
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :schema_name,
|
4
|
+
:model_class,
|
5
|
+
:controller_class,
|
6
|
+
:title,
|
7
|
+
:papertrail_group_id,
|
8
|
+
:papertrail_token,
|
9
|
+
:layout,
|
10
|
+
:default_page_options
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@model_class = "::ActiveRecord::Base"
|
14
|
+
@controller_class = "::ApplicationController"
|
15
|
+
@title = "Naf - a Rails Job Scheduling Engine"
|
16
|
+
@papertrail_group_id = nil
|
17
|
+
@papertrail_token = nil
|
18
|
+
@layout = "naf_layout"
|
19
|
+
@default_page_options = [10, 20, 50, 100, 250, 500, 750, 1000, 1500, 2000]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/naf/engine.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'will_paginate'
|
3
|
+
require 'facter'
|
4
|
+
require 'jquery-rails'
|
5
|
+
require 'log4r_remote_syslog_outputter'
|
6
|
+
require 'partitioned'
|
7
|
+
|
8
|
+
module Naf
|
9
|
+
class Engine < ::Rails::Engine
|
10
|
+
isolate_namespace Naf
|
11
|
+
engine_name "naf"
|
12
|
+
|
13
|
+
initializer "dependencies" do
|
14
|
+
require 'partitioned'
|
15
|
+
require 'log4r_remote_syslog_outputter'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/naf/version.rb
ADDED
@@ -0,0 +1,370 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
# Add methods for aliasing and overriding rake tasks
|
4
|
+
# From: http://metaskills.net/2010/5/26/the-alias_method_chain-of-rake-override-rake-task
|
5
|
+
|
6
|
+
Rake::TaskManager.class_eval do
|
7
|
+
def alias_task(fq_name)
|
8
|
+
raise "Task '#{fq_name}' not found" unless @tasks.has_key?(fq_name)
|
9
|
+
|
10
|
+
new_name = "#{fq_name}:original"
|
11
|
+
@tasks[new_name] = @tasks.delete(fq_name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def alias_task(fq_name)
|
16
|
+
Rake.application.alias_task(fq_name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def override_task(*args, &block)
|
20
|
+
name, params, deps = Rake.application.resolve_args(args.dup)
|
21
|
+
fq_name = Rake.application.instance_variable_get(:@scope).to_a.reverse.push(name).join(':')
|
22
|
+
alias_task(fq_name)
|
23
|
+
Rake::Task.define_task(*args, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
# --------------------------------------------------
|
27
|
+
# ---------------Custom Rake Tasks for Naf----------
|
28
|
+
# --------------------------------------------------
|
29
|
+
|
30
|
+
namespace :naf do
|
31
|
+
namespace :isolate do
|
32
|
+
desc "Custom isolation Engine migrations to db/naf/migrate folder, for use on non-primary database"
|
33
|
+
task :migrations do
|
34
|
+
|
35
|
+
puts "Moving naf migration files to folder: #{isolated_naf_migrations_folder}"
|
36
|
+
|
37
|
+
FileUtils.mkdir(isolated_naf_folder) unless Dir.exists?(isolated_naf_folder)
|
38
|
+
FileUtils.mkdir(isolated_naf_migrations_folder) unless Dir.exists?(isolated_naf_migrations_folder)
|
39
|
+
|
40
|
+
source_folder = "#{Rails.root}/db/migrate"
|
41
|
+
|
42
|
+
Dir.entries(source_folder).grep(/\.naf\.rb/).each do |migration_file|
|
43
|
+
file_path = "#{source_folder}/#{migration_file}"
|
44
|
+
puts "#{isolated_naf_migrations_folder}/#{migration_file}"
|
45
|
+
if File.exists?("#{isolated_naf_migrations_folder}#{migration_file}")
|
46
|
+
puts "\t#{migration_file} already exists, skipping"
|
47
|
+
else
|
48
|
+
puts "\t #{file_path} => #{isolated_naf_migrations_folder}#{migration_file}"
|
49
|
+
FileUtils.mv(file_path, isolated_naf_migrations_folder)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
namespace :janitor do
|
57
|
+
desc "create partitioning infrastructure for naf tables"
|
58
|
+
task infrastructure: :environment do
|
59
|
+
model_names = [::Naf::HistoricalJob.name,
|
60
|
+
::Naf::HistoricalJobPrerequisite.name,
|
61
|
+
::Naf::HistoricalJobAffinityTab.name]
|
62
|
+
::Logical::Naf::CreateInfrastructure.new(model_names).work
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
namespace :db do
|
67
|
+
desc "Custom migrate task, connects to correct database, migrations found in db/naf/migrate"
|
68
|
+
task migrate: :environment do
|
69
|
+
if using_another_database? and naf_migrations.size > 0
|
70
|
+
puts "Running naf migrations with database configuration: #{naf_environment}"
|
71
|
+
puts naf_migrations
|
72
|
+
connect_to_naf_database do
|
73
|
+
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
74
|
+
ActiveRecord::Migrator.migrate(isolated_naf_migrations_folder, version )
|
75
|
+
end
|
76
|
+
else
|
77
|
+
#Invoke the standard migration task, within the Naf Engine scope
|
78
|
+
ENV['SCOPE'] = 'naf'
|
79
|
+
Rake::Task['db:migrate'].invoke
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
desc "Perform a rollback on the on the naf migrations"
|
84
|
+
task rollback: :environment do
|
85
|
+
if using_another_database? and naf_migrations.size > 0
|
86
|
+
connect_to_naf_database do
|
87
|
+
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
|
88
|
+
ActiveRecord::Migrator.rollback(isolated_naf_migrations_folder, step)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
ENV['SCOPE'] = 'naf'
|
92
|
+
Rake::Task['db:rollback'].invoke
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
namespace :migrate do
|
97
|
+
|
98
|
+
desc 'Runs the "up" for a given migration VERSION.'
|
99
|
+
task up: [:environment] do
|
100
|
+
if using_another_database? and naf_migrations.size > 0
|
101
|
+
connect_to_naf_database do
|
102
|
+
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
103
|
+
raise 'VERSION is required' unless version
|
104
|
+
ActiveRecord::Migrator.run(:up, [isolated_naf_migrations_folder], version)
|
105
|
+
end
|
106
|
+
else
|
107
|
+
puts "You are using the primary database for Naf, please run: rake db:migrate:up VERSION=x"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
desc 'Runs the "down" for a given migration VERSION.'
|
112
|
+
task down: [:environment] do
|
113
|
+
if using_another_database? and naf_migrations.size > 0
|
114
|
+
connect_to_naf_database do
|
115
|
+
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
|
116
|
+
raise 'VERSION is required' unless version
|
117
|
+
ActiveRecord::Migrator.run(:down, [isolated_naf_migrations_folder], version)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
puts "You are using the primary database for Naf, please run: rake db:migrate:down VERSION=x"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
desc "Show the status of migrations"
|
125
|
+
task status: :environment do
|
126
|
+
if using_another_database? and naf_migrations.size > 0
|
127
|
+
connect_to_naf_database do
|
128
|
+
config = ActiveRecord::Base.configurations[naf_environment]
|
129
|
+
unless ActiveRecord::Base.connection.table_exists?(ActiveRecord::Migrator.schema_migrations_table_name)
|
130
|
+
puts 'Schema migrations table does not exist yet.'
|
131
|
+
next # means "return" for rake task
|
132
|
+
end
|
133
|
+
db_list = ActiveRecord::Base.connection.select_values("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name}")
|
134
|
+
file_list = []
|
135
|
+
Dir.foreach(isolated_naf_migrations_folder) do |file|
|
136
|
+
# only files matching "20091231235959_some_name.rb" pattern
|
137
|
+
if match_data = /^(\d{14})_(.+)\.rb$/.match(file)
|
138
|
+
status = db_list.delete(match_data[1]) ? 'up' : 'down'
|
139
|
+
file_list << [status, match_data[1], match_data[2].humanize]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
db_list.map! do |version|
|
143
|
+
['up', version, '********** NO FILE **********']
|
144
|
+
end
|
145
|
+
# output
|
146
|
+
puts "\ndatabase: #{config['database']}\n\n"
|
147
|
+
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
148
|
+
puts "-" * 50
|
149
|
+
(db_list + file_list).sort_by {|migration| migration[1]}.each do |migration|
|
150
|
+
puts "#{migration[0].center(8)} #{migration[1].ljust(14)} #{migration[2]}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
else
|
154
|
+
puts "You are using the primary database for Naf, please run: rake db:migrate:status"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
namespace :structure do
|
160
|
+
desc "Dump the naf_development schema"
|
161
|
+
task dump: :environment do
|
162
|
+
env = "naf_#{::Rails.env}"
|
163
|
+
config = ActiveRecord::Base.configurations[env]
|
164
|
+
ENV['PGHOST'] = config["host"] if config["host"]
|
165
|
+
ENV['PGPORT'] = config["port"].to_s if config["port"]
|
166
|
+
ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
|
167
|
+
search_path = "naf*"
|
168
|
+
command = "pg_dump -i -U \"#{config["username"]}\" -s -x -O"
|
169
|
+
( config["exclude"] || [] ).each {|e| command << " -T \"#{e}\""}
|
170
|
+
command << " -f db/#{env}_structure.sql --schema=#{search_path} #{config["database"]} > /dev/null 2>&1"
|
171
|
+
`#{command}`
|
172
|
+
raise "Error dumping database structure for #{env}" if $?.exitstatus == 1
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
namespace :test do
|
177
|
+
desc "Drop the Naf Test database"
|
178
|
+
task purge: :environment do
|
179
|
+
abcs = ActiveRecord::Base.configurations
|
180
|
+
config = abcs['naf_test']
|
181
|
+
ActiveRecord::Base.clear_active_connections!
|
182
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
183
|
+
ActiveRecord::Base.connection.drop_database config['database']
|
184
|
+
@encoding = config['encoding'] || ENV['CHARSET'] || 'utf8'
|
185
|
+
begin
|
186
|
+
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
187
|
+
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
|
188
|
+
ActiveRecord::Base.establish_connection(config)
|
189
|
+
rescue Exception => e
|
190
|
+
$stderr.puts e, *(e.backtrace)
|
191
|
+
$stderr.puts "Couldn't create database for #{config.inspect}"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
desc "Clone naf_development to naf_test"
|
195
|
+
task clone_structure: [ "naf:db:structure:dump", "naf:db:test:purge" ] do
|
196
|
+
abcs = ActiveRecord::Base.configurations
|
197
|
+
config = abcs['naf_test']
|
198
|
+
ENV['PGHOST'] = config["host"] if config["host"]
|
199
|
+
ENV['PGPORT'] = config["port"].to_s if config["port"]
|
200
|
+
ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
|
201
|
+
`psql -U "#{config["username"]}" -f db/naf_#{::Rails.env}_structure.sql #{config["database"]}`
|
202
|
+
raise "Error loading database structure for #{env}" if $?.exitstatus == 1
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
desc "Undo all of the naf schema migrations"
|
208
|
+
task schema_rollback: :environment do
|
209
|
+
puts "Rolling back all of Naf migrations"
|
210
|
+
if using_another_database? and naf_migrations.size > 0
|
211
|
+
connect_to_naf_database do
|
212
|
+
ActiveRecord::Migrator.migrate(isolated_naf_migrations_folder, 0)
|
213
|
+
end
|
214
|
+
else
|
215
|
+
ENV['SCOPE'] = 'naf'
|
216
|
+
ENV['VERSION'] = '0'
|
217
|
+
Rake::Task['db:migrate'].invoke
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
desc "Delete all of the naf schema migrations files that were installed"
|
222
|
+
task remove_migration_files: [:environment, :schema_rollback] do
|
223
|
+
naf_migrations.each do |migration|
|
224
|
+
if using_another_database? and naf_migrations.size > 0
|
225
|
+
file_path = "#{isolated_naf_migrations_folder}#{migration}"
|
226
|
+
else
|
227
|
+
file_path = "#{standard_migrations_folder}#{migration}"
|
228
|
+
end
|
229
|
+
if File.exists?(file_path)
|
230
|
+
puts "Removing migration file: #{migration}"
|
231
|
+
File.delete(file_path)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
if Dir.exists?(isolated_naf_migrations_folder)
|
235
|
+
puts "Removing folder #{isolated_naf_migrations_folder}"
|
236
|
+
FileUtils.rmdir(isolated_naf_migrations_folder)
|
237
|
+
end
|
238
|
+
if Dir.exists?(isolated_naf_folder)
|
239
|
+
puts "Removing folder #{isolated_naf_folder}"
|
240
|
+
FileUtils.rmdir(isolated_naf_folder)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
desc "Deletes initalizers, configs that were installed, revert edit to config/routes"
|
245
|
+
task system_teardown: :environment do
|
246
|
+
# The first two files configured to be removed, if someone is using an older versions of naf
|
247
|
+
files_to_remove = [
|
248
|
+
"config/initializers/job_system_initializer.rb",
|
249
|
+
"config/job_system_config.yml",
|
250
|
+
"config/initializers/naf_initializer.rb",
|
251
|
+
"config/initializers/naf.rb",
|
252
|
+
"config/naf_log4r.yml",
|
253
|
+
"config/naf_config.yml"
|
254
|
+
]
|
255
|
+
edit_file_line_regex_hash = {
|
256
|
+
"config/routes.rb" => %r{$ mount Naf::Engine, :at => "/job_system"\s*\n}
|
257
|
+
}
|
258
|
+
files_to_remove.each do |file|
|
259
|
+
file_path = "#{Rails.root}/#{file}"
|
260
|
+
if File.exists?(file_path)
|
261
|
+
puts "Removing file: #{file}"
|
262
|
+
File.delete(file_path)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
edit_file_line_regex_hash.each do |file, regex|
|
266
|
+
puts "Reverting Naf Engine's edits to #{file}"
|
267
|
+
file_path = "#{Rails.root}/#{file}"
|
268
|
+
gsub_file(file_path, regex, '')
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
desc "remove partitioning infrastructure for naf tables"
|
273
|
+
task remove_partitions: :environment do
|
274
|
+
klasses = [::Naf::HistoricalJob, ::Naf::HistoricalJobPrerequisite, ::Naf::HistoricalJobAffinityTab]
|
275
|
+
existing_schemas = database_schemas
|
276
|
+
schemas = klasses.map{ |klass| klass.configurator.schema_name }
|
277
|
+
if using_another_database?
|
278
|
+
connect_to_naf_database do
|
279
|
+
schemas.each do |schema|
|
280
|
+
ActiveRecord::Base.connection.execute("DROP SCHEMA #{schema} CASCADE") if existing_schemas.include?(schema)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
else
|
284
|
+
schemas.each do |schema|
|
285
|
+
ActiveRecord::Base.connection.execute("DROP SCHEMA #{schema} CASCADE") if existing_schemas.include?(schema)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
desc "The master task for completely expunging the installation of the naf Engine"
|
290
|
+
task teardown: [:system_teardown, :remove_migration_files, :remove_partitions] do
|
291
|
+
end
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
# Helper Methods
|
296
|
+
|
297
|
+
def database_schemas
|
298
|
+
params = ["SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname NOT IN ('information_schema') ORDER by nspname; ", 'SCHEMA']
|
299
|
+
if using_another_database?
|
300
|
+
connect_to_naf_database do
|
301
|
+
return ActiveRecord::Base.connection.query(*params).flatten
|
302
|
+
end
|
303
|
+
else
|
304
|
+
return ActiveRecord::Base.connection.query(*params).flatten
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
# Transactions method to connect to the specific database
|
309
|
+
# you want the naf tables to live in
|
310
|
+
def connect_to_naf_database
|
311
|
+
original = ActiveRecord::Base.remove_connection
|
312
|
+
ActiveRecord::Base.establish_connection(naf_environment)
|
313
|
+
yield
|
314
|
+
ensure
|
315
|
+
ActiveRecord::Base.establish_connection original
|
316
|
+
end
|
317
|
+
|
318
|
+
# Figure out if you are using another database for naf
|
319
|
+
def using_another_database?
|
320
|
+
return naf_environment == "naf_#{Rails.env}"
|
321
|
+
end
|
322
|
+
|
323
|
+
# Specifiy the naf environment, the configuration that migrations with run under,
|
324
|
+
# If the naf_#{Rails.env} configuration exists in in database.yml, choose that,
|
325
|
+
# else choose Rails.env
|
326
|
+
def naf_environment
|
327
|
+
naf_environments = ActiveRecord::Base.configurations.keys.select{|env| env == "naf_#{Rails.env}"}
|
328
|
+
if naf_environments.any?
|
329
|
+
return naf_environments.first
|
330
|
+
else
|
331
|
+
return Rails.env.to_s
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# Subsitute matches to a given regex in the given file, with the given string
|
336
|
+
# Used right now just to revert config/routes.rb
|
337
|
+
def gsub_file(path, regexp, *args, &block)
|
338
|
+
content = File.read(path).gsub(regexp, *args, &block)
|
339
|
+
File.open(path, 'wb') { |file| file.write(content) }
|
340
|
+
end
|
341
|
+
|
342
|
+
def standard_migrations_folder
|
343
|
+
"#{Rails.root}/db/migrate/"
|
344
|
+
end
|
345
|
+
|
346
|
+
def isolated_naf_folder
|
347
|
+
"#{Rails.root}/db/naf/"
|
348
|
+
end
|
349
|
+
|
350
|
+
def isolated_naf_migrations_folder
|
351
|
+
"#{isolated_naf_folder}migrate/"
|
352
|
+
end
|
353
|
+
|
354
|
+
def naf_migrations
|
355
|
+
if using_another_database?
|
356
|
+
unless Dir.exists?(isolated_naf_folder) and Dir.exists?(isolated_naf_migrations_folder)
|
357
|
+
raise NafConfigurationError
|
358
|
+
else
|
359
|
+
Dir.entries(isolated_naf_migrations_folder).grep(/\.naf\.rb$/)
|
360
|
+
end
|
361
|
+
else
|
362
|
+
Dir.entries(standard_migrations_folder).grep(/\.naf\.rb$/)
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
class NafUsageError < Exception
|
367
|
+
end
|
368
|
+
|
369
|
+
class NafConfigurationError < Exception
|
370
|
+
end
|