sqoop.jobs.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  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. var jobs = (function($) {
  17. var job_registry = {};
  18. var JobModel = koify.Model.extend({
  19. 'id': -1,
  20. 'name': null,
  21. 'from_connector_id': 0,
  22. 'from_link_id': 0,
  23. 'to_connector_id': 0,
  24. 'to_link_id': 0,
  25. 'from_config_values': [],
  26. 'to_config_values': [],
  27. 'driver_config_values': [],
  28. 'creation_date': null,
  29. 'creation_user': null,
  30. 'update_date': null,
  31. 'update_user': null,
  32. 'initialize': function(attrs) {
  33. var self = this;
  34. var _attrs = $.extend(true, {}, attrs);
  35. _attrs = transform_keys(_attrs, {
  36. 'from-connector-id': 'from_connector_id',
  37. 'to-connector-id': 'to_connector_id',
  38. 'from-link-id': 'from_link_id',
  39. 'to-link-id': 'to_link_id',
  40. 'from-config-values': 'from_config_values',
  41. 'to-config-values': 'to_config_values',
  42. 'driver-config-values': 'driver_config_values',
  43. // 'creation-date': 'creation_date',
  44. // 'creation-user': 'creation_user',
  45. // 'update-date': 'update_date',
  46. // 'update-user': 'update_user'
  47. });
  48. _attrs = transform_values(_attrs, {
  49. 'from_config_values': to_configs,
  50. 'to_config_values': to_configs,
  51. 'driver_config_values': to_configs
  52. });
  53. return _attrs;
  54. }
  55. });
  56. var Job = koify.Node.extend({
  57. 'identifier': 'job',
  58. 'persists': true,
  59. 'model_class': JobModel,
  60. 'base_url': '/sqoop/api/jobs/',
  61. 'initialize': function() {
  62. var self = this;
  63. self.parent.initialize.apply(self, arguments);
  64. self.selected = ko.observable();
  65. self.connectors = ko.observableArray();
  66. self.links = ko.observableArray();
  67. self.createdFormatted = ko.computed(function() {
  68. if (self.creation_date()) {
  69. return moment(self.creation_date()).configat('MM/DD/YYYY hh:mm A');
  70. } else {
  71. return 0;
  72. }
  73. });
  74. self.updatedFormatted = ko.computed(function() {
  75. if (self.update_date()) {
  76. return moment(self.update_date()).configat('MM/DD/YYYY hh:mm A');
  77. } else {
  78. return 0;
  79. }
  80. });
  81. self.submission = ko.computed({
  82. owner: self,
  83. read: function () {
  84. return submissions.setDefaultSubmission(this.id());
  85. },
  86. write: function (submission) {
  87. submissions.putSubmission(submission);
  88. self.id.valueHasMutated();
  89. if (self.runningInterval == 0 && self.isRunning()) {
  90. self.runningInterval = setInterval(function() {
  91. if (!self.isRunning()) {
  92. clearInterval(self.runningInterval);
  93. self.runningInterval = 0;
  94. }
  95. self.getStatus();
  96. }, 2000);
  97. }
  98. }
  99. });
  100. self.persisted = ko.computed(function() {
  101. return self.id() > -1;
  102. });
  103. self.isRunning = ko.computed(function() {
  104. return self.submission() && $.inArray(self.submission().status(), ['BOOTING', 'RUNNING']) > -1;
  105. });
  106. self.hasSucceeded = ko.computed(function() {
  107. return self.submission() && $.inArray(self.submission().status(), ['SUCCEEDED']) > -1;
  108. });
  109. self.hasFailed = ko.computed(function() {
  110. return self.submission() && $.inArray(self.submission().status(), ['FAILURE_ON_SUBMIT', 'FAILED']) > -1;
  111. });
  112. self.outputDirectoryFilebrowserURL = ko.computed(function() {
  113. var output_directory = null;
  114. $.each(self.to_config_values(), function(index, config) {
  115. if (config.name() == 'output') {
  116. $.each(config.inputs(), function(index, input) {
  117. if (input.name() == 'output.outputDirectory') {
  118. output_directory = input.value();
  119. }
  120. });
  121. }
  122. });
  123. return (output_directory) ? '/filebrowser/view' + output_directory : null;
  124. });
  125. self.inputDirectoryFilebrowserURL = ko.computed(function() {
  126. var input_directory = null;
  127. $.each(self.from_config_values(), function(index, config) {
  128. if (config.name() == 'input') {
  129. $.each(config.inputs(), function(index, input) {
  130. if (input.name() == 'input.inputDirectory') {
  131. input_directory = input.value();
  132. }
  133. });
  134. }
  135. });
  136. return (input_directory) ? '/filebrowser/view' + input_directory : null;
  137. });
  138. self.storageType = ko.computed(function() {
  139. var storage_type = null;
  140. $.each(self.from_config_values(), function(index, config) {
  141. if (config.name() == 'input') {
  142. storage_type = 'HDFS'; // Hardcoded for now
  143. } else if (config.name() == 'output') {
  144. $.each(config.inputs(), function(index, input) {
  145. if (input.name() == 'output.storageType') {
  146. storage_type = input.value();
  147. }
  148. });
  149. }
  150. });
  151. return storage_type;
  152. });
  153. self.table = ko.computed(function() {
  154. var table = null;
  155. $.each(self.from_config_values(), function(index, config) {
  156. if (config.name() == 'table') {
  157. $.each(config.inputs(), function(index, input) {
  158. if (input.name() == 'table.tableName') {
  159. table = input.value();
  160. }
  161. });
  162. }
  163. });
  164. return table;
  165. });
  166. self.fromLink = ko.computed(function() {
  167. var link = null;
  168. $.each(self.links(), function(index, $link) {
  169. if (self.from_link_id() == $link.id()) {
  170. link = $link;
  171. }
  172. });
  173. return link;
  174. });
  175. self.toLink = ko.computed(function() {
  176. var link = null;
  177. $.each(self.links(), function(index, $link) {
  178. if (self.to_link_id() == $link.id()) {
  179. link = $link;
  180. }
  181. });
  182. return link;
  183. });
  184. self.fromLabel = ko.computed(function() {
  185. if (self.fromLink()) {
  186. if (self.fromLink().isHdfs()) {
  187. return "HDFS";
  188. }
  189. if (self.fromLink().isRdbms()) {
  190. return self.fromLink().type();
  191. }
  192. }
  193. return null;
  194. });
  195. self.toLabel = ko.computed(function() {
  196. if (self.toLink()) {
  197. if (self.toLink().isHdfs()) {
  198. return "HDFS";
  199. }
  200. if (self.toLink().isRdbms()) {
  201. return self.toLink().type();
  202. }
  203. }
  204. return null;
  205. });
  206. self.runningInterval = 0;
  207. },
  208. map: function() {
  209. var self = this;
  210. var mapping_options = $.extend(true, {
  211. 'ignore': ['parent', 'initialize']
  212. }, configs.MapProperties);
  213. if ('__ko_mapping__' in self) {
  214. ko.mapping.fromJS(self.model, mapping_options, self);
  215. } else {
  216. var mapped = ko.mapping.fromJS(self.model, mapping_options);
  217. $.extend(self, mapped);
  218. }
  219. },
  220. 'start': function(options) {
  221. var self = this;
  222. $(document).trigger('start.job', [options, self]);
  223. var options = $.extend({
  224. type: 'POST',
  225. success: function(data) {
  226. switch(data.status) {
  227. case 0:
  228. self.submission(new submissions.Submission({modelDict: data.submission}));
  229. $(document).trigger('started.job', [self, options, data.submission]);
  230. break;
  231. default:
  232. case 1:
  233. var error = data.errors[0];
  234. $(document).trigger('start_fail.job', [self, options, error]);
  235. break;
  236. }
  237. }
  238. }, options);
  239. self.request('/sqoop/api/jobs/' + self.id() + '/start', options);
  240. },
  241. 'stop': function(options) {
  242. var self = this;
  243. $(document).trigger('stop.job', [options, self]);
  244. var options = $.extend({
  245. type: 'POST',
  246. success: function(data) {
  247. switch(data.status) {
  248. case 0:
  249. self.submission(new submissions.Submission({modelDict: data.submission}));
  250. $(document).trigger('stopped.job', [self, options, data.submission]);
  251. break;
  252. default:
  253. case 1:
  254. $(document).trigger('stop_fail.job', [self, options, data]);
  255. break;
  256. }
  257. }
  258. }, options);
  259. self.request('/sqoop/api/jobs/' + self.id() + '/stop', options);
  260. },
  261. 'getStatus': function(options) {
  262. var self = this;
  263. $(document).trigger('get_status.job', [self, options]);
  264. var options = $.extend({
  265. type: 'GET',
  266. success: function(data) {
  267. switch(data.status) {
  268. case 0:
  269. self.submission(new submissions.Submission({modelDict: data.submission}));
  270. $(document).trigger('got_status.job', [self, options, data.submission]);
  271. break;
  272. default:
  273. case 1:
  274. $(document).trigger('get_status_fail.job', [self, options, data]);
  275. break;
  276. }
  277. }
  278. }, options);
  279. self.request('/sqoop/api/jobs/' + self.id() + '/status', options);
  280. },
  281. 'getData': function() {
  282. var self = this;
  283. var model = ko.sqoop.fixModel(self);
  284. var data = {};
  285. model = transform_keys(model, {
  286. 'from_connector_id': 'from-connector-id',
  287. 'to_connector_id': 'to-connector-id',
  288. 'from_link_id': 'from-link-id',
  289. 'to_link_id': 'to-link-id',
  290. 'from_config_values': 'from-config-values',
  291. 'to_config_values': 'to-config-values',
  292. 'driver_config_values': 'driver-config-values'
  293. });
  294. data[self.identifier] = ko.utils.stringifyJson(model);
  295. return data;
  296. }
  297. });
  298. function fetch_jobs(options) {
  299. $(document).trigger('load.jobs', [options]);
  300. var request = $.extend({
  301. url: '/sqoop/api/jobs/',
  302. dataType: 'json',
  303. type: 'GET',
  304. success: fetcher_success('jobs', Job, options),
  305. error: fetcher_error('jobs', Job, options)
  306. }, options || {});
  307. $.ajax(request);
  308. }
  309. function put_job(job) {
  310. job_registry[job.id()] = job;
  311. }
  312. function get_job(id) {
  313. return job_registry[id];
  314. }
  315. function sync_jobs(jobs) {
  316. job_registry = {};
  317. $.each(jobs, function(index, job) {
  318. put_job(job);
  319. });
  320. }
  321. $(document).on('loaded.jobs', function(e, nodes, options) {
  322. sync_jobs(nodes);
  323. });
  324. return {
  325. 'JobModel': JobModel,
  326. 'Job': Job,
  327. 'fetchJobs': fetch_jobs,
  328. 'putJob': put_job,
  329. 'getJob': get_job
  330. }
  331. })($);