controls_view.js 43 KB

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