controls_view.js 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. var App = require('app');
  19. /**
  20. * Abstract view for config fields.
  21. * Add popover support to control
  22. */
  23. App.ServiceConfigPopoverSupport = Ember.Mixin.create({
  24. /**
  25. * Config object. It will instance of App.ServiceConfigProperty
  26. */
  27. serviceConfig: null,
  28. attributeBindings:['readOnly'],
  29. isPopoverEnabled: true,
  30. didInsertElement: function () {
  31. $('body').tooltip({
  32. selector: '[data-toggle=tooltip]',
  33. placement: 'top'
  34. });
  35. // if description for this serviceConfig not exist, then no need to show popover
  36. if (this.get('isPopoverEnabled') !== 'false' && this.get('serviceConfig.description')) {
  37. App.popover(this.$(), {
  38. title: Em.I18n.t('installer.controls.serviceConfigPopover.title').format(
  39. this.get('serviceConfig.displayName'),
  40. (this.get('serviceConfig.displayName') == this.get('serviceConfig.name')) ? '' : this.get('serviceConfig.name')
  41. ),
  42. content: this.get('serviceConfig.description'),
  43. placement: 'right',
  44. trigger: 'hover'
  45. });
  46. }
  47. },
  48. willDestroyElement: function() {
  49. this.$().popover('destroy');
  50. },
  51. readOnly: function () {
  52. return !this.get('serviceConfig.isEditable');
  53. }.property('serviceConfig.isEditable')
  54. });
  55. /**
  56. * mixin set class that serve as unique element identificator,
  57. * id not used in order to avoid collision with ember ids
  58. */
  59. App.ServiceConfigCalculateId = Ember.Mixin.create({
  60. idClass: Ember.computed(function () {
  61. var label = Em.get(this, 'serviceConfig.name') ? Em.get(this, 'serviceConfig.name').toLowerCase().replace(/\./g, '-') : '',
  62. fileName = Em.get(this, 'serviceConfig.filename') ? Em.get(this, 'serviceConfig.filename').toLowerCase().replace(/\./g, '-') : '',
  63. group = Em.get(this, 'serviceConfig.group.name') || 'default';
  64. isOrigin = Em.get(this, 'serviceConfig.compareConfigs.length') > 0 ? '-origin' : '';
  65. return 'service-config-' + label + '-' + fileName + '-' + group + isOrigin;
  66. }),
  67. classNameBindings: 'idClass'
  68. });
  69. /**
  70. * Default input control
  71. * @type {*}
  72. */
  73. App.ServiceConfigTextField = Ember.TextField.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, {
  74. valueBinding: 'serviceConfig.value',
  75. classNameBindings: 'textFieldClassName',
  76. placeholderBinding: 'serviceConfig.defaultValue',
  77. keyPress: function (event) {
  78. if (event.keyCode == 13) {
  79. return false;
  80. }
  81. },
  82. //Set editDone true for last edited config text field parameter
  83. focusOut: function (event) {
  84. this.get('serviceConfig').set("editDone", true);
  85. },
  86. //Set editDone false for all current category config text field parameter
  87. focusIn: function (event) {
  88. if (!this.get('serviceConfig.isOverridden') && !this.get('serviceConfig.isComparison')) {
  89. this.get("parentView.categoryConfigsAll").setEach("editDone", false);
  90. }
  91. },
  92. textFieldClassName: function () {
  93. if (this.get('serviceConfig.unit')) {
  94. return ['input-small'];
  95. } else if (this.get('serviceConfig.displayType') === 'principal') {
  96. return ['span12'];
  97. } else {
  98. return ['span9'];
  99. }
  100. }.property('serviceConfig.displayType', 'serviceConfig.unit')
  101. });
  102. /**
  103. * Customized input control with Units type specified
  104. * @type {Em.View}
  105. */
  106. App.ServiceConfigTextFieldWithUnit = Ember.View.extend(App.ServiceConfigPopoverSupport, {
  107. valueBinding: 'serviceConfig.value',
  108. classNames: ['input-append', 'with-unit'],
  109. placeholderBinding: 'serviceConfig.defaultValue',
  110. templateName: require('templates/wizard/controls_service_config_textfield_with_unit')
  111. });
  112. /**
  113. * Password control
  114. * @type {*}
  115. */
  116. App.ServiceConfigPasswordField = Ember.TextField.extend({
  117. serviceConfig: null,
  118. type: 'password',
  119. attributeBindings:['readOnly'],
  120. valueBinding: 'serviceConfig.value',
  121. classNames: [ 'span4' ],
  122. placeholder: Em.I18n.t('form.item.placeholders.typePassword'),
  123. template: Ember.Handlebars.compile('{{view view.retypePasswordView}}'),
  124. keyPress: function (event) {
  125. if (event.keyCode == 13) {
  126. return false;
  127. }
  128. },
  129. retypePasswordView: Ember.TextField.extend({
  130. placeholder: Em.I18n.t('form.passwordRetype'),
  131. attributeBindings:['readOnly'],
  132. type: 'password',
  133. classNames: [ 'span4', 'retyped-password' ],
  134. keyPress: function (event) {
  135. if (event.keyCode == 13) {
  136. return false;
  137. }
  138. },
  139. valueBinding: 'parentView.serviceConfig.retypedPassword',
  140. readOnly: function () {
  141. return !this.get('parentView.serviceConfig.isEditable');
  142. }.property('parentView.serviceConfig.isEditable')
  143. }),
  144. readOnly: function () {
  145. return !this.get('serviceConfig.isEditable');
  146. }.property('serviceConfig.isEditable')
  147. });
  148. /**
  149. * Textarea control
  150. * @type {*}
  151. */
  152. App.ServiceConfigTextArea = Ember.TextArea.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, {
  153. valueBinding: 'serviceConfig.value',
  154. rows: 4,
  155. classNames: ['span9', 'directories']
  156. });
  157. /**
  158. * Textarea control for content type
  159. * @type {*}
  160. */
  161. App.ServiceConfigTextAreaContent = Ember.TextArea.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, {
  162. valueBinding: 'serviceConfig.value',
  163. rows: 20,
  164. classNames: ['span10']
  165. });
  166. /**
  167. * Textarea control with bigger height
  168. * @type {*}
  169. */
  170. App.ServiceConfigBigTextArea = App.ServiceConfigTextArea.extend(App.ServiceConfigCalculateId, {
  171. rows: 10
  172. });
  173. /**
  174. * Checkbox control
  175. * @type {*}
  176. */
  177. App.ServiceConfigCheckbox = Ember.Checkbox.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, {
  178. checkedBinding: 'serviceConfig.value',
  179. disabled: function () {
  180. return !this.get('serviceConfig.isEditable');
  181. }.property('serviceConfig.isEditable')
  182. });
  183. App.ServiceConfigRadioButtons = Ember.View.extend(App.ServiceConfigCalculateId, {
  184. templateName: require('templates/wizard/controls_service_config_radio_buttons'),
  185. didInsertElement: function () {
  186. // on page render, automatically populate JDBC URLs only for default database settings
  187. // so as to not lose the user's customizations on these fields
  188. if (['addServiceController', 'installerController'].contains(this.get('controller.wizardController.name'))) {
  189. if (/^New\s\w+\sDatabase$/.test(this.get('serviceConfig.value'))) {
  190. this.onOptionsChange();
  191. } else {
  192. this.handleDBConnectionProperty();
  193. }
  194. }
  195. },
  196. configs: function () {
  197. if (this.get('controller.name') == 'mainServiceInfoConfigsController') return this.get('categoryConfigsAll');
  198. return this.get('categoryConfigsAll').filterProperty('isObserved', true);
  199. }.property('categoryConfigsAll'),
  200. serviceConfig: null,
  201. categoryConfigsAll: null,
  202. onOptionsChange: function () {
  203. // The following if condition will be satisfied only for installer wizard flow
  204. if (this.get('configs').length) {
  205. var connectionUrl = this.get('connectionUrl');
  206. var dbClass = this.get('dbClass');
  207. if (connectionUrl) {
  208. if (this.get('serviceConfig.serviceName') === 'HIVE') {
  209. var hiveDbType = this.get('parentView.serviceConfigs').findProperty('name', 'hive_database_type');
  210. switch (this.get('serviceConfig.value')) {
  211. case 'New MySQL Database':
  212. case 'Existing MySQL Database':
  213. connectionUrl.set('value', "jdbc:mysql://" + this.get('hostName') + "/" + this.get('databaseName') + "?createDatabaseIfNotExist=true");
  214. dbClass.set('value', "com.mysql.jdbc.Driver");
  215. Em.set(hiveDbType, 'value', 'mysql');
  216. break;
  217. case Em.I18n.t('services.service.config.hive.oozie.postgresql'):
  218. connectionUrl.set('value', "jdbc:postgresql://" + this.get('hostName') + ":5432/" + this.get('databaseName'));
  219. dbClass.set('value', "org.postgresql.Driver");
  220. Em.set(hiveDbType, 'value', 'postgres');
  221. break;
  222. case 'Existing Oracle Database':
  223. connectionUrl.set('value', "jdbc:oracle:thin:@//" + this.get('hostName') + ":1521/" + this.get('databaseName'));
  224. dbClass.set('value', "oracle.jdbc.driver.OracleDriver");
  225. Em.set(hiveDbType, 'value', 'oracle');
  226. break;
  227. case 'Existing MSSQL Server database with integrated authentication':
  228. connectionUrl.set('value', "jdbc:sqlserver://" + this.get('hostName') + ";databaseName=" + this.get('databaseName') + ";integratedSecurity=true");
  229. dbClass.set('value', "com.microsoft.sqlserver.jdbc.SQLServerDriver");
  230. Em.set(hiveDbType, 'value', 'mssql');
  231. break;
  232. case 'Existing MSSQL Server database with sql auth':
  233. connectionUrl.set('value', "jdbc:sqlserver://" + this.get('hostName') + ";databaseName=" + this.get('databaseName'));
  234. dbClass.set('value', "com.microsoft.sqlserver.jdbc.SQLServerDriver");
  235. Em.set(hiveDbType, 'value', 'mssql');
  236. break;
  237. }
  238. var isNotExistingMySQLServer = this.get('serviceConfig.value') !== 'Existing MSSQL Server database with integrated authentication';
  239. this.get('categoryConfigsAll').findProperty('name', 'javax.jdo.option.ConnectionUserName').setProperties({
  240. isVisible: isNotExistingMySQLServer,
  241. isRequired: isNotExistingMySQLServer
  242. });
  243. this.get('categoryConfigsAll').findProperty('name', 'javax.jdo.option.ConnectionPassword').setProperties({
  244. isVisible: isNotExistingMySQLServer,
  245. isRequired: isNotExistingMySQLServer
  246. });
  247. } else if (this.get('serviceConfig.serviceName') === 'OOZIE') {
  248. switch (this.get('serviceConfig.value')) {
  249. case 'New Derby Database':
  250. connectionUrl.set('value', "jdbc:derby:${oozie.data.dir}/${oozie.db.schema.name}-db;create=true");
  251. dbClass.set('value', "org.apache.derby.jdbc.EmbeddedDriver");
  252. break;
  253. case 'Existing MySQL Database':
  254. connectionUrl.set('value', "jdbc:mysql://" + this.get('hostName') + "/" + this.get('databaseName'));
  255. dbClass.set('value', "com.mysql.jdbc.Driver");
  256. break;
  257. case Em.I18n.t('services.service.config.hive.oozie.postgresql'):
  258. connectionUrl.set('value', "jdbc:postgresql://" + this.get('hostName') + ":5432/" + this.get('databaseName'));
  259. dbClass.set('value', "org.postgresql.Driver");
  260. break;
  261. case 'Existing Oracle Database':
  262. connectionUrl.set('value', "jdbc:oracle:thin:@//" + this.get('hostName') + ":1521/" + this.get('databaseName'));
  263. dbClass.set('value', "oracle.jdbc.driver.OracleDriver");
  264. break;
  265. case 'Existing MSSQL Server database with integrated authentication':
  266. connectionUrl.set('value', "jdbc:sqlserver://" + this.get('hostName') + ";databaseName=" + this.get('databaseName') + ";integratedSecurity=true");
  267. dbClass.set('value', "com.microsoft.sqlserver.jdbc.SQLServerDriver");
  268. break;
  269. case 'Existing MSSQL Server database with sql auth':
  270. connectionUrl.set('value', "jdbc:sqlserver://" + this.get('hostName') + ";databaseName=" + this.get('databaseName'));
  271. dbClass.set('value', "com.microsoft.sqlserver.jdbc.SQLServerDriver");
  272. break;
  273. }
  274. isNotExistingMySQLServer = this.get('serviceConfig.value') !== 'Existing MSSQL Server database with integrated authentication';
  275. this.get('categoryConfigsAll').findProperty('name', 'oozie.service.JPAService.jdbc.username').setProperties({
  276. isVisible: isNotExistingMySQLServer,
  277. isRequired: isNotExistingMySQLServer
  278. });
  279. this.get('categoryConfigsAll').findProperty('name', 'oozie.service.JPAService.jdbc.password').setProperties({
  280. isVisible: isNotExistingMySQLServer,
  281. isRequired: isNotExistingMySQLServer
  282. });
  283. }
  284. connectionUrl.set('defaultValue', connectionUrl.get('value'));
  285. }
  286. }
  287. }.observes('databaseName', 'hostName'),
  288. nameBinding: 'serviceConfig.radioName',
  289. databaseNameProperty: function () {
  290. switch (this.get('serviceConfig.serviceName')) {
  291. case 'HIVE':
  292. return this.get('categoryConfigsAll').findProperty('name', 'ambari.hive.db.schema.name');
  293. case 'OOZIE':
  294. return this.get('categoryConfigsAll').findProperty('name', 'oozie.db.schema.name');
  295. default:
  296. return null;
  297. }
  298. }.property('serviceConfig.serviceName'),
  299. databaseName: function () {
  300. return this.get('databaseNameProperty.value');
  301. }.property('databaseNameProperty.value'),
  302. hostNameProperty: function () {
  303. var value = this.get('serviceConfig.value');
  304. var returnValue;
  305. var hostname;
  306. if (this.get('serviceConfig.serviceName') === 'HIVE') {
  307. switch (value) {
  308. case 'New MySQL Database':
  309. hostname = this.get('categoryConfigsAll').findProperty('name', 'hive_ambari_host');
  310. break;
  311. case 'Existing MySQL Database':
  312. hostname = this.get('categoryConfigsAll').findProperty('name', 'hive_existing_mysql_host');
  313. break;
  314. case Em.I18n.t('services.service.config.hive.oozie.postgresql'):
  315. hostname = this.get('categoryConfigsAll').findProperty('name', 'hive_existing_postgresql_host');
  316. break;
  317. case 'Existing Oracle Database':
  318. hostname = this.get('categoryConfigsAll').findProperty('name', 'hive_existing_oracle_host');
  319. break;
  320. case 'Existing MSSQL Server database with integrated authentication':
  321. hostname = this.get('categoryConfigsAll').findProperty('name', 'hive_existing_mssql_server_host');
  322. break;
  323. case 'Existing MSSQL Server database with sql auth':
  324. hostname = this.get('categoryConfigsAll').findProperty('name', 'hive_existing_mssql_server_2_host');
  325. break;
  326. }
  327. if (hostname) {
  328. returnValue = hostname;
  329. } else {
  330. returnValue = this.get('categoryConfigsAll').findProperty('name', 'hive_hostname');
  331. }
  332. } else if (this.get('serviceConfig.serviceName') === 'OOZIE') {
  333. switch (value) {
  334. case 'New Derby Database':
  335. hostname = this.get('categoryConfigsAll').findProperty('name', 'oozie_ambari_host');
  336. break;
  337. case 'Existing MySQL Database':
  338. hostname = this.get('categoryConfigsAll').findProperty('name', 'oozie_existing_mysql_host');
  339. break;
  340. case Em.I18n.t('services.service.config.hive.oozie.postgresql'):
  341. hostname = this.get('categoryConfigsAll').findProperty('name', 'oozie_existing_postgresql_host');
  342. break;
  343. case 'Existing Oracle Database':
  344. hostname = this.get('categoryConfigsAll').findProperty('name', 'oozie_existing_oracle_host');
  345. break;
  346. case 'Existing MSSQL Server database with integrated authentication':
  347. hostname = this.get('categoryConfigsAll').findProperty('name', 'oozie_existing_mssql_server_host');
  348. break;
  349. case 'Existing MSSQL Server database with sql auth':
  350. hostname = this.get('categoryConfigsAll').findProperty('name', 'oozie_existing_mssql_server_2_host');
  351. break;
  352. }
  353. if (hostname) {
  354. returnValue = hostname;
  355. } else {
  356. returnValue = this.get('categoryConfigsAll').findProperty('name', 'oozie_hostname');
  357. }
  358. }
  359. return returnValue;
  360. }.property('serviceConfig.serviceName', 'serviceConfig.value'),
  361. hostName: function () {
  362. return this.get('hostNameProperty.value');
  363. }.property('hostNameProperty.value'),
  364. connectionUrl: function () {
  365. if (this.get('serviceConfig.serviceName') === 'HIVE') {
  366. return this.get('categoryConfigsAll').findProperty('name', 'javax.jdo.option.ConnectionURL');
  367. } else {
  368. return this.get('categoryConfigsAll').findProperty('name', 'oozie.service.JPAService.jdbc.url');
  369. }
  370. }.property('serviceConfig.serviceName'),
  371. dbClass: function () {
  372. if (this.get('serviceConfig.serviceName') === 'HIVE') {
  373. return this.get('categoryConfigsAll').findProperty('name', 'javax.jdo.option.ConnectionDriverName');
  374. } else {
  375. return this.get('categoryConfigsAll').findProperty('name', 'oozie.service.JPAService.jdbc.driver');
  376. }
  377. }.property('serviceConfig.serviceName'),
  378. /**
  379. * `Observer` that add <code>additionalView</code> to <code>App.ServiceConfigProperty</code>
  380. * that responsible for (if existing db selected)
  381. * 1. checking database connection
  382. * 2. showing jdbc driver setup warning msg.
  383. *
  384. * @method handleDBConnectionProperty
  385. **/
  386. handleDBConnectionProperty: function() {
  387. var handledProperties = ['oozie_database', 'hive_database'];
  388. var currentValue = this.get('serviceConfig.value');
  389. var databases = /MySQL|PostgreSQL|Oracle|Derby|MSSQL/gi;
  390. var currentDB = currentValue.match(databases)[0];
  391. var databasesTypes = /MySQL|PostgreS|Oracle|Derby|MSSQL/gi;
  392. var currentDBType = currentValue.match(databasesTypes)[0];
  393. var existingDatabase = /existing/gi.test(currentValue);
  394. // db connection check button show up if existed db selected
  395. var propertyAppendTo1 = this.get('categoryConfigsAll').findProperty('displayName', 'Database URL');
  396. if (currentDB && existingDatabase) {
  397. if (handledProperties.contains(this.get('serviceConfig.name'))) {
  398. if (propertyAppendTo1) propertyAppendTo1.set('additionalView', App.CheckDBConnectionView.extend({databaseName: currentDB}));
  399. }
  400. } else {
  401. propertyAppendTo1.set('additionalView', null);
  402. }
  403. // warning msg under database type radio buttons, to warn the user to setup jdbc driver if existed db selected
  404. var propertyHive = this.get('categoryConfigsAll').findProperty('displayName', 'Hive Database');
  405. var propertyOozie = this.get('categoryConfigsAll').findProperty('displayName', 'Oozie Database');
  406. var propertyAppendTo2 = propertyHive ? propertyHive : propertyOozie;
  407. if (currentDB && existingDatabase) {
  408. if (handledProperties.contains(this.get('serviceConfig.name'))) {
  409. if (propertyAppendTo2) {
  410. propertyAppendTo2.set('additionalView', Ember.View.extend({
  411. template: Ember.Handlebars.compile('<div class="alert">{{{view.message}}}</div>'),
  412. message: Em.I18n.t('services.service.config.database.msg.jdbcSetup').format(currentDBType.toLowerCase(), currentDBType.toLowerCase())
  413. }));
  414. }
  415. }
  416. } else {
  417. propertyAppendTo2.set('additionalView', null);
  418. }
  419. }.observes('serviceConfig.value'),
  420. optionsBinding: 'serviceConfig.options'
  421. });
  422. App.ServiceConfigRadioButton = Ember.Checkbox.extend({
  423. tagName: 'input',
  424. attributeBindings: ['type', 'name', 'value', 'checked', 'disabled'],
  425. checked: false,
  426. type: 'radio',
  427. name: null,
  428. value: null,
  429. didInsertElement: function () {
  430. console.debug('App.ServiceConfigRadioButton.didInsertElement');
  431. if (this.get('parentView.serviceConfig.value') === this.get('value')) {
  432. console.debug(this.get('name') + ":" + this.get('value') + ' is checked');
  433. this.set('checked', true);
  434. }
  435. },
  436. click: function () {
  437. this.set('checked', true);
  438. console.debug('App.ServiceConfigRadioButton.click');
  439. this.onChecked();
  440. },
  441. onChecked: function () {
  442. // Wrapping the call with Ember.run.next prevents a problem where setting isVisible on component
  443. // causes JS error due to re-rendering. For example, this occurs when switching the Config Group
  444. // in Service Config page
  445. Em.run.next(this, function() {
  446. console.debug('App.ServiceConfigRadioButton.onChecked');
  447. this.set('parentView.serviceConfig.value', this.get('value'));
  448. var components = this.get('parentView.serviceConfig.options');
  449. if (components) {
  450. components.forEach(function (_component) {
  451. if (_component.foreignKeys) {
  452. _component.foreignKeys.forEach(function (_componentName) {
  453. if (this.get('parentView.categoryConfigsAll').someProperty('name', _componentName)) {
  454. var component = this.get('parentView.categoryConfigsAll').findProperty('name', _componentName);
  455. component.set('isVisible', _component.displayName === this.get('value'));
  456. }
  457. }, this);
  458. }
  459. }, this);
  460. }
  461. });
  462. }.observes('checked'),
  463. disabled: function () {
  464. return !this.get('parentView.serviceConfig.isEditable') ||
  465. !['addServiceController', 'installerController'].contains(this.get('controller.wizardController.name')) && /^New\s\w+\sDatabase$/.test(this.get('value'));
  466. }.property('parentView.serviceConfig.isEditable')
  467. });
  468. App.ServiceConfigComboBox = Ember.Select.extend(App.ServiceConfigPopoverSupport, App.ServiceConfigCalculateId, {
  469. contentBinding: 'serviceConfig.options',
  470. selectionBinding: 'serviceConfig.value',
  471. placeholderBinding: 'serviceConfig.defaultValue',
  472. classNames: [ 'span3' ]
  473. });
  474. /**
  475. * Base component for host config with popover support
  476. */
  477. App.ServiceConfigHostPopoverSupport = Ember.Mixin.create({
  478. /**
  479. * Config object. It will instance of App.ServiceConfigProperty
  480. */
  481. serviceConfig: null,
  482. didInsertElement: function () {
  483. App.popover(this.$(), {
  484. title: this.get('serviceConfig.displayName'),
  485. content: this.get('serviceConfig.description'),
  486. placement: 'right',
  487. trigger: 'hover'
  488. });
  489. }
  490. });
  491. /**
  492. * Master host component.
  493. * Show hostname without ability to edit it
  494. * @type {*}
  495. */
  496. App.ServiceConfigMasterHostView = Ember.View.extend(App.ServiceConfigHostPopoverSupport, App.ServiceConfigCalculateId, {
  497. classNames: ['master-host', 'span6'],
  498. valueBinding: 'serviceConfig.value',
  499. template: Ember.Handlebars.compile('{{value}}')
  500. });
  501. /**
  502. * text field property view that enables possibility
  503. * for check connectio
  504. * @type {*}
  505. */
  506. App.checkConnectionView = App.ServiceConfigTextField.extend({
  507. didInsertElement: function() {
  508. this._super();
  509. var kdc = this.get('categoryConfigsAll').findProperty('name', 'kdc_type');
  510. var propertyAppendTo = this.get('categoryConfigsAll').findProperty('name', 'admin_password');
  511. if (propertyAppendTo) propertyAppendTo.set('additionalView', App.CheckDBConnectionView.extend({databaseName: kdc && kdc.get('value')}));
  512. }
  513. });
  514. /**
  515. * Show value as plain label in italics
  516. * @type {*}
  517. */
  518. App.ServiceConfigLabelView = Ember.View.extend(App.ServiceConfigHostPopoverSupport, App.ServiceConfigCalculateId, {
  519. classNames: ['master-host', 'span6'],
  520. valueBinding: 'serviceConfig.value',
  521. template: Ember.Handlebars.compile('<i>{{view.value}}</i>')
  522. });
  523. /**
  524. * Base component to display Multiple hosts
  525. * @type {*}
  526. */
  527. App.ServiceConfigMultipleHostsDisplay = Ember.Mixin.create(App.ServiceConfigHostPopoverSupport, App.ServiceConfigCalculateId, {
  528. hasNoHosts: function () {
  529. console.log('view', this.get('viewName')); //to know which View cause errors
  530. console.log('controller', this.get('controller').name); //should be slaveComponentGroupsController
  531. if (!this.get('value')) {
  532. return true;
  533. }
  534. return this.get('value').length === 0;
  535. }.property('value'),
  536. hasOneHost: function () {
  537. return this.get('value').length === 1;
  538. }.property('value'),
  539. hasMultipleHosts: function () {
  540. return this.get('value').length > 1;
  541. }.property('value'),
  542. otherLength: function () {
  543. var len = this.get('value').length;
  544. if (len > 2) {
  545. return Em.I18n.t('installer.controls.serviceConfigMultipleHosts.others').format(len - 1);
  546. } else {
  547. return Em.I18n.t('installer.controls.serviceConfigMultipleHosts.other');
  548. }
  549. }.property('value')
  550. });
  551. /**
  552. * Multiple master host component.
  553. * Show hostnames without ability to edit it
  554. * @type {*}
  555. */
  556. App.ServiceConfigMasterHostsView = Ember.View.extend(App.ServiceConfigMultipleHostsDisplay, App.ServiceConfigCalculateId, {
  557. viewName: "serviceConfigMasterHostsView",
  558. valueBinding: 'serviceConfig.value',
  559. classNames: ['master-hosts', 'span6'],
  560. templateName: require('templates/wizard/master_hosts'),
  561. /**
  562. * Onclick handler for link
  563. */
  564. showHosts: function () {
  565. var serviceConfig = this.get('serviceConfig');
  566. App.ModalPopup.show({
  567. header: Em.I18n.t('installer.controls.serviceConfigMasterHosts.header').format(serviceConfig.category),
  568. bodyClass: Ember.View.extend({
  569. serviceConfig: serviceConfig,
  570. templateName: require('templates/wizard/master_hosts_popup')
  571. }),
  572. secondary: null
  573. });
  574. }
  575. });
  576. /**
  577. * Show tabs list for slave hosts
  578. * @type {*}
  579. */
  580. App.SlaveComponentGroupsMenu = Em.CollectionView.extend(App.ServiceConfigCalculateId, {
  581. content: function () {
  582. return this.get('controller.componentGroups');
  583. }.property('controller.componentGroups'),
  584. tagName: 'ul',
  585. classNames: ["nav", "nav-tabs"],
  586. itemViewClass: Em.View.extend({
  587. classNameBindings: ["active"],
  588. active: function () {
  589. return this.get('content.active');
  590. }.property('content.active'),
  591. errorCount: function () {
  592. return this.get('content.properties').filterProperty('isValid', false).filterProperty('isVisible', true).get('length');
  593. }.property('content.properties.@each.isValid', 'content.properties.@each.isVisible'),
  594. templateName: require('templates/wizard/controls_slave_component_groups_menu')
  595. })
  596. });
  597. /**
  598. * <code>Add group</code> button
  599. * @type {*}
  600. */
  601. App.AddSlaveComponentGroupButton = Ember.View.extend(App.ServiceConfigCalculateId, {
  602. tagName: 'span',
  603. slaveComponentName: null,
  604. didInsertElement: function () {
  605. App.popover(this.$(), {
  606. title: Em.I18n.t('installer.controls.addSlaveComponentGroupButton.title').format(this.get('slaveComponentName')),
  607. content: Em.I18n.t('installer.controls.addSlaveComponentGroupButton.content').format(this.get('slaveComponentName'), this.get('slaveComponentName'), this.get('slaveComponentName')),
  608. placement: 'right',
  609. trigger: 'hover'
  610. });
  611. }
  612. });
  613. /**
  614. * Multiple Slave Hosts component
  615. * @type {*}
  616. */
  617. App.ServiceConfigSlaveHostsView = Ember.View.extend(App.ServiceConfigMultipleHostsDisplay, App.ServiceConfigCalculateId, {
  618. viewName: 'serviceConfigSlaveHostsView',
  619. classNames: ['slave-hosts', 'span6'],
  620. valueBinding: 'serviceConfig.value',
  621. templateName: require('templates/wizard/slave_hosts'),
  622. /**
  623. * Onclick handler for link
  624. */
  625. showHosts: function () {
  626. var serviceConfig = this.get('serviceConfig');
  627. App.ModalPopup.show({
  628. header: Em.I18n.t('installer.controls.serviceConfigMasterHosts.header').format(serviceConfig.category),
  629. bodyClass: Ember.View.extend({
  630. serviceConfig: serviceConfig,
  631. templateName: require('templates/wizard/master_hosts_popup')
  632. }),
  633. secondary: null
  634. });
  635. }
  636. });
  637. /**
  638. * properties for present active slave group
  639. * @type {*}
  640. */
  641. App.SlaveGroupPropertiesView = Ember.View.extend(App.ServiceConfigCalculateId, {
  642. viewName: 'serviceConfigSlaveHostsView',
  643. group: function () {
  644. return this.get('controller.activeGroup');
  645. }.property('controller.activeGroup'),
  646. groupConfigs: function () {
  647. console.log("************************************************************************");
  648. console.log("The value of group is: " + this.get('group'));
  649. console.log("************************************************************************");
  650. return this.get('group.properties');
  651. }.property('group.properties.@each').cacheable(),
  652. errorCount: function () {
  653. return this.get('group.properties').filterProperty('isValid', false).filterProperty('isVisible', true).get('length');
  654. }.property('configs.@each.isValid', 'configs.@each.isVisible')
  655. });
  656. /**
  657. * DropDown component for <code>select hosts for groups</code> popup
  658. * @type {*}
  659. */
  660. App.SlaveComponentDropDownGroupView = Ember.View.extend(App.ServiceConfigCalculateId, {
  661. viewName: "slaveComponentDropDownGroupView",
  662. /**
  663. * On change handler for <code>select hosts for groups</code> popup
  664. * @param event
  665. */
  666. changeGroup: function (event) {
  667. var host = this.get('content');
  668. var groupName = $('#' + this.get('elementId') + ' select').val();
  669. this.get('controller').changeHostGroup(host, groupName);
  670. },
  671. optionTag: Ember.View.extend({
  672. /**
  673. * Whether current value(OptionTag value) equals to host value(assigned to SlaveComponentDropDownGroupView.content)
  674. */
  675. selected: function () {
  676. return this.get('parentView.content.group') === this.get('content');
  677. }.property('content')
  678. })
  679. });
  680. /**
  681. * Show info about current group
  682. * @type {*}
  683. */
  684. App.SlaveComponentChangeGroupNameView = Ember.View.extend(App.ServiceConfigCalculateId, {
  685. contentBinding: 'controller.activeGroup',
  686. classNames: ['control-group'],
  687. classNameBindings: 'error',
  688. error: false,
  689. setError: function () {
  690. this.set('error', false);
  691. }.observes('controller.activeGroup'),
  692. errorMessage: function () {
  693. return this.get('error') ? Em.I18n.t('installer.controls.slaveComponentChangeGroupName.error') : '';
  694. }.property('error'),
  695. /**
  696. * Onclick handler for saving updated group name
  697. * @param event
  698. */
  699. changeGroupName: function (event) {
  700. var inputVal = $('#' + this.get('elementId') + ' input[type="text"]').val();
  701. if (inputVal !== this.get('content.name')) {
  702. var result = this.get('controller').changeSlaveGroupName(this.get('content'), inputVal);
  703. this.set('error', result);
  704. }
  705. }
  706. });
  707. /**
  708. * View for testing connection to database.
  709. **/
  710. App.CheckDBConnectionView = Ember.View.extend({
  711. templateName: require('templates/common/form/check_db_connection'),
  712. /** @property {string} btnCaption - text for button **/
  713. btnCaption: Em.I18n.t('services.service.config.database.btn.idle'),
  714. /** @property {string} responseCaption - text for status link **/
  715. responseCaption: null,
  716. /** @property {boolean} isConnecting - is request to server activated **/
  717. isConnecting: false,
  718. /** @property {boolean} isValidationPassed - check validation for required fields **/
  719. isValidationPassed: null,
  720. /** @property {string} databaseName- name of current database **/
  721. databaseName: null,
  722. /** @property {boolean} isRequestResolved - check for finished request to server **/
  723. isRequestResolved: false,
  724. /** @property {boolean} isConnectionSuccess - check for successful connection to database **/
  725. isConnectionSuccess: null,
  726. /** @property {string} responseFromServer - message from server response **/
  727. responseFromServer: null,
  728. /** @property {Object} ambariRequiredProperties - properties that need for custom action request **/
  729. ambariRequiredProperties: null,
  730. /** @property {Number} currentRequestId - current custom action request id **/
  731. currentRequestId: null,
  732. /** @property {Number} currentTaskId - current custom action task id **/
  733. currentTaskId: null,
  734. /** @property {jQuery.Deferred} request - current $.ajax request **/
  735. request: null,
  736. /** @property {Number} pollInterval - timeout interval for ajax polling **/
  737. pollInterval: 3000,
  738. /** @property {string} hostNameProperty - host name property based on service and database names **/
  739. hostNameProperty: function() {
  740. if (!/wizard/i.test(this.get('controller.name')) && this.get('parentView.service.serviceName') === 'HIVE') {
  741. return this.get('parentView.service.serviceName').toLowerCase() + '_hostname';
  742. } else if (this.get('parentView.service.serviceName') === 'KERBEROS') {
  743. return 'kdc_host';
  744. }
  745. return '{0}_existing_{1}_host'.format(this.get('parentView.service.serviceName').toLowerCase(), this.get('databaseName').toLowerCase());
  746. }.property('databaseName'),
  747. /** @property {boolean} isBtnDisabled - disable button on failed validation or active request **/
  748. isBtnDisabled: function() {
  749. return !this.get('isValidationPassed') || this.get('isConnecting');
  750. }.property('isValidationPassed', 'isConnecting'),
  751. /** @property {object} requiredProperties - properties that necessary for database connection **/
  752. requiredProperties: function() {
  753. var propertiesMap = {
  754. OOZIE: ['oozie.db.schema.name','oozie.service.JPAService.jdbc.username','oozie.service.JPAService.jdbc.password','oozie.service.JPAService.jdbc.driver','oozie.service.JPAService.jdbc.url'],
  755. HIVE: ['ambari.hive.db.schema.name','javax.jdo.option.ConnectionUserName','javax.jdo.option.ConnectionPassword','javax.jdo.option.ConnectionDriverName','javax.jdo.option.ConnectionURL'],
  756. KERBEROS: ['kdc_host']
  757. };
  758. return propertiesMap[this.get('parentView.service.serviceName')];
  759. }.property(),
  760. /** @property {Object} propertiesPattern - check pattern according to type of connection properties **/
  761. propertiesPattern: function() {
  762. var patterns = {
  763. db_connection_url: /jdbc\.url|connectionurl|kdc_host/ig
  764. };
  765. if (this.get('parentView.service.serviceName') != "KERBEROS") {
  766. patterns.user_name = /(username|dblogin)$/ig;
  767. patterns.user_passwd = /(dbpassword|password)$/ig;
  768. }
  769. return patterns;
  770. }.property('parentView.service.serviceName'),
  771. /** @property {String} masterHostName - host name location of Master Component related to Service **/
  772. masterHostName: function() {
  773. var serviceMasterMap = {
  774. 'OOZIE': 'oozieserver_host',
  775. 'HDFS': 'hadoop_host',
  776. 'HIVE': 'hive_ambari_host',
  777. 'KERBEROS': 'kdc_host'
  778. };
  779. return this.get('parentView.categoryConfigsAll').findProperty('name', serviceMasterMap[this.get('parentView.service.serviceName')]).get('value');
  780. }.property('parentView.service.serviceName', 'parentView.categoryConfigsAll.@each.value'),
  781. /** @property {Object} connectionProperties - service specific config values mapped for custom action request **/
  782. connectionProperties: function() {
  783. var propObj = {};
  784. for (var key in this.get('propertiesPattern')) {
  785. propObj[key] = this.getConnectionProperty(this.get('propertiesPattern')[key]);
  786. }
  787. return propObj;
  788. }.property('parentView.categoryConfigsAll.@each.value'),
  789. /**
  790. * Properties that stores in local storage used for handling
  791. * last success connection.
  792. *
  793. * @property {Object} preparedDBProperties
  794. **/
  795. preparedDBProperties: function() {
  796. var propObj = {};
  797. for (var key in this.get('propertiesPattern')) {
  798. var propName = this.getConnectionProperty(this.get('propertiesPattern')[key], true);
  799. propObj[propName] = this.get('parentView.categoryConfigsAll').findProperty('name', propName).get('value');
  800. }
  801. return propObj;
  802. }.property(),
  803. /** Check validation and load ambari properties **/
  804. didInsertElement: function() {
  805. var kdc = this.get('parentView.categoryConfigsAll').findProperty('name', 'kdc_type');
  806. if (kdc) {
  807. var name = kdc.get('value') == 'Existing MIT KDC' ? 'KDC' : 'AD';
  808. App.popover(this.$(), {
  809. title: Em.I18n.t('services.service.config.database.btn.idle'),
  810. content: Em.I18n.t('installer.controls.checkConnection.popover').format(name),
  811. placement: 'right',
  812. trigger: 'hover'
  813. });
  814. }
  815. this.handlePropertiesValidation();
  816. this.getAmbariProperties();
  817. },
  818. /** On view destroy **/
  819. willDestroyElement: function() {
  820. this.set('isConnecting', false);
  821. this._super();
  822. },
  823. /**
  824. * Observer that take care about enabling/disabling button based on required properties validation.
  825. *
  826. * @method handlePropertiesValidation
  827. **/
  828. handlePropertiesValidation: function() {
  829. this.restore();
  830. var isValid = true;
  831. var properties = [].concat(this.get('requiredProperties'));
  832. properties.push(this.get('hostNameProperty'));
  833. properties.forEach(function(propertyName) {
  834. var property = this.get('parentView.categoryConfigsAll').findProperty('name', propertyName);
  835. if(property && !property.get('isValid')) isValid = false;
  836. }, this);
  837. this.set('isValidationPassed', isValid);
  838. }.observes('parentView.categoryConfigsAll.@each.isValid', 'parentView.categoryConfigsAll.@each.value', 'databaseName'),
  839. getConnectionProperty: function(regexp, isGetName) {
  840. var _this = this;
  841. var propertyName = _this.get('requiredProperties').filter(function(item) {
  842. return regexp.test(item);
  843. })[0];
  844. return (isGetName) ? propertyName : _this.get('parentView.categoryConfigsAll').findProperty('name', propertyName).get('value');
  845. },
  846. /**
  847. * Set up ambari properties required for custom action request
  848. *
  849. * @method getAmbariProperties
  850. **/
  851. getAmbariProperties: function() {
  852. var clusterController = App.router.get('clusterController');
  853. var _this = this;
  854. if (!App.isEmptyObject(App.db.get('tmp', 'ambariProperties')) && !this.get('ambariProperties')) {
  855. this.set('ambariProperties', App.db.get('tmp', 'ambariProperties'));
  856. return;
  857. }
  858. if (App.isEmptyObject(clusterController.get('ambariProperties'))) {
  859. clusterController.loadAmbariProperties().done(function(data) {
  860. _this.formatAmbariProperties(data.RootServiceComponents.properties);
  861. });
  862. } else {
  863. this.formatAmbariProperties(clusterController.get('ambariProperties'));
  864. }
  865. },
  866. formatAmbariProperties: function(properties) {
  867. var defaults = {
  868. threshold: "60",
  869. ambari_server_host: location.hostname,
  870. check_execute_list : "db_connection_check"
  871. };
  872. var properties = App.permit(properties, ['jdk.name','jdk_location','java.home']);
  873. var renameKey = function(oldKey, newKey) {
  874. if (properties[oldKey]) {
  875. defaults[newKey] = properties[oldKey];
  876. delete properties[oldKey];
  877. }
  878. };
  879. renameKey('java.home', 'java_home');
  880. renameKey('jdk.name', 'jdk_name');
  881. $.extend(properties, defaults);
  882. App.db.set('tmp', 'ambariProperties', properties);
  883. this.set('ambariProperties', properties);
  884. },
  885. /**
  886. * `Action` method for starting connect to current database.
  887. *
  888. * @method connectToDatabase
  889. **/
  890. connectToDatabase: function() {
  891. if (this.get('isBtnDisabled')) return;
  892. this.set('isRequestResolved', false);
  893. App.db.set('tmp', this.get('parentView.service.serviceName') + '_connection', {});
  894. this.setConnectingStatus(true);
  895. if (App.get('testMode')) {
  896. this.startPolling();
  897. } else {
  898. this.runCheckConnection();
  899. }
  900. },
  901. /**
  902. * runs check connections methods depending on service
  903. * @return {void}
  904. * @method runCheckConnection
  905. */
  906. runCheckConnection: function() {
  907. if (this.get('parentView.service.serviceName') === 'KERBEROS') {
  908. this.runKDCCheck();
  909. } else {
  910. this.createCustomAction();
  911. }
  912. },
  913. /**
  914. * send ajax request to perforn kdc host check
  915. * @return {App.ajax}
  916. * @method runKDCCheck
  917. */
  918. runKDCCheck: function() {
  919. return App.ajax.send({
  920. name: 'admin.kerberos_security.test_connection',
  921. sender: this,
  922. data: {
  923. kdcHostname: this.get('masterHostName')
  924. },
  925. success: 'onRunKDCCheckSuccess',
  926. error: 'onCreateActionError'
  927. });
  928. },
  929. /**
  930. *
  931. * @param data
  932. */
  933. onRunKDCCheckSuccess: function(data) {
  934. var statusCode = {
  935. success: 'REACHABLE',
  936. failed: 'UNREACHABLE'
  937. };
  938. if (data == statusCode['success']) {
  939. this.setResponseStatus('success');
  940. } else {
  941. this.setResponseStatus('failed');
  942. }
  943. this.set('responseFromServer', data);
  944. },
  945. /**
  946. * Run custom action for database connection.
  947. *
  948. * @method createCustomAction
  949. **/
  950. createCustomAction: function() {
  951. var dbName = this.get('databaseName').toLowerCase() === 'postgresql' ? 'postgres' : this.get('databaseName').toLowerCase();
  952. var params = $.extend(true, {}, { db_name: dbName }, this.get('connectionProperties'), this.get('ambariProperties'));
  953. App.ajax.send({
  954. name: 'custom_action.create',
  955. sender: this,
  956. data: {
  957. requestInfo: {
  958. parameters: params
  959. },
  960. filteredHosts: [this.get('masterHostName')]
  961. },
  962. success: 'onCreateActionSuccess',
  963. error: 'onCreateActionError'
  964. });
  965. },
  966. /**
  967. * Run updater if task is created successfully.
  968. *
  969. * @method onConnectActionS
  970. **/
  971. onCreateActionSuccess: function(data) {
  972. this.set('currentRequestId', data.Requests.id);
  973. App.ajax.send({
  974. name: 'custom_action.request',
  975. sender: this,
  976. data: {
  977. requestId: this.get('currentRequestId')
  978. },
  979. success: 'setCurrentTaskId'
  980. });
  981. },
  982. setCurrentTaskId: function(data) {
  983. this.set('currentTaskId', data.items[0].Tasks.id);
  984. this.startPolling();
  985. },
  986. startPolling: function() {
  987. if (this.get('isConnecting'))
  988. this.getTaskInfo();
  989. },
  990. getTaskInfo: function() {
  991. var request = App.ajax.send({
  992. name: 'custom_action.request',
  993. sender: this,
  994. data: {
  995. requestId: this.get('currentRequestId'),
  996. taskId: this.get('currentTaskId')
  997. },
  998. success: 'getTaskInfoSuccess'
  999. });
  1000. this.set('request', request);
  1001. },
  1002. getTaskInfoSuccess: function(data) {
  1003. var task = data.Tasks;
  1004. this.set('responseFromServer', {
  1005. stderr: task.stderr,
  1006. stdout: task.stdout
  1007. });
  1008. if (task.status === 'COMPLETED') {
  1009. var structuredOut = task.structured_out.db_connection_check;
  1010. if (structuredOut.exit_code != 0) {
  1011. this.set('responseFromServer', {
  1012. stderr: task.stderr,
  1013. stdout: task.stdout,
  1014. structuredOut: structuredOut.message
  1015. });
  1016. this.setResponseStatus('failed');
  1017. } else {
  1018. App.db.set('tmp', this.get('parentView.service.serviceName') + '_connection', this.get('preparedDBProperties'));
  1019. this.setResponseStatus('success');
  1020. }
  1021. }
  1022. if (task.status === 'FAILED') {
  1023. this.setResponseStatus('failed');
  1024. }
  1025. if (/PENDING|QUEUED|IN_PROGRESS/.test(task.status)) {
  1026. Em.run.later(this, function() {
  1027. this.startPolling();
  1028. }, this.get('pollInterval'));
  1029. }
  1030. },
  1031. onCreateActionError: function(jqXhr, status, errorMessage) {
  1032. this.setResponseStatus('failed');
  1033. this.set('responseFromServer', errorMessage);
  1034. },
  1035. setResponseStatus: function(isSuccess) {
  1036. var isSuccess = isSuccess == 'success';
  1037. this.setConnectingStatus(false);
  1038. this.set('responseCaption', isSuccess ? Em.I18n.t('services.service.config.database.connection.success') : Em.I18n.t('services.service.config.database.connection.failed'));
  1039. this.set('isConnectionSuccess', isSuccess);
  1040. this.set('isRequestResolved', true);
  1041. },
  1042. /**
  1043. * Switch captions and statuses for active/non-active request.
  1044. *
  1045. * @method setConnectionStatus
  1046. * @param {Boolean} [active]
  1047. */
  1048. setConnectingStatus: function(active) {
  1049. if (active) {
  1050. this.set('responseCaption', Em.I18n.t('services.service.config.database.connection.inProgress'));
  1051. }
  1052. this.set('controller.testConnectionInProgress', !!active);
  1053. this.set('btnCaption', !!active ? Em.I18n.t('services.service.config.database.btn.connecting') : Em.I18n.t('services.service.config.database.btn.idle'));
  1054. this.set('isConnecting', !!active);
  1055. },
  1056. /**
  1057. * Set view to init status.
  1058. *
  1059. * @method restore
  1060. **/
  1061. restore: function() {
  1062. if (this.get('request')) {
  1063. this.get('request').abort();
  1064. this.set('request', null);
  1065. }
  1066. this.set('responseCaption', null);
  1067. this.set('responseFromServer', null);
  1068. this.setConnectingStatus(false);
  1069. this.set('isRequestResolved', false);
  1070. },
  1071. /**
  1072. * `Action` method for showing response from server in popup.
  1073. *
  1074. * @method showLogsPopup
  1075. **/
  1076. showLogsPopup: function() {
  1077. if (this.get('isConnectionSuccess')) return;
  1078. var _this = this;
  1079. var popup = App.showAlertPopup('Error: {0} connection'.format(this.get('databaseName')));
  1080. if (typeof this.get('responseFromServer') == 'object') {
  1081. popup.set('bodyClass', Em.View.extend({
  1082. templateName: require('templates/common/error_log_body'),
  1083. openedTask: _this.get('responseFromServer')
  1084. }));
  1085. } else {
  1086. popup.set('body', this.get('responseFromServer'));
  1087. }
  1088. return popup;
  1089. }
  1090. });