workflow.models.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. // Licensed to Cloudera, Inc. under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. Cloudera, Inc. licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. // Since knockout maps arrays without calling "update" nor "create"
  17. // Provide a JSON string that will be parsed in custom 'create' and 'update' functions.
  18. // These serialized values are also stored in the backend.
  19. var MODEL_FIELDS_JSON = ['parameters', 'job_properties', 'files', 'archives', 'prepares', 'params',
  20. 'deletes', 'mkdirs', 'moves', 'chmods', 'touchzs'];
  21. function normalize_model_fields(node_model) {
  22. $.each(MODEL_FIELDS_JSON, function(index, field) {
  23. if (field in node_model && $.isArray(node_model[field])) {
  24. node_model[field] = JSON.stringify(node_model[field]);
  25. }
  26. });
  27. return node_model;
  28. }
  29. // Parse JSON if it is JSON and appropriately map.
  30. // Apply subscriber to each mapping.
  31. var map_params = function(options, subscribe) {
  32. options.data = ($.type(options.data) == "string") ? $.parseJSON(options.data) : options.data;
  33. if ($.isArray(options.data)) {
  34. var mapping = ko.mapping.fromJS(options.data);
  35. $.each(mapping(), function(index, value) {
  36. subscribe(value);
  37. });
  38. return mapping;
  39. } else {
  40. var mapping = ko.mapping.fromJS(options.data, {});
  41. subscribe(mapping);
  42. return mapping;
  43. }
  44. };
  45. // Maps JSON strings to fields in the view model.
  46. var MAPPING_OPTIONS = {
  47. ignore: ['initialize', 'toString', 'copy'],
  48. job_properties: {
  49. create: function(options) {
  50. var parent = options.parent;
  51. var subscribe = function(mapping) {
  52. mapping.name.subscribe(function(value) {
  53. parent.job_properties.valueHasMutated();
  54. });
  55. mapping.value.subscribe(function(value) {
  56. parent.job_properties.valueHasMutated();
  57. });
  58. };
  59. return map_params(options, subscribe);
  60. },
  61. update: function(options) {
  62. var parent = options.parent;
  63. var subscribe = function(mapping) {
  64. mapping.name.subscribe(function(value) {
  65. parent.job_properties.valueHasMutated();
  66. });
  67. mapping.value.subscribe(function(value) {
  68. parent.job_properties.valueHasMutated();
  69. });
  70. };
  71. return map_params(options, subscribe);
  72. }
  73. },
  74. files: {
  75. create: function(options) {
  76. return map_params(options, function() {});
  77. },
  78. update: function(options) {
  79. return map_params(options, function() {});
  80. }
  81. },
  82. archives: {
  83. create: function(options) {
  84. var parent = options.parent;
  85. var subscribe = function(mapping) {
  86. mapping.name.subscribe(function(value) {
  87. parent.archives.valueHasMutated();
  88. });
  89. mapping.dummy.subscribe(function(value) {
  90. parent.archives.valueHasMutated();
  91. });
  92. };
  93. return map_params(options, subscribe);
  94. },
  95. update: function(options) {
  96. var parent = options.parent;
  97. var subscribe = function(mapping) {
  98. mapping.name.subscribe(function(value) {
  99. parent.archives.valueHasMutated();
  100. });
  101. mapping.dummy.subscribe(function(value) {
  102. parent.archives.valueHasMutated();
  103. });
  104. };
  105. return map_params(options, subscribe);
  106. }
  107. },
  108. params: {
  109. create: function(options) {
  110. var parent = options.parent;
  111. var subscribe = function(mapping) {
  112. mapping.value.subscribe(function(value) {
  113. parent.params.valueHasMutated();
  114. });
  115. mapping.type.subscribe(function(value) {
  116. parent.params.valueHasMutated();
  117. });
  118. };
  119. return map_params(options, subscribe);
  120. },
  121. update: function(options) {
  122. var parent = options.parent;
  123. var subscribe = function(mapping) {
  124. mapping.value.subscribe(function(value) {
  125. parent.params.valueHasMutated();
  126. });
  127. mapping.type.subscribe(function(value) {
  128. parent.params.valueHasMutated();
  129. });
  130. };
  131. return map_params(options, subscribe);
  132. }
  133. },
  134. prepares: {
  135. create: function(options) {
  136. var parent = options.parent;
  137. var subscribe = function(mapping) {
  138. mapping.value.subscribe(function(value) {
  139. parent.prepares.valueHasMutated();
  140. });
  141. mapping.type.subscribe(function(value) {
  142. parent.prepares.valueHasMutated();
  143. });
  144. };
  145. return map_params(options, subscribe);
  146. },
  147. update: function(options) {
  148. var parent = options.parent;
  149. var subscribe = function(mapping) {
  150. mapping.value.subscribe(function(value) {
  151. parent.prepares.valueHasMutated();
  152. });
  153. mapping.type.subscribe(function(value) {
  154. parent.prepares.valueHasMutated();
  155. });
  156. };
  157. return map_params(options, subscribe);
  158. }
  159. },
  160. deletes: {
  161. create: function(options) {
  162. return map_params(options, function() {});
  163. },
  164. update: function(options) {
  165. return map_params(options, function() {});
  166. },
  167. },
  168. mkdirs: {
  169. create: function(options) {
  170. return map_params(options, function() {});
  171. },
  172. update: function(options) {
  173. return map_params(options, function() {});
  174. },
  175. },
  176. moves: {
  177. create: function(options) {
  178. var parent = options.parent;
  179. var subscribe = function(mapping) {
  180. mapping.source.subscribe(function(value) {
  181. parent.moves.valueHasMutated();
  182. });
  183. mapping.destination.subscribe(function(value) {
  184. parent.moves.valueHasMutated();
  185. });
  186. };
  187. return map_params(options, subscribe);
  188. },
  189. update: function(options) {
  190. var parent = options.parent;
  191. var subscribe = function(mapping) {
  192. mapping.source.subscribe(function(value) {
  193. parent.moves.valueHasMutated();
  194. });
  195. mapping.destination.subscribe(function(value) {
  196. parent.moves.valueHasMutated();
  197. });
  198. };
  199. return map_params(options, subscribe);
  200. }
  201. },
  202. chmods: {
  203. create: function(options) {
  204. var parent = options.parent;
  205. var subscribe = function(mapping) {
  206. mapping.path.subscribe(function(value) {
  207. parent.chmods.valueHasMutated();
  208. });
  209. mapping.permissions.subscribe(function(value) {
  210. parent.chmods.valueHasMutated();
  211. });
  212. mapping.recursive.subscribe(function(value) {
  213. parent.chmods.valueHasMutated();
  214. });
  215. };
  216. return map_params(options, subscribe);
  217. },
  218. update: function(options) {
  219. var parent = options.parent;
  220. var subscribe = function(mapping) {
  221. mapping.path.subscribe(function(value) {
  222. parent.chmods.valueHasMutated();
  223. });
  224. mapping.permissions.subscribe(function(value) {
  225. parent.chmods.valueHasMutated();
  226. });
  227. mapping.recursive.subscribe(function(value) {
  228. parent.chmods.valueHasMutated();
  229. });
  230. };
  231. return map_params(options, subscribe);
  232. },
  233. },
  234. touchzs: {
  235. create: function(options) {
  236. return map_params(options, function() {});
  237. },
  238. update: function(options) {
  239. return map_params(options, function() {});
  240. }
  241. }
  242. };
  243. var ModelModule = function($) {
  244. var module = function(attrs) {
  245. var self = this;
  246. $.extend(self, attrs);
  247. module.prototype.initialize.apply(self, arguments);
  248. return self;
  249. };
  250. $.extend(module.prototype, {
  251. // Normal stuff
  252. initialize: function(){},
  253. toString: function() {
  254. var self = this;
  255. return JSON.stringify(self, null, '\t');
  256. },
  257. copy: function() {
  258. var self = this;
  259. var model = $.extend(true, {}, self);
  260. $.each(MODEL_FIELDS_JSON, function(i, field) {
  261. if (field in model && $.type(model[field]) != "string") {
  262. model[field] = JSON.stringify(model[field]);
  263. }
  264. });
  265. return model;
  266. }
  267. });
  268. return module;
  269. };
  270. var WorkflowModel = ModelModule($);
  271. $.extend(WorkflowModel.prototype, {
  272. id: 0,
  273. name: '',
  274. description: '',
  275. start: 0,
  276. end: 0,
  277. schema_version: 0.4,
  278. deployment_dir: '',
  279. is_shared: true,
  280. parameters: '[]',
  281. job_xml: ''
  282. });
  283. var NodeModel = ModelModule($);
  284. $.extend(NodeModel.prototype, {
  285. id: 0,
  286. name: '',
  287. description: '',
  288. node_type: '',
  289. workflow: 0,
  290. child_links: []
  291. });
  292. var ForkModel = ModelModule($);
  293. $.extend(ForkModel.prototype, {
  294. id: 0,
  295. name: '',
  296. description: '',
  297. node_type: 'fork',
  298. workflow: 0,
  299. child_links: []
  300. });
  301. var DecisionModel = ModelModule($);
  302. $.extend(DecisionModel.prototype, {
  303. id: 0,
  304. name: '',
  305. description: '',
  306. node_type: 'decision',
  307. workflow: 0,
  308. child_links: []
  309. });
  310. var DistCPModel = ModelModule($);
  311. $.extend(DistCPModel.prototype, {
  312. id: 0,
  313. name: '',
  314. description: '',
  315. node_type: 'distcp',
  316. workflow: 0,
  317. job_properties: '[]',
  318. prepares: '[]',
  319. job_xml: '',
  320. params: '[]',
  321. child_links: []
  322. });
  323. var MapReduceModel = ModelModule($);
  324. $.extend(MapReduceModel.prototype, {
  325. id: 0,
  326. name: '',
  327. description: '',
  328. node_type: 'mapreduce',
  329. workflow: 0,
  330. files: '[]',
  331. archives: '[]',
  332. job_properties: '[]',
  333. jar_path: '',
  334. prepares: '[]',
  335. job_xml: '',
  336. child_links: []
  337. });
  338. var StreamingModel = ModelModule($);
  339. $.extend(StreamingModel.prototype, {
  340. id: 0,
  341. name: '',
  342. description: '',
  343. node_type: 'streaming',
  344. workflow: 0,
  345. files: '[]',
  346. archives: '[]',
  347. job_properties: '[]',
  348. mapper: '',
  349. reducer: '',
  350. child_links: []
  351. });
  352. var JavaModel = ModelModule($);
  353. $.extend(JavaModel.prototype, {
  354. id: 0,
  355. name: '',
  356. description: '',
  357. node_type: 'java',
  358. workflow: 0,
  359. files: '[]',
  360. archives: '[]',
  361. job_properties: '[]',
  362. jar_path: '',
  363. prepares: '[]',
  364. job_xml: '',
  365. main_class: '',
  366. args: '',
  367. java_opts: '',
  368. capture_output: false,
  369. child_links: []
  370. });
  371. var PigModel = ModelModule($);
  372. $.extend(PigModel.prototype, {
  373. id: 0,
  374. name: '',
  375. description: '',
  376. node_type: 'pig',
  377. workflow: 0,
  378. files: '[]',
  379. archives: '[]',
  380. job_properties: '[]',
  381. prepares: '[]',
  382. job_xml: '',
  383. params: '[]',
  384. script_path: '',
  385. child_links: []
  386. });
  387. var HiveModel = ModelModule($);
  388. $.extend(HiveModel.prototype, {
  389. id: 0,
  390. name: '',
  391. description: '',
  392. node_type: 'hive',
  393. workflow: 0,
  394. files: '[]',
  395. archives: '[]',
  396. job_properties: '[]',
  397. prepares: '[]',
  398. job_xml: '',
  399. params: '[]',
  400. script_path: '',
  401. child_links: []
  402. });
  403. var SqoopModel = ModelModule($);
  404. $.extend(SqoopModel.prototype, {
  405. id: 0,
  406. name: '',
  407. description: '',
  408. node_type: 'sqoop',
  409. workflow: 0,
  410. files: '[]',
  411. archives: '[]',
  412. job_properties: '[]',
  413. prepares: '[]',
  414. job_xml: '',
  415. params: '[]',
  416. script_path: '',
  417. child_links: []
  418. });
  419. var ShellModel = ModelModule($);
  420. $.extend(ShellModel.prototype, {
  421. id: 0,
  422. name: '',
  423. description: '',
  424. node_type: 'shell',
  425. workflow: 0,
  426. files: '[]',
  427. archives: '[]',
  428. job_properties: '[]',
  429. prepares: '[]',
  430. job_xml: '',
  431. params: '[]',
  432. command: '',
  433. capture_output: false,
  434. child_links: []
  435. });
  436. var SshModel = ModelModule($);
  437. $.extend(SshModel.prototype, {
  438. id: 0,
  439. name: '',
  440. description: '',
  441. node_type: 'ssh',
  442. workflow: 0,
  443. user: '',
  444. host: '',
  445. params: '[]',
  446. command: '',
  447. capture_output: false,
  448. child_links: []
  449. });
  450. var FsModel = ModelModule($);
  451. $.extend(FsModel.prototype, {
  452. id: 0,
  453. name: '',
  454. description: '',
  455. node_type: 'fs',
  456. workflow: 0,
  457. deletes: '[]',
  458. mkdirs: '[]',
  459. moves: '[]',
  460. chmods: '[]',
  461. touchzs: '[]',
  462. child_links: []
  463. });
  464. var EmailModel = ModelModule($);
  465. $.extend(EmailModel.prototype, {
  466. id: 0,
  467. name: '',
  468. description: '',
  469. node_type: 'email',
  470. workflow: 0,
  471. to: '',
  472. cc: '',
  473. subject: '',
  474. body: '',
  475. child_links: []
  476. });
  477. var SubWorkflowModel = ModelModule($);
  478. $.extend(SubWorkflowModel.prototype, {
  479. id: 0,
  480. name: '',
  481. description: '',
  482. node_type: 'subworkflow',
  483. workflow: 0,
  484. sub_workflow: 0,
  485. propagate_configuration: true,
  486. job_properties: '[]',
  487. child_links: []
  488. });
  489. var GenericModel = ModelModule($);
  490. $.extend(GenericModel.prototype, {
  491. id: 0,
  492. name: '',
  493. description: '',
  494. node_type: 'generic',
  495. workflow: 0,
  496. xml: '',
  497. child_links: []
  498. });
  499. function nodeModelChooser(node_type) {
  500. switch(node_type) {
  501. case 'mapreduce':
  502. return MapReduceModel;
  503. case 'streaming':
  504. return StreamingModel;
  505. case 'java':
  506. return JavaModel;
  507. case 'pig':
  508. return PigModel;
  509. case 'hive':
  510. return HiveModel;
  511. case 'sqoop':
  512. return SqoopModel;
  513. case 'shell':
  514. return ShellModel;
  515. case 'ssh':
  516. return SshModel;
  517. case 'distcp':
  518. return DistCPModel;
  519. case 'fs':
  520. return FsModel;
  521. case 'email':
  522. return EmailModel;
  523. case 'subworkflow':
  524. return SubWorkflowModel;
  525. case 'generic':
  526. return GenericModel;
  527. case 'fork':
  528. return ForkModel;
  529. case 'decision':
  530. return DecisionModel;
  531. default:
  532. return NodeModel;
  533. }
  534. }