naf 1.1.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.
Files changed (295) hide show
  1. data/.gitignore +16 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +17 -0
  5. data/LICENSE +2 -0
  6. data/README.rdoc +22 -0
  7. data/RELEASE_NOTES.rdoc +18 -0
  8. data/Rakefile +43 -0
  9. data/app/assets/images/bg-grad.png +0 -0
  10. data/app/assets/images/clock.png +0 -0
  11. data/app/assets/images/control_play_blue.png +0 -0
  12. data/app/assets/images/down_arrow.gif +0 -0
  13. data/app/assets/images/papertrail_job.png +0 -0
  14. data/app/assets/images/papertrail_machine.png +0 -0
  15. data/app/assets/images/papertrail_machine_runner.png +0 -0
  16. data/app/assets/images/terminate.png +0 -0
  17. data/app/assets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  18. data/app/assets/images/ui-bg_flat_0_ffffff_40x100.png +0 -0
  19. data/app/assets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  20. data/app/assets/images/ui-bg_glass_0_f4f4f4_1x400.png +0 -0
  21. data/app/assets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  22. data/app/assets/images/ui-bg_glass_65_f4f4f4_1x400.png +0 -0
  23. data/app/assets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  24. data/app/assets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  25. data/app/assets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  26. data/app/assets/images/ui-bg_glass_75_f4f4f4_1x400.png +0 -0
  27. data/app/assets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  28. data/app/assets/images/ui-bg_highlight-soft_0_f4f4f4_1x100.png +0 -0
  29. data/app/assets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  30. data/app/assets/images/ui-icons_222222_256x240.png +0 -0
  31. data/app/assets/images/ui-icons_2e83ff_256x240.png +0 -0
  32. data/app/assets/images/ui-icons_454545_256x240.png +0 -0
  33. data/app/assets/images/ui-icons_888888_256x240.png +0 -0
  34. data/app/assets/images/ui-icons_cd0a0a_256x240.png +0 -0
  35. data/app/assets/images/up_arrow.gif +0 -0
  36. data/app/assets/javascripts/dataTablesTemplates/applications.js +94 -0
  37. data/app/assets/javascripts/dataTablesTemplates/jobs.js +163 -0
  38. data/app/assets/javascripts/dataTablesTemplates/machine_runner_invocations.js +60 -0
  39. data/app/assets/javascripts/dataTablesTemplates/machine_runners.js +82 -0
  40. data/app/assets/javascripts/dataTablesTemplates/machines.js +93 -0
  41. data/app/assets/javascripts/date.js +104 -0
  42. data/app/assets/javascripts/iso8601.js +41 -0
  43. data/app/assets/javascripts/jquery.dataTables.custom.js +62 -0
  44. data/app/assets/javascripts/jquery.dataTables.js +6862 -0
  45. data/app/assets/javascripts/naf.js +30 -0
  46. data/app/assets/javascripts/underscore.js +713 -0
  47. data/app/assets/stylesheets/jquery_ui/jquery-ui-1.8.5.custom.css.erb +572 -0
  48. data/app/assets/stylesheets/min_naf.css +14 -0
  49. data/app/assets/stylesheets/min_naf/layout.css.scss +355 -0
  50. data/app/assets/stylesheets/naf.css +14 -0
  51. data/app/assets/stylesheets/naf/layout.css.scss +497 -0
  52. data/app/controllers/naf/affinities_controller.rb +61 -0
  53. data/app/controllers/naf/application_controller.rb +43 -0
  54. data/app/controllers/naf/application_schedule_affinity_tabs_controller.rb +75 -0
  55. data/app/controllers/naf/applications_controller.rb +153 -0
  56. data/app/controllers/naf/historical_job_affinity_tabs_controller.rb +65 -0
  57. data/app/controllers/naf/historical_jobs_controller.rb +159 -0
  58. data/app/controllers/naf/janitorial_assignments_controller.rb +77 -0
  59. data/app/controllers/naf/logger_names_controller.rb +58 -0
  60. data/app/controllers/naf/logger_styles_controller.rb +59 -0
  61. data/app/controllers/naf/machine_affinity_slots_controller.rb +69 -0
  62. data/app/controllers/naf/machine_runner_invocations_controller.rb +59 -0
  63. data/app/controllers/naf/machine_runners_controller.rb +26 -0
  64. data/app/controllers/naf/machines_controller.rb +95 -0
  65. data/app/helpers/naf/application_helper.rb +275 -0
  66. data/app/models/log4r/papertrail_outputter.rb +19 -0
  67. data/app/models/logical/naf/application.rb +183 -0
  68. data/app/models/logical/naf/construction_zone/ad_hoc_work_order.rb +22 -0
  69. data/app/models/logical/naf/construction_zone/application_schedule_work_order.rb +15 -0
  70. data/app/models/logical/naf/construction_zone/application_work_order.rb +25 -0
  71. data/app/models/logical/naf/construction_zone/boss.rb +123 -0
  72. data/app/models/logical/naf/construction_zone/foreman.rb +53 -0
  73. data/app/models/logical/naf/construction_zone/proletariat.rb +40 -0
  74. data/app/models/logical/naf/construction_zone/work_order.rb +100 -0
  75. data/app/models/logical/naf/create_infrastructure.rb +48 -0
  76. data/app/models/logical/naf/job.rb +357 -0
  77. data/app/models/logical/naf/job_creator.rb +155 -0
  78. data/app/models/logical/naf/job_fetcher.rb +167 -0
  79. data/app/models/logical/naf/job_statuses/errored.rb +27 -0
  80. data/app/models/logical/naf/job_statuses/finished.rb +26 -0
  81. data/app/models/logical/naf/job_statuses/finished_less_minute.rb +25 -0
  82. data/app/models/logical/naf/job_statuses/queued.rb +32 -0
  83. data/app/models/logical/naf/job_statuses/running.rb +34 -0
  84. data/app/models/logical/naf/job_statuses/terminated.rb +25 -0
  85. data/app/models/logical/naf/job_statuses/waiting.rb +43 -0
  86. data/app/models/logical/naf/machine.rb +85 -0
  87. data/app/models/logical/naf/machine_runner.rb +46 -0
  88. data/app/models/logical/naf/machine_runner_invocation.rb +50 -0
  89. data/app/models/logical/naf/pickler.rb +74 -0
  90. data/app/models/logical/naf/unpickler.rb +98 -0
  91. data/app/models/naf/affinity.rb +145 -0
  92. data/app/models/naf/affinity_classification.rb +44 -0
  93. data/app/models/naf/application.rb +100 -0
  94. data/app/models/naf/application_run_group_restriction.rb +39 -0
  95. data/app/models/naf/application_schedule.rb +181 -0
  96. data/app/models/naf/application_schedule_affinity_tab.rb +86 -0
  97. data/app/models/naf/application_schedule_prerequisite.rb +50 -0
  98. data/app/models/naf/application_type.rb +72 -0
  99. data/app/models/naf/by_historical_job_id.rb +86 -0
  100. data/app/models/naf/historical_job.rb +334 -0
  101. data/app/models/naf/historical_job_affinity_tab.rb +61 -0
  102. data/app/models/naf/historical_job_prerequisite.rb +19 -0
  103. data/app/models/naf/janitorial_archive_assignment.rb +36 -0
  104. data/app/models/naf/janitorial_assignment.rb +37 -0
  105. data/app/models/naf/janitorial_create_assignment.rb +36 -0
  106. data/app/models/naf/janitorial_drop_assignment.rb +36 -0
  107. data/app/models/naf/logger_level.rb +21 -0
  108. data/app/models/naf/logger_name.rb +23 -0
  109. data/app/models/naf/logger_style.rb +58 -0
  110. data/app/models/naf/logger_style_name.rb +28 -0
  111. data/app/models/naf/machine.rb +257 -0
  112. data/app/models/naf/machine_affinity_slot.rb +78 -0
  113. data/app/models/naf/machine_runner.rb +51 -0
  114. data/app/models/naf/machine_runner_invocation.rb +71 -0
  115. data/app/models/naf/naf_base.rb +9 -0
  116. data/app/models/naf/queued_job.rb +164 -0
  117. data/app/models/naf/running_job.rb +80 -0
  118. data/app/models/process/naf/application.rb +164 -0
  119. data/app/models/process/naf/janitor.rb +117 -0
  120. data/app/models/process/naf/machine_manager.rb +150 -0
  121. data/app/models/process/naf/machine_upgrader.rb +112 -0
  122. data/app/models/process/naf/runner.rb +539 -0
  123. data/app/views/naf/affinities/_form.html.erb +50 -0
  124. data/app/views/naf/affinities/edit.html.erb +11 -0
  125. data/app/views/naf/affinities/index.html.erb +57 -0
  126. data/app/views/naf/affinities/new.html.erb +15 -0
  127. data/app/views/naf/affinities/show.html.erb +48 -0
  128. data/app/views/naf/application_schedule_affinity_tabs/_form.html.erb +31 -0
  129. data/app/views/naf/application_schedule_affinity_tabs/edit.html.erb +12 -0
  130. data/app/views/naf/application_schedule_affinity_tabs/new.html.erb +11 -0
  131. data/app/views/naf/applications/_application_schedule.html.erb +80 -0
  132. data/app/views/naf/applications/_application_schedule_prerequisites.html.erb +14 -0
  133. data/app/views/naf/applications/_form.html.erb +109 -0
  134. data/app/views/naf/applications/_search_container.html.erb +94 -0
  135. data/app/views/naf/applications/_show.html.erb +34 -0
  136. data/app/views/naf/applications/edit.html.erb +11 -0
  137. data/app/views/naf/applications/index.html.erb +51 -0
  138. data/app/views/naf/applications/index.json.erb +11 -0
  139. data/app/views/naf/applications/new.html.erb +11 -0
  140. data/app/views/naf/applications/show.html.erb +203 -0
  141. data/app/views/naf/datatable.html.erb +49 -0
  142. data/app/views/naf/historical_job_affinity_tabs/_form.html.erb +36 -0
  143. data/app/views/naf/historical_job_affinity_tabs/edit.html.erb +11 -0
  144. data/app/views/naf/historical_job_affinity_tabs/new.html.erb +11 -0
  145. data/app/views/naf/historical_jobs/_form.html.erb +94 -0
  146. data/app/views/naf/historical_jobs/_runners.html.erb +22 -0
  147. data/app/views/naf/historical_jobs/_search_container.html.erb +140 -0
  148. data/app/views/naf/historical_jobs/edit.html.erb +11 -0
  149. data/app/views/naf/historical_jobs/index.html.erb +48 -0
  150. data/app/views/naf/historical_jobs/index.json.erb +26 -0
  151. data/app/views/naf/historical_jobs/new.html.erb +61 -0
  152. data/app/views/naf/historical_jobs/show.html.erb +201 -0
  153. data/app/views/naf/janitorial_assignments/_form.html.erb +38 -0
  154. data/app/views/naf/janitorial_assignments/_rows.html.erb +17 -0
  155. data/app/views/naf/janitorial_assignments/edit.html.erb +11 -0
  156. data/app/views/naf/janitorial_assignments/index.html.erb +56 -0
  157. data/app/views/naf/janitorial_assignments/index.js.erb +1 -0
  158. data/app/views/naf/janitorial_assignments/new.html.erb +11 -0
  159. data/app/views/naf/layouts/jquery_datatables.json.erb +6 -0
  160. data/app/views/naf/logger_names/_form.html.erb +18 -0
  161. data/app/views/naf/logger_names/edit.html.erb +11 -0
  162. data/app/views/naf/logger_names/new.html.erb +11 -0
  163. data/app/views/naf/logger_names/show.html.erb +44 -0
  164. data/app/views/naf/logger_styles/_form.html.erb +30 -0
  165. data/app/views/naf/logger_styles/_logger_style_names.html.erb +19 -0
  166. data/app/views/naf/logger_styles/edit.html.erb +11 -0
  167. data/app/views/naf/logger_styles/new.html.erb +11 -0
  168. data/app/views/naf/logger_styles/show.html.erb +48 -0
  169. data/app/views/naf/machine_affinity_slots/_form.html.erb +36 -0
  170. data/app/views/naf/machine_affinity_slots/edit.html.erb +11 -0
  171. data/app/views/naf/machine_affinity_slots/new.html.erb +11 -0
  172. data/app/views/naf/machine_runner_invocations/_filter.html.erb +21 -0
  173. data/app/views/naf/machine_runner_invocations/index.html.erb +36 -0
  174. data/app/views/naf/machine_runner_invocations/index.json.erb +16 -0
  175. data/app/views/naf/machine_runner_invocations/show.html.erb +91 -0
  176. data/app/views/naf/machine_runners/index.html.erb +82 -0
  177. data/app/views/naf/machine_runners/index.json.erb +16 -0
  178. data/app/views/naf/machine_runners/show.html.erb +113 -0
  179. data/app/views/naf/machines/_filter.html.erb +26 -0
  180. data/app/views/naf/machines/_form.html.erb +62 -0
  181. data/app/views/naf/machines/_show.html.erb +169 -0
  182. data/app/views/naf/machines/edit.html.erb +11 -0
  183. data/app/views/naf/machines/index.html.erb +51 -0
  184. data/app/views/naf/machines/index.json.erb +23 -0
  185. data/app/views/naf/machines/new.html.erb +11 -0
  186. data/app/views/naf/machines/show.html.erb +92 -0
  187. data/app/views/naf/record.html.erb +46 -0
  188. data/app/views/naf/shared/_application.html.erb +50 -0
  189. data/app/views/naf/shared/_information_container.html.erb +19 -0
  190. data/app/views/naf/shared/_select_per_page.html.erb +72 -0
  191. data/ci/test-build.sh +17 -0
  192. data/ci/travis.sh +26 -0
  193. data/config/initializers/naf.rb +3 -0
  194. data/config/routes.rb +38 -0
  195. data/db/migrate/20120820023848_naf_schema.rb +413 -0
  196. data/doc/README_FOR_APP +2 -0
  197. data/lib/generators/naf_generator.rb +45 -0
  198. data/lib/generators/templates/config/logging/af.yml +26 -0
  199. data/lib/generators/templates/config/logging/naf.yml +22 -0
  200. data/lib/generators/templates/config/logging/nafjob.yml +16 -0
  201. data/lib/generators/templates/config/logging/nafrunner.yml +17 -0
  202. data/lib/generators/templates/naf.rb +11 -0
  203. data/lib/generators/templates/naf_layout.html.erb +15 -0
  204. data/lib/naf.rb +48 -0
  205. data/lib/naf/configuration.rb +23 -0
  206. data/lib/naf/engine.rb +18 -0
  207. data/lib/naf/version.rb +3 -0
  208. data/lib/tasks/naf_tasks.rake +370 -0
  209. data/naf.gemspec +30 -0
  210. data/script/rails +10 -0
  211. data/spec/controllers/naf/affinities_controller_spec.rb +79 -0
  212. data/spec/controllers/naf/application_controller_spec.rb +10 -0
  213. data/spec/controllers/naf/application_schedule_affinity_tabs_controller_spec.rb +106 -0
  214. data/spec/controllers/naf/applications_controller_spec.rb +109 -0
  215. data/spec/controllers/naf/historical_job_affinity_tabs_controller_spec.rb +96 -0
  216. data/spec/controllers/naf/historical_jobs_controller_spec.rb +19 -0
  217. data/spec/controllers/naf/machine_affinity_slots_controller_spec.rb +109 -0
  218. data/spec/controllers/naf/machines_controller_spec.rb +74 -0
  219. data/spec/dummy/.gitignore +12 -0
  220. data/spec/dummy/README +19 -0
  221. data/spec/dummy/Rakefile +7 -0
  222. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  223. data/spec/dummy/app/assets/stylesheets/application.css +14 -0
  224. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  225. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  226. data/spec/dummy/app/models/my_script.rb +8 -0
  227. data/spec/dummy/app/models/other/base.rb.sample +10 -0
  228. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  229. data/spec/dummy/app/views/layouts/naf_layout.html.erb +15 -0
  230. data/spec/dummy/config.ru +4 -0
  231. data/spec/dummy/config/application.rb +62 -0
  232. data/spec/dummy/config/boot.rb +10 -0
  233. data/spec/dummy/config/database-non_primary.yml +20 -0
  234. data/spec/dummy/config/database-primary.yml +16 -0
  235. data/spec/dummy/config/environment.rb +5 -0
  236. data/spec/dummy/config/environments/development.rb +37 -0
  237. data/spec/dummy/config/environments/production.rb +67 -0
  238. data/spec/dummy/config/environments/test.rb +37 -0
  239. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  240. data/spec/dummy/config/initializers/inflections.rb +15 -0
  241. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  242. data/spec/dummy/config/initializers/naf.rb.non_primary +4 -0
  243. data/spec/dummy/config/initializers/naf.rb.primary +3 -0
  244. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  245. data/spec/dummy/config/initializers/session_store.rb +8 -0
  246. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  247. data/spec/dummy/config/locales/en.yml +5 -0
  248. data/spec/dummy/config/logging/af.yml +26 -0
  249. data/spec/dummy/config/logging/naf.yml +22 -0
  250. data/spec/dummy/config/logging/nafjob.yml +16 -0
  251. data/spec/dummy/config/logging/nafrunner.yml +17 -0
  252. data/spec/dummy/config/routes.rb +5 -0
  253. data/spec/dummy/db/.gitignore +2 -0
  254. data/spec/dummy/lib/tasks/dummy.rake +60 -0
  255. data/spec/dummy/public/404.html +26 -0
  256. data/spec/dummy/public/422.html +26 -0
  257. data/spec/dummy/public/500.html +25 -0
  258. data/spec/dummy/public/favicon.ico +0 -0
  259. data/spec/dummy/script/rails +6 -0
  260. data/spec/factories/naf.rb +433 -0
  261. data/spec/helpers/naf/application_helper_spec.rb +0 -0
  262. data/spec/models/logical/naf/application_spec.rb +69 -0
  263. data/spec/models/logical/naf/job_creator_spec.rb +32 -0
  264. data/spec/models/logical/naf/job_fetcher_spec.rb +140 -0
  265. data/spec/models/logical/naf/job_spec.rb +282 -0
  266. data/spec/models/logical/naf/machine_spec.rb +61 -0
  267. data/spec/models/naf/affinity_classification_spec.rb +56 -0
  268. data/spec/models/naf/affinity_spec.rb +100 -0
  269. data/spec/models/naf/application_run_group_restriction_spec.rb +57 -0
  270. data/spec/models/naf/application_schedule_affinity_tab_spec.rb +85 -0
  271. data/spec/models/naf/application_schedule_prerequisite_spec.rb +35 -0
  272. data/spec/models/naf/application_schedule_spec.rb +166 -0
  273. data/spec/models/naf/application_spec.rb +128 -0
  274. data/spec/models/naf/application_type_spec.rb +104 -0
  275. data/spec/models/naf/historical_job_affinity_tab_spec.rb +59 -0
  276. data/spec/models/naf/historical_job_prerequisite_spec.rb +25 -0
  277. data/spec/models/naf/historical_job_spec.rb +334 -0
  278. data/spec/models/naf/logger_level_spec.rb +34 -0
  279. data/spec/models/naf/logger_name_spec.rb +35 -0
  280. data/spec/models/naf/logger_style_name_spec.rb +39 -0
  281. data/spec/models/naf/logger_style_spec.rb +89 -0
  282. data/spec/models/naf/machine_affinity_slot_spec.rb +77 -0
  283. data/spec/models/naf/machine_runner_invocation_spec.rb +38 -0
  284. data/spec/models/naf/machine_runner_spec.rb +37 -0
  285. data/spec/models/naf/machine_spec.rb +425 -0
  286. data/spec/models/naf/naf_base_spec.rb +14 -0
  287. data/spec/models/naf/queued_job_spec.rb +171 -0
  288. data/spec/models/naf/running_job_spec.rb +107 -0
  289. data/spec/models/process/naf/application_spec.rb +8 -0
  290. data/spec/models/process/naf/janitor_spec.rb +10 -0
  291. data/spec/models/process/naf/runner_spec.rb +10 -0
  292. data/spec/spec_helper.rb +32 -0
  293. data/spec/support/engine_routing.rb +27 -0
  294. data/spec/support/script_spec_helper.rb +58 -0
  295. metadata +590 -0
@@ -0,0 +1,44 @@
1
+ module Naf
2
+ class AffinityClassification < NafBase
3
+ # Protect from mass-assignment issue
4
+ attr_accessible :affinity_classification_name
5
+
6
+ #---------------------
7
+ # *** Associations ***
8
+ #+++++++++++++++++++++
9
+
10
+ has_many :affinities, dependent: :destroy
11
+
12
+ #--------------------
13
+ # *** Validations ***
14
+ #++++++++++++++++++++
15
+
16
+ validates :affinity_classification_name, presence: true,
17
+ length: { minimum: 1 }
18
+
19
+ #-------------------------
20
+ # *** Class Methods ***
21
+ #+++++++++++++++++++++++++
22
+
23
+ def self.purpose
24
+ @@purpose ||= find_by_affinity_classification_name('purpose')
25
+ end
26
+
27
+ def self.location
28
+ @@location ||= find_by_affinity_classification_name('location')
29
+ end
30
+
31
+ def self.application
32
+ @@application ||= find_by_affinity_classification_name('application')
33
+ end
34
+
35
+ def self.weight
36
+ @@weight ||= find_by_affinity_classification_name('weight')
37
+ end
38
+
39
+ def self.machine
40
+ @@machine ||= find_by_affinity_classification_name('machine')
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,100 @@
1
+ module Naf
2
+ class Application < NafBase
3
+ # Protect from mass-assignment issue
4
+ attr_accessible :title,
5
+ :command,
6
+ :application_type_id,
7
+ :log_level,
8
+ :short_name,
9
+ :deleted,
10
+ :application_schedule,
11
+ :application_schedule_attributes
12
+
13
+ #---------------------
14
+ # *** Associations ***
15
+ #+++++++++++++++++++++
16
+
17
+ belongs_to :application_type,
18
+ class_name: '::Naf::ApplicationType'
19
+ has_one :application_schedule,
20
+ class_name: '::Naf::ApplicationSchedule',
21
+ dependent: :destroy
22
+ has_many :historical_jobs,
23
+ class_name: '::Naf::HistoricalJob'
24
+
25
+ #--------------------
26
+ # *** Validations ***
27
+ #++++++++++++++++++++
28
+
29
+ validates :application_type_id,
30
+ :command,
31
+ :title, presence: true
32
+ validates :title, uniqueness: true
33
+ validates :short_name, uniqueness: true,
34
+ allow_blank: true,
35
+ allow_nil: true,
36
+ format: {
37
+ with: /^[a-zA-Z_][a-zA-Z0-9_]*$/,
38
+ message: "letters should be first"
39
+ }
40
+
41
+ validate :check_references_with_application_schedule_prerequisites
42
+ before_save :check_blank_values
43
+ accepts_nested_attributes_for :application_schedule, allow_destroy: true
44
+
45
+ #--------------------
46
+ # *** Delegations ***
47
+ #++++++++++++++++++++
48
+
49
+ delegate :script_type_name, to: :application_type
50
+
51
+ #-------------------------
52
+ # *** Instance Methods ***
53
+ #+++++++++++++++++++++++++
54
+
55
+ def to_s
56
+ components = []
57
+ components << "DELETED" if deleted
58
+ components << "id: #{id}"
59
+ components << title
60
+
61
+ return "::Naf::Application<#{components.join(', ')}>"
62
+ end
63
+
64
+ def last_queued_job
65
+ last_queued_job = ::Naf::HistoricalJob.
66
+ queued_between(Time.zone.now - Naf::HistoricalJob::JOB_STALE_TIME, Time.zone.now).
67
+ where(application_id: self.id).
68
+ group(:application_id).
69
+ select("application_id, MAX(id) AS id").first
70
+ last_queued_job ? Naf::HistoricalJob.find(last_queued_job.id) : nil
71
+ end
72
+
73
+ def short_name_if_it_exist
74
+ short_name || title
75
+ end
76
+
77
+ def self.pickleables(pickler)
78
+ self.where(deleted: false)
79
+ end
80
+
81
+ private
82
+
83
+ def check_blank_values
84
+ self.short_name = nil if self.short_name.blank?
85
+ self.log_level = nil if self.log_level.blank?
86
+ end
87
+
88
+ def check_references_with_application_schedule_prerequisites
89
+ if application_schedule.try(:marked_for_destruction?)
90
+ prerequisites = Naf::ApplicationSchedulePrerequisite.
91
+ where(prerequisite_application_schedule_id: application_schedule.id).all
92
+ unless prerequisites.blank?
93
+ errors.add(:base, "Cannot delete scheduler, because the following applications are referenced to it: " +
94
+ "#{prerequisites.map{ |pre| pre.application_schedule.title }.join(', ') }")
95
+ end
96
+ end
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,39 @@
1
+ module Naf
2
+ class ApplicationRunGroupRestriction < NafBase
3
+ # Protect from mass-assignment issue
4
+ attr_accessible :application_run_group_restriction_name
5
+
6
+ #---------------------
7
+ # *** Associations ***
8
+ #+++++++++++++++++++++
9
+
10
+ has_many :application_schedules,
11
+ class_name: '::Naf::ApplicationSchedule'
12
+ has_many :historical_jobs,
13
+ class_name: '::Naf::HistoricalJob'
14
+
15
+ #--------------------
16
+ # *** Validations ***
17
+ #++++++++++++++++++++
18
+
19
+ validates :application_run_group_restriction_name, presence: true
20
+
21
+ #-------------------------
22
+ # *** Class Methods ***
23
+ #+++++++++++++++++++++++++
24
+
25
+
26
+ def self.no_limit
27
+ @no_limit ||= find_by_application_run_group_restriction_name('no limit')
28
+ end
29
+
30
+ def self.limited_per_machine
31
+ @limited_per_machine ||= find_by_application_run_group_restriction_name('limited per machine')
32
+ end
33
+
34
+ def self.limited_per_all_machines
35
+ @limited_per_all_machines ||= find_by_application_run_group_restriction_name('limited per all machines')
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,181 @@
1
+ module Naf
2
+ class ApplicationSchedule < NafBase
3
+ include PgAdvisoryLocker
4
+
5
+ # Protect from mass-assignment issue
6
+ attr_accessible :application_id,
7
+ :application_run_group_restriction_id,
8
+ :application_run_group_name,
9
+ :run_interval,
10
+ :priority,
11
+ :visible,
12
+ :enabled,
13
+ :run_start_minute,
14
+ :application_run_group_limit,
15
+ :application_schedule_prerequisites_attributes,
16
+ :enqueue_backlogs
17
+
18
+ SCHEDULES_LOCK_ID = 0
19
+
20
+ #---------------------
21
+ # *** Associations ***
22
+ #+++++++++++++++++++++
23
+
24
+ belongs_to :application,
25
+ class_name: '::Naf::Application'
26
+ belongs_to :application_run_group_restriction,
27
+ class_name: '::Naf::ApplicationRunGroupRestriction'
28
+ has_many :application_schedule_affinity_tabs,
29
+ class_name: '::Naf::ApplicationScheduleAffinityTab',
30
+ dependent: :destroy
31
+ has_many :affinities,
32
+ through: :application_schedule_affinity_tabs
33
+ has_many :application_schedule_prerequisites,
34
+ class_name: "::Naf::ApplicationSchedulePrerequisite",
35
+ dependent: :destroy
36
+ has_many :prerequisites,
37
+ class_name: "::Naf::ApplicationSchedule",
38
+ through: :application_schedule_prerequisites,
39
+ source: :prerequisite_application_schedule
40
+
41
+ accepts_nested_attributes_for :application_schedule_prerequisites, allow_destroy: true
42
+
43
+ #--------------------
44
+ # *** Validations ***
45
+ #++++++++++++++++++++
46
+
47
+ validates :application_run_group_restriction_id, presence: true
48
+ validates :priority, numericality: {
49
+ only_integer: true,
50
+ greater_than: -2147483648,
51
+ less_than: 2147483647
52
+ }
53
+ validates :application_run_group_limit, numericality: {
54
+ only_integer: true,
55
+ greater_than_or_equal_to: 1,
56
+ less_than: 2147483647,
57
+ allow_blank: true
58
+ }
59
+ validates :run_start_minute, numericality: {
60
+ only_integer: true,
61
+ greater_than_or_equal_to: 0,
62
+ less_than: 24*60,
63
+ allow_blank: true
64
+ }
65
+ validates :run_interval, numericality: {
66
+ only_integer: true,
67
+ greater_than_or_equal_to: 0,
68
+ less_than: 2147483647,
69
+ allow_blank: true
70
+ }
71
+
72
+ before_save :check_blank_values
73
+ validate :visible_enabled_check
74
+ validate :run_interval_at_time_check
75
+ validate :enabled_application_id_unique
76
+ validate :prerequisite_application_schedule_id_uniqueness
77
+
78
+ #--------------------
79
+ # *** Delegations ***
80
+ #++++++++++++++++++++
81
+
82
+ delegate :title, to: :application
83
+ delegate :application_run_group_restriction_name, to: :application_run_group_restriction
84
+
85
+ #----------------------
86
+ # *** Class Methods ***
87
+ #++++++++++++++++++++++
88
+
89
+ def self.try_lock_schedules
90
+ try_lock_record(SCHEDULES_LOCK_ID)
91
+ end
92
+
93
+ def self.unlock_schedules
94
+ unlock_record(SCHEDULES_LOCK_ID)
95
+ end
96
+
97
+ def self.exact_schedules
98
+ where('run_start_minute is not null')
99
+ end
100
+
101
+ def self.relative_schedules
102
+ where('run_interval >= 0')
103
+ end
104
+
105
+ def self.pickables
106
+ # check the application is deleted
107
+ self.where(:deleted => false)
108
+ end
109
+
110
+ #-------------------------
111
+ # *** Instance Methods ***
112
+ #+++++++++++++++++++++++++
113
+
114
+ def to_s
115
+ components = []
116
+ if enabled
117
+ components << "ENABLED"
118
+ else
119
+ if visible
120
+ components << "DISABLED"
121
+ else
122
+ components << "HIDDEN|DISABLED"
123
+ end
124
+ end
125
+ components << "id: #{id}"
126
+ components << "\"#{application.title}\""
127
+ if run_start_minute
128
+ components << "start at: #{"%02d" % (run_start_minute/60)}:#{"%02d" % (run_start_minute%60)}"
129
+ else
130
+ components << "start every: #{run_interval} minutes"
131
+ end
132
+
133
+ return "::Naf::ApplicationSchedule<#{components.join(', ')}>"
134
+ end
135
+
136
+ def visible_enabled_check
137
+ unless visible or !enabled
138
+ errors.add(:visible, "must be true, or set enabled to false")
139
+ errors.add(:enabled, "must be false, if visible is set to false")
140
+ end
141
+ end
142
+
143
+ def enabled_application_id_unique
144
+ return unless enabled
145
+
146
+ if id
147
+ conditions = ["id <> ? AND application_id = ? AND enabled = ?", id, application_id, true]
148
+ else
149
+ conditions = ["application_id = ? AND enabled = ?", application_id, true]
150
+ end
151
+
152
+ num_collisions = self.class.count(conditions: conditions)
153
+ errors.add(:application_id, "is enabled and has already been taken") if num_collisions > 0
154
+ end
155
+
156
+ def run_interval_at_time_check
157
+ unless (run_start_minute.blank? || run_interval.blank?)
158
+ errors.add(:run_interval, "or Run start minute must be nil")
159
+ errors.add(:run_start_minute, "or Run interval must be nil")
160
+ end
161
+ end
162
+
163
+ def self.pickleables(pickler)
164
+ self.joins(:application).
165
+ where("#{::Naf.schema_name}.applications.deleted IS FALSE")
166
+ end
167
+
168
+ private
169
+
170
+ def prerequisite_application_schedule_id_uniqueness
171
+ if application_schedule_prerequisites.map{ |asp| asp.prerequisite_application_schedule_id }.uniq!
172
+ errors.add(:prerequisite_application_schedule_id, "should be an uniqueness")
173
+ end
174
+ end
175
+
176
+ def check_blank_values
177
+ self.application_run_group_name = nil if self.application_run_group_name.blank?
178
+ end
179
+
180
+ end
181
+ end
@@ -0,0 +1,86 @@
1
+ module Naf
2
+ class ApplicationScheduleAffinityTab < NafBase
3
+ # Protect from mass-assignment issue
4
+ attr_accessible :application_schedule_id,
5
+ :affinity_id,
6
+ :affinity_parameter
7
+
8
+ #---------------------
9
+ # *** Associations ***
10
+ #+++++++++++++++++++++
11
+
12
+ belongs_to :application_schedule,
13
+ class_name: '::Naf::ApplicationSchedule'
14
+ belongs_to :affinity,
15
+ class_name: '::Naf::Affinity'
16
+
17
+ #--------------------
18
+ # *** Validations ***
19
+ #++++++++++++++++++++
20
+
21
+ validates :application_schedule_id,
22
+ :affinity_id, presence: true
23
+ validates_uniqueness_of :affinity_id, scope: :application_schedule_id,
24
+ message: 'has already been taken for this script'
25
+
26
+ #--------------------
27
+ # *** Delegations ***
28
+ #++++++++++++++++++++
29
+
30
+ delegate :affinity_name,
31
+ :affinity_classification_name, to: :affinity
32
+
33
+
34
+ #-------------------------
35
+ # *** Instance Methods ***
36
+ #+++++++++++++++++++++++++
37
+
38
+ def script_title
39
+ application_schedule.title
40
+ end
41
+
42
+ def application
43
+ if schedule = application_schedule
44
+ application_schedule.application
45
+ else
46
+ nil
47
+ end
48
+ end
49
+
50
+ def self.pickleables(pickler)
51
+ self.joins([application_schedule: :application]).
52
+ where('applications.deleted = false')
53
+ end
54
+
55
+ def pickle(pickler, associations = nil, ignored_attributes = [:created_at, :updated_at])
56
+ instance_attributes = attributes.symbolize_keys
57
+ ignored_attributes.each do |ignored_attribute|
58
+ instance_attributes.delete(ignored_attribute.to_sym)
59
+ end
60
+
61
+ unless associations
62
+ associations = {}
63
+ instance_attributes.keys.select{|key| key.to_s =~ /_id$/}.each do |key|
64
+ association_name = key.to_s[0..-4].to_sym
65
+ association = association(association_name) rescue nil
66
+ if association
67
+ associations[key] = association.options[:class_name].constantize.name
68
+ end
69
+ end
70
+ end
71
+
72
+ return Hash[instance_attributes.map { |key, value|
73
+ if associations[key] == 'Naf::Affinity'
74
+ [key, { association_model_name: associations[key],
75
+ association_classification_value: affinity.affinity_classification_id,
76
+ association_affinity_value: affinity.affinity_name }]
77
+ elsif associations[key] == 'Naf::ApplicationSchedule'
78
+ [key, { association_model_name: associations[key], association_value: value }]
79
+ else
80
+ [key,value]
81
+ end
82
+ } ]
83
+ end
84
+
85
+ end
86
+ end