From a366a47989bd613c9813f6fc352a3ebf82520536 Mon Sep 17 00:00:00 2001 From: AKHIL PB Date: Wed, 26 Apr 2017 15:33:07 +0530 Subject: [PATCH] YARN-6419-yarn-native-services.002 --- .../main/webapp/app/adapters/yarn-servicedef.js | 48 ++++ .../main/webapp/app/components/breadcrumb-bar.js | 1 + .../main/webapp/app/components/config-tooltip.js | 24 ++ .../webapp/app/components/config-upload-modal.js | 54 ++++ .../main/webapp/app/components/deploy-service.js | 160 ++++++++++++ .../app/components/fileconfig-viewer-dialog.js | 36 +++ .../app/components/service-component-table.js | 75 ++++++ .../webapp/app/components/service-config-table.js | 89 +++++++ .../app/components/service-fileconfig-table.js | 114 +++++++++ .../webapp/app/controllers/yarn-deploy-service.js | 69 +++++ .../src/main/webapp/app/models/yarn-servicedef.js | 279 +++++++++++++++++++++ .../hadoop-yarn-ui/src/main/webapp/app/router.js | 1 + .../main/webapp/app/routes/yarn-deploy-service.js | 27 ++ .../src/main/webapp/app/services/hosts.js | 4 + .../src/main/webapp/app/styles/app.css | 142 +++++++++++ .../app/templates/components/breadcrumb-bar.hbs | 4 +- .../app/templates/components/config-tooltip.hbs | 38 +++ .../templates/components/config-upload-modal.hbs | 44 ++++ .../app/templates/components/deploy-service.hbs | 153 +++++++++++ .../components/fileconfig-viewer-dialog.hbs | 53 ++++ .../components/service-component-table.hbs | 119 +++++++++ .../templates/components/service-config-table.hbs | 129 ++++++++++ .../components/service-fileconfig-table.hbs | 140 +++++++++++ .../src/main/webapp/app/templates/yarn-apps.hbs | 2 +- .../webapp/app/templates/yarn-apps/services.hbs | 8 +- .../webapp/app/templates/yarn-deploy-service.hbs | 33 +++ .../main/webapp/app/templates/yarn-services.hbs | 4 + .../src/main/webapp/config/configs.env | 7 + .../src/main/webapp/config/default-config.js | 2 + .../integration/components/config-tooltip-test.js | 43 ++++ .../components/config-upload-modal-test.js | 43 ++++ .../integration/components/deploy-service-test.js | 43 ++++ .../components/fileconfig-viewer-dialog-test.js | 43 ++++ .../components/service-component-table-test.js | 43 ++++ .../components/service-config-table-test.js | 43 ++++ .../components/service-fileconfig-table-test.js | 43 ++++ .../tests/unit/adapters/yarn-servicedef-test.js | 30 +++ .../unit/controllers/yarn-deploy-service-test.js | 30 +++ .../tests/unit/models/yarn-servicedef-test.js | 30 +++ .../tests/unit/routes/yarn-deploy-service-test.js | 29 +++ 40 files changed, 2276 insertions(+), 3 deletions(-) create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/config-tooltip.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/config-upload-modal.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/fileconfig-viewer-dialog.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-component-table.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-config-table.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-fileconfig-table.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/config-tooltip.hbs create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/config-upload-modal.hbs create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/fileconfig-viewer-dialog.hbs create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-component-table.hbs create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-config-table.hbs create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-fileconfig-table.hbs create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/config-tooltip-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/config-upload-modal-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/fileconfig-viewer-dialog-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-component-table-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-config-table-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-fileconfig-table-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js create mode 100644 hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js new file mode 100644 index 0000000..a4d3fd9 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; +import AbstractAdapter from './abstract'; + +export default AbstractAdapter.extend({ + address: "dashWebAddress", + restNameSpace: "dashService", + serverName: "DASH", + + deployService(request) { + var url = this.buildURL(); + return this.jqueryAjax(url, "POST", request); + }, + + jqueryAjax(url, type, data) { + return new Ember.RSVP.Promise(function(resolve, reject) { + Ember.$.ajax({ + url: url, + type: type, + data: data, + contentType: "application/json", + dataType: "json" + }).then(function(resp) { + Ember.run(null, resolve, resp); + }, function(jqXHR) { + jqXHR.then = null; + Ember.run(null, reject, jqXHR); + }); + }); + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js index 44edb8e..b8d974a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js @@ -21,6 +21,7 @@ import Ember from 'ember'; export default Ember.Component.extend({ breadcrumbs: null, + hideRefresh: false, actions:{ refresh: function () { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/config-tooltip.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/config-tooltip.js new file mode 100644 index 0000000..743cc8e --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/config-tooltip.js @@ -0,0 +1,24 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + classNames: ['tooltip service-config-tooltip'], + data: null +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/config-upload-modal.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/config-upload-modal.js new file mode 100644 index 0000000..2f9dc9c --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/config-upload-modal.js @@ -0,0 +1,54 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + dialogId: "config_upload_modal", + title: "Upload Configuration", + configJson: '', + parseErrorMsg: '', + + actions: { + uploadConfig() { + var json = this.get('configJson'); + try { + JSON.parse(json); + this.upateParseResults(""); + } catch (ex) { + this.upateParseResults("Invalid JSON: " + ex.message); + throw ex; + } + if (!this.get('parseErrorMsg')) { + this.sendAction("uploadConfig", json); + } + } + }, + + didInsertElement() { + this.$('#' + this.get('dialogId')).on('shown.bs.modal', function() { + this.upateParseResults(""); + }.bind(this)); + }, + + isValidConfigJson: Ember.computed.notEmpty('configJson'), + + upateParseResults(message) { + this.set('parseErrorMsg', message); + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js new file mode 100644 index 0000000..49aed87 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js @@ -0,0 +1,160 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + viewType: 'standard', + savedStandardTemplates: null, + savedJsonTemplates: null, + savedTemplateName: '', + serviceDef: null, + jsonServiceDef: '', + serviceResp: null, + isLoading: false, + + actions: { + showSaveTemplateModal() { + this.$('#saveListModal').modal('show'); + }, + + deployService() { + this.set('serviceResp', null); + if (this.get('isStandardViewType')) { + this.sendAction("deployServiceDef", this.get('serviceDef')); + } else { + this.sendAction("deployServiceJson", this.get('jsonServiceDef')); + } + }, + + updateViewType(type) { + this.set('viewType', type); + }, + + addToSavedList() { + this.unselectAllSavedList(); + if (this.get('isStandardViewType')) { + this.get('savedStandardTemplates').addObject({ + name: this.get('savedTemplateName'), + defId: this.get('serviceDef.id'), + active: true + }); + this.set('serviceDef.isCached', true); + } else { + this.get('savedJsonTemplates').addObject({ + name: this.get('savedTemplateName'), + json: this.get('jsonServiceDef'), + active: true + }); + } + this.$('#saveListModal').modal('hide'); + this.set('savedTemplateName', ''); + }, + + updateServiceDef(def) { + this.selectActiveListItem(def); + if (this.get('isStandardViewType')) { + this.set('serviceDef', this.getStore().peekRecord('yarn-servicedef', def.defId)); + } else { + this.set('jsonServiceDef', def.json); + } + }, + + clearConfigs() { + this.unselectAllSavedList(); + if (this.get('isStandardViewType')) { + var oldDef = this.get('serviceDef'); + var def = oldDef.createNewServiceDef(); + this.set('serviceDef', def); + if (!oldDef.get('isCached')) { + oldDef.deleteRecord(); + } + } else { + this.set('jsonServiceDef', ''); + } + }, + + removeFromSavedList(list) { + if (list.active) { + this.send('clearConfigs'); + } + if (this.get('isStandardViewType')) { + this.get('savedStandardTemplates').removeObject(list); + } else { + this.get('savedJsonTemplates').removeObject(list); + } + }, + + clearServiceResponse() { + this.set('serviceResp', null); + } + }, + + didInsertElement() { + var self = this; + self.$().find('.modal').on('shown.bs.modal', function() { + self.$().find('.modal.in').find('input.form-control:first').focus(); + }); + }, + + selectActiveListItem(item) { + this.unselectAllSavedList(); + Ember.set(item, 'active', true); + }, + + unselectAllSavedList() { + this.get('getSavedList').forEach(function(item) { + Ember.set(item, 'active', false); + }); + }, + + getSavedList: Ember.computed('viewType', function() { + if (this.get('isStandardViewType')) { + return this.get('savedStandardTemplates'); + } else { + return this.get('savedJsonTemplates'); + } + }), + + getStore: function() { + return this.get('serviceDef.store'); + }, + + isStandardViewType: Ember.computed.equal('viewType', 'standard'), + + isCustomViewType: Ember.computed.equal('viewType', 'custom'), + + isValidTemplateName: Ember.computed.notEmpty('savedTemplateName'), + + isValidServiceDef: Ember.computed('serviceDef.name', 'serviceDef.queue', 'serviceDef.serviceComponents.[]', function () { + return this.get('serviceDef').isValidServiceDef(); + }), + + isValidJsonService: Ember.computed.notEmpty('jsonServiceDef'), + + enableSaveOrDeployBtn: Ember.computed('isValidServiceDef', 'isValidJsonService', 'viewType', 'isLoading', function() { + if (this.get('isLoading')) { + return false; + } + if (this.get('isStandardViewType')) { + return this.get('isValidServiceDef'); + } else { + return this.get('isValidJsonService'); + } + }) +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/fileconfig-viewer-dialog.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/fileconfig-viewer-dialog.js new file mode 100644 index 0000000..d4912768 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/fileconfig-viewer-dialog.js @@ -0,0 +1,36 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + dialogId: "fileconfig_viewer_dialog", + title: "File Configuration Properties", + props: null, + customProps: Ember.computed('props', function() { + var custom = []; + var props = this.get('props'); + for (var pro in props) { + custom.push({ + name: pro, + value: props[pro] + }); + } + return custom; + }) +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-component-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-component-table.js new file mode 100644 index 0000000..887edd9 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-component-table.js @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + serviceDef: null, + componentConfigJson: '', + currentComponent: null, + duplicateNameError: false, + + actions: { + showAddComponentModal() { + var newComp = this.get('serviceDef').createNewServiceComponent(); + this.set('currentComponent', newComp); + this.set('duplicateNameError', false); + this.$('#addComponentModal').modal('show'); + }, + + addNewComponent() { + this.set('duplicateNameError', false); + if (this.isCurrentNameDuplicate()) { + this.set('duplicateNameError', true); + return; + } + this.get('serviceDef.serviceComponents').addObject(this.get('currentComponent')); + this.$('#addComponentModal').modal('hide'); + }, + + removeComponent(component) { + this.get('serviceDef.serviceComponents').removeObject(component); + }, + + showUploadConfigModal(component) { + var $modalDialog = this.$('#service_component_config_upload_modal'); + this.set('componentConfigJson', ''); + $modalDialog.modal('show'); + $modalDialog.data('targetComponent', component); + }, + + uploadComponentConfig(json) { + var $modalDialog = this.$('#service_component_config_upload_modal'); + var component = $modalDialog.data('targetComponent'); + var parsedJson = JSON.parse(json); + component.set('configuration', parsedJson); + $modalDialog.modal('hide'); + $modalDialog.data('targetComponent', null); + } + }, + + isCurrentNameDuplicate() { + var currName = this.get('currentComponent.name'); + var item = this.get('serviceDef.serviceComponents').findBy('name', currName); + return !Ember.isNone(item); + }, + + isValidComponentConfigJson: Ember.computed.notEmpty('componentConfigJson'), + + isValidCurrentComponent: Ember.computed.and('currentComponent', 'currentComponent.name', 'currentComponent.cpus', 'currentComponent.memory', 'currentComponent.numOfContainers', 'currentComponent.artifactId', 'currentComponent.launchCommand') +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-config-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-config-table.js new file mode 100644 index 0000000..b0a78dd --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-config-table.js @@ -0,0 +1,89 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + serviceDef: null, + currentConfig: null, + serviceConfigJson: '', + + actions: { + showNewConfigurationModal() { + var newConfig = this.get('serviceDef').createNewServiceConfig(); + this.set('currentConfig', newConfig); + this.$('#addConfigurationModal').modal('show'); + if (this.get('isNonEmptyComponents') && this.get('currentConfig.componentName') === '') { + this.set('currentConfig.componentName', this.get('componentNames.firstObject')); + } + }, + + removeConfiguration(config) { + this.get('serviceDef.serviceConfigs').removeObject(config); + }, + + configTypeChanged(type) { + this.set('currentConfig.type', type); + if (type === 'quicklink') { + this.set('currentConfig.scope', 'service'); + this.set('currentConfig.componentName', ''); + } + }, + + addNewConfiguration() { + this.get('serviceDef.serviceConfigs').addObject(this.get('currentConfig')); + this.$('#addConfigurationModal').modal('hide'); + }, + + showServiceConfigUploadModal() { + this.set('serviceConfigJson', ''); + this.$("#service_config_upload_modal").modal('show'); + }, + + uploadServiceConfig(json) { + this.get('serviceDef').convertJsonServiceConfigs(json); + this.$("#service_config_upload_modal").modal('hide'); + }, + + configScopeChanged(scope) { + this.set('currentConfig.scope', scope); + }, + + scopeComponentChanged(name) { + this.set('currentConfig.componentName', name); + } + }, + + isNonEmptyComponents: Ember.computed('serviceDef.serviceComponents.length', function() { + return this.get('serviceDef.serviceComponents.length') > 0; + }), + + isNotQuicklink: Ember.computed('currentConfig.type', function() { + return this.get('currentConfig.type') !== "quicklink"; + }), + + componentNames: Ember.computed('serviceDef.serviceComponents.[]', function() { + var names = []; + this.get('serviceDef.serviceComponents').forEach(function(cmp) { + names.push(cmp.get('name')); + }); + return names; + }), + + isValidCurrentConfig: Ember.computed.and('currentConfig', 'currentConfig.name', 'currentConfig.value') +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-fileconfig-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-fileconfig-table.js new file mode 100644 index 0000000..c16d5aa --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-fileconfig-table.js @@ -0,0 +1,114 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Component.extend({ + serviceDef: null, + currentFileConfig: null, + fileConfigJson: '', + fileConfigProps: '', + propertyViewer: null, + parseError: '', + + actions: { + showNewConfigFileModal() { + var newFile = this.get('serviceDef').createNewFileConfig(); + this.set('currentFileConfig', newFile); + this.set('fileConfigProps', ''); + this.set('parseError', ''); + this.$('#addFileConfigModal').modal('show'); + if (this.get('isNonEmptyComponents') && this.get('currentFileConfig.componentName') === '') { + this.set('currentFileConfig.componentName', this.get('componentNames.firstObject')); + } + }, + + removeFileConfiguration(file) { + this.get('serviceDef.fileConfigs').removeObject(file); + }, + + addNewFileConfig() { + this.set('parseError', ''); + var props = this.get('fileConfigProps'); + if (props) { + try { + var parsed = JSON.parse(props); + this.set('currentFileConfig.props', parsed); + } catch (err) { + this.set('parseError', `Invalid JSON: ${err.message}`); + throw err; + } + } + this.get('serviceDef.fileConfigs').addObject(this.get('currentFileConfig')); + this.$('#addFileConfigModal').modal('hide'); + }, + + showFileConfigUploadModal() { + this.set('fileConfigJson', ''); + this.$("#service_file_config_upload_modal").modal('show'); + }, + + uploadFileConfig(json) { + this.get('serviceDef').convertJsonFileConfigs(json); + this.$("#service_file_config_upload_modal").modal('hide'); + }, + + configScopeChanged(scope) { + this.set('currentFileConfig.scope', scope); + }, + + scopeComponentChanged(name) { + this.set('currentFileConfig.componentName', name); + }, + + configTypeChanged(type) { + this.set('currentFileConfig.type', type); + if (type === "HADOOP_XML_TEMPLATE") { + this.set('currentFileConfig.props', null); + } else { + this.set('currentFileConfig.srcFile', ''); + } + this.set('fileConfigProps', ''); + }, + + showFileConfigPropertyViewer(props) { + this.set('propertyViewer', props); + this.$("#file_config_properties_viewer").modal('show'); + } + }, + + isNonEmptyComponents: Ember.computed('serviceDef.serviceComponents.length', function() { + return this.get('serviceDef.serviceComponents.length') > 0; + }), + + componentNames: Ember.computed('serviceDef.serviceComponents.[]', function() { + var names = []; + this.get('serviceDef.serviceComponents').forEach(function(cmp) { + names.push(cmp.get('name')); + }); + return names; + }), + + isValidCurrentFileConfig: Ember.computed('currentFileConfig', 'currentFileConfig.srcFile', 'currentFileConfig.destFile', 'fileConfigProps', function() { + return this.get('currentFileConfig') && this.get('currentFileConfig.destFile') && (this.get('currentFileConfig.srcFile') || this.get('fileConfigProps')); + }), + + isConfigTypeProperties: Ember.computed('currentFileConfig.type', function() { + return this.get('currentFileConfig.type') === 'PROPERTIES'; + }) +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js new file mode 100644 index 0000000..5ae1583 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js @@ -0,0 +1,69 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Controller.extend({ + breadcrumbs: [{ + text: "Home", + routeName: 'application' + }, { + text: "Services", + routeName: 'yarn-services', + }, { + text: "New Service", + routeName: 'yarn-deploy-service', + }], + + savedStandardTemplates: [], + savedJsonTemplates: [], + serviceResponse: null, + isLoading: false, + + actions: { + deployServiceDef(serviceDef) { + var defjson = serviceDef.getServiceJSON(); + this.deployServiceApp(JSON.stringify(defjson)); + }, + + deployServiceJson(json) { + this.deployServiceApp(json); + } + }, + + gotoServices() { + Ember.run.later(this, function() { + this.set('serviceResponse', null); + this.transitionToRoute('yarn-services'); + }, 1000); + }, + + deployServiceApp(requestJson) { + var self = this; + var adapter = this.store.adapterFor('yarn-servicedef'); + this.set('isLoading', true); + adapter.deployService(requestJson).then(function() { + self.set('serviceResponse', {message: 'Service has been accepted successfully. Redirecting to services in a second.', type: 'success'}); + self.gotoServices(); + }, function(errmsg) { + self.set('serviceResponse', {message: errmsg, type: 'error'}); + }).finally(function() { + self.set('isLoading', false); + }); + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js new file mode 100644 index 0000000..e12ff4a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js @@ -0,0 +1,279 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import DS from 'ember-data'; +import Ember from 'ember'; + +export default DS.Model.extend({ + name: DS.attr('string', {defaultValue: ''}), + queue: DS.attr('string', {defaultValue: ''}), + lifetime: DS.attr('string', {defaultValue: ''}), + isCached: DS.attr('boolean', {defaultValue: false}), + + serviceComponents: DS.attr({defaultValue: function() { + return Ember.A(); + }}), + + serviceConfigs: DS.attr({defaultValue: function() { + return Ember.A(); + }}), + + fileConfigs: DS.attr({defaultValue: function() { + return Ember.A(); + }}), + + quicklinks: DS.attr({defaultValue: function() { + return {}; + }}), + + clear() { + this.set('name', ''); + this.set('queue', ''); + this.set('lifetime', ''); + this.get('serviceComponents').clear(); + this.get('serviceConfigs').clear(); + this.get('fileConfigs').clear(); + this.set('quicklinks', {}); + }, + + isValidServiceDef() { + return this.get('name') !== '' && this.get('queue') !== '' && this.get('serviceComponents.length') > 0; + }, + + createNewServiceComponent() { + return Ember.Object.create({ + name: '', + numOfContainers: '', + cpus: '', + memory: '', + artifactId: '', + artifactType: 'DOCKER', + launchCommand: '', + dependencies: [], + uniqueComponentSupport: false, + configuration: null + }); + }, + + createNewServiceConfig(name, value) { + var Config = Ember.Object.extend({ + name: name || '', + value: value || '', + type: 'property', // property OR env OR quicklink + scope: 'service', // service OR component + componentName: '', + capitalizedType: Ember.computed('type', function() { + return Ember.String.capitalize(this.get('type')); + }), + formattedScope: Ember.computed('scope', 'componentName', function() { + if (this.get('scope') !== 'service') { + return this.get('componentName') + ' [Component]'; + } + return Ember.String.capitalize(this.get('scope')); + }) + }); + return Config.create(); + }, + + createNewFileConfig(src, dest) { + var FileConfig = Ember.Object.extend({ + type: 'HADOOP_XML_TEMPLATE', // HADOOP_XML_TEMPLATE OR PROPERTIES + srcFile: src || '', + destFile: dest || '', + scope: 'service', // service OR component + componentName: '', + props: null, + formattedScope: Ember.computed('scope', 'componentName', function() { + if (this.get('scope') !== 'service') { + return this.get('componentName') + ' [Component]'; + } + return Ember.String.capitalize(this.get('scope')); + }) + }); + return FileConfig.create(); + }, + + getServiceJSON() { + return this.serializeServiceDef(); + }, + + serializeServiceDef() { + var json = { + name: "", + queue: "", + lifetime: "-1", + components: [], + configuration: { + properties: {}, + env: {}, + files: [] + }, + quicklinks: {} + }; + + var components = this.get('serviceComponents'); + var configs = this.get('serviceConfigs'); + var fileConfigs = this.get('fileConfigs'); + + json['name'] = this.get('name'); + json['queue'] = this.get('queue'); + + if (this.get('lifetime')) { + json['lifetime'] = this.get('lifetime'); + } + + components.forEach(function(component) { + json.components.push(this.serializeComponent(component)); + }.bind(this)); + + configs.forEach(function(config) { + let conf = this.serializeConfiguration(config); + if (conf.scope === "service") { + if (conf.type === "property") { + json.configuration.properties[conf.name] = conf.value; + } else if (conf.type === "env") { + json.configuration.env[conf.name] = conf.value; + } else if (conf.type === "quicklink") { + json.quicklinks[conf.name] = conf.value; + } + } else if (conf.scope === "component") { + let requiredCmp = json.components.findBy('name', conf.componentName); + if (requiredCmp) { + requiredCmp.configuration = requiredCmp.configuration || {}; + requiredCmp.configuration.properties = requiredCmp.configuration.properties || {}; + requiredCmp.configuration.env = requiredCmp.configuration.env || {}; + if (conf.type === "property") { + requiredCmp.configuration.properties[conf.name] = conf.value; + } else if (conf.type === "env") { + requiredCmp.configuration.env[conf.name] = conf.value; + } + } + } + }.bind(this)); + + fileConfigs.forEach(function(file) { + let scope = file.get('scope'); + if (scope === "service") { + json.configuration.files.push(this.serializeFileConfig(file)); + } else if (scope === "component") { + let requiredCmp = json.components.findBy('name', file.get('componentName')); + if (requiredCmp) { + requiredCmp.configuration = requiredCmp.configuration || {}; + requiredCmp.configuration.files = requiredCmp.configuration.files || []; + requiredCmp.configuration.files.push(this.serializeFileConfig(file)); + } + } + }.bind(this)); + + return json; + }, + + serializeComponent(record) { + var json = {}; + json['name'] = record.get('name'); + json['number_of_containers'] = record.get('numOfContainers'); + json['launch_command'] = record.get('launchCommand'); + json['dependencies'] = []; + json['artifact'] = { + id: record.get('artifactId'), + type: record.get('artifactType') + }; + json['resource'] = { + cpus: record.get('cpus'), + memory: record.get('memory') + }; + if (record.get('uniqueComponentSupport')) { + json['unique_component_support'] = "true"; + } + if (record.get('configuration')) { + json['configuration'] = record.get('configuration'); + } + return json; + }, + + serializeConfiguration(config) { + var json = {}; + json["type"] = config.get('type'); + json["scope"] = config.get('scope'); + json["componentName"] = config.get('componentName'); + json["name"] = config.get('name'); + json["value"] = config.get('value'); + return json; + }, + + serializeFileConfig(file) { + var json = {}; + json["type"] = file.get('type'); + json["dest_file"] = file.get('destFile'); + if (file.get('type') === "HADOOP_XML_TEMPLATE") { + json["src_file"] = file.get('srcFile'); + } else { + json["props"] = file.get('props'); + } + return json; + }, + + createNewServiceDef() { + return this.get('store').createRecord('yarn-servicedef', { + id: 'yarn_servicedef_' + Date.now() + }); + }, + + convertJsonServiceConfigs(json) { + var parsedJson = JSON.parse(json); + if (parsedJson.properties) { + for (let prop in parsedJson.properties) { + if (parsedJson.properties.hasOwnProperty(prop)) { + let newPropObj = this.createNewServiceConfig(prop, parsedJson.properties[prop]); + this.get('serviceConfigs').addObject(newPropObj); + } + } + } + if (parsedJson.env) { + for (let envprop in parsedJson.env) { + if (parsedJson.env.hasOwnProperty(envprop)) { + let newEnvObj = this.createNewServiceConfig(envprop, parsedJson.env[envprop]); + newEnvObj.set('type', 'env'); + this.get('serviceConfigs').addObject(newEnvObj); + } + } + } + }, + + convertJsonFileConfigs(json) { + var parsedJson = JSON.parse(json); + if (parsedJson.files) { + parsedJson.files.forEach(function(file) { + let newFileObj = this.createNewFileConfig(file.src_file, file.dest_file); + this.get('fileConfigs').addObject(newFileObj); + }.bind(this)); + } + }, + + cloneServiceDef() { + var clone = this.createNewServiceDef(); + clone.set('name', this.get('name')); + clone.set('queue', this.get('queue')); + clone.set('lifetime', this.get('lifetime')); + clone.get('serviceComponents', this.get('serviceComponents')); + clone.get('serviceConfigs', this.get('serviceConfigs')); + clone.get('fileConfigs', this.get('fileConfigs')); + clone.set('quicklinks', this.get('quicklinks')); + return clone; + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js index a45861e..8b7cf69 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js @@ -49,6 +49,7 @@ Router.map(function() { this.route('yarn-container-log', { path: '/yarn-container-log/:node_id/:node_addr/:container_id/:filename' }); + this.route('yarn-deploy-service'); this.route('cluster-overview'); this.route('yarn-app', { path: '/yarn-app/:app_id' }); this.route('yarn-app-attempt', { path: '/yarn-app-attempt/:app_attempt_id'}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js new file mode 100644 index 0000000..05ef600 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Ember from 'ember'; + +export default Ember.Route.extend({ + model() { + return this.store.createRecord('yarn-servicedef', { + id: 'yarn_servicedef_' + Date.now() + }); + } +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js index 807844e..9359530 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js @@ -75,4 +75,8 @@ export default Ember.Service.extend({ rmWebAddress: Ember.computed(function () { return this.normalizeURL(this.get("env.app.hosts.rmWebAddress")); }), + + dashWebAddress: Ember.computed(function () { + return this.normalizeURL(this.get("env.app.hosts.dashWebAddress")); + }) }); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css index e3dfcd9..e8d385e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css @@ -314,3 +314,145 @@ div.attempt-info-panel table > tbody > tr > td:last-of-type { overflow: hidden; text-overflow: ellipsis; } + +.deploy-service textarea { + border-radius: 5px !important; + resize: none; + word-wrap: break-word; +} + +.deploy-service .loading-state { + opacity: 0.5; +} + +.deploy-service .loading-state img { + width: 80px; + height: 80px; + margin: 40px auto; + left: 50% !important; + position: absolute; + z-index: 9999; +} + +.align-center { + text-align: center !important; +} + +.bold-text { + font-weight: bold !important; +} + +.deploy-service .saved-list { + min-height: 600px; +} + +.deploy-service .glyphicon { + cursor: pointer; +} + +.deploy-service .remove-icon:hover { + color: #d9534f; +} + +.deploy-service .savedlist-column { + padding-top: 10px; +} + +.deploy-service .definition-column { + padding-top: 10px; + border-left: 1px solid #ddd; +} + +.deploy-service .content-area { + padding: 15px 0px; + border-top: 1px solid #ddd; +} + +.deploy-service .custom-json-area { + padding: 10px 0; + margin-top: -26px; +} + +.deploy-service-modal .modal-dialog { + width: 400px; +} + +.deploy-service-modal .form-group { + margin-bottom: 5px; +} + +.deploy-service .action-btns { + text-align: right; + padding-bottom: 15px; + padding-right: 0; +} + +table.table-custom-action > thead > tr > th:last-of-type, table.table-custom-action > tbody > tr > td:last-of-type { + width: 50px !important; +} + +.deploy-service .toggle-btn.active { + color: #fff; + background-color: #337ab7; + border-color: #337ab7; + text-shadow: none; +} + +.deploy-service .service-resp { + word-wrap: break-word; +} + +.deploy-service .service-resp .remove-icon { + padding: 5px; +} + +table.table-custom-bordered { + border: 1px solid #ddd !important; + border-radius: 3px !important; +} + +table.table-custom-bordered > thead > tr > th, table.table-custom-bordered > tbody > tr > td { + border-bottom: 1px solid #ddd !important; + border-right: 1px solid #ddd !important; +} + +table.table-custom-striped > thead > tr, .table-custom-striped > tbody > tr:nth-of-type(even) { + background-color: #f9f9f9 !important; +} + +.deploy-service label.required:after, .deploy-service-modal label.required:after { + content: '*'; + color: #d9534f; +} + +.deploy-service .form-group.shrink-height { + margin-bottom: -8px; +} + +div.tooltip.service-config-tooltip { + position: absolute; + display: none; + opacity: 1; + z-index: 9999; + width: 550px; + max-width: 550px; + word-wrap: break-word; + font: 14px sans-serif !important; + left: 0; + top: 0; +} + +div.tooltip.service-config-tooltip .table { + background: lightsteelblue; + border-radius: 5px; + text-align: left; +} + +table.fix-table-overflow { + table-layout: fixed; +} + +table.fix-table-overflow > tbody > tr > td:last-of-type { + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs index 24acbd9..54229cc 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs @@ -18,5 +18,7 @@ diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/config-tooltip.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/config-tooltip.hbs new file mode 100644 index 0000000..e1d3f22 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/config-tooltip.hbs @@ -0,0 +1,38 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + +{{#if data}} + + + + + + + + + {{#each data.files as |file|}} + + + + + {{/each}} + +
Source FileDestination File
{{file.src_file}}{{file.dest_file}}
+{{/if}} + +{{yield}} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/config-upload-modal.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/config-upload-modal.hbs new file mode 100644 index 0000000..045fb0f --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/config-upload-modal.hbs @@ -0,0 +1,44 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + + diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs new file mode 100644 index 0000000..aa3097a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs @@ -0,0 +1,153 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + +
+ {{#if serviceResp}} +
+
+
+ +
+ {{serviceResp.message}} +
+
+
+
+ {{/if}} +
+ {{#if isLoading}} + Loading... + {{/if}} +
+
+
+ +
+ +
+
+ +
+ +
+ + +
+
+ {{#if isStandardViewType}} + +
+
+
+ + {{input type="text" class="form-control" placeholder="Service Name" value=serviceDef.name}} +
+
+
+
+ +
+
+
+ + {{input type="text" class="form-control" placeholder="Queue Name" value=serviceDef.queue}} +
+
+
+
+ +
+
+
+ + {{input type="number" min="0" class="form-control" placeholder="Service Lifetime (Seconds)" value=serviceDef.lifetime}} +
+
+
+
+ +
+ {{service-component-table serviceDef=serviceDef applicationCtrl=applicationCtrl}} +
+ +
+ {{service-config-table serviceDef=serviceDef}} +
+ +
+ {{service-fileconfig-table serviceDef=serviceDef}} +
+ {{/if}} + + {{#if isCustomViewType}} +
+ {{textarea class="form-control" rows="29" cols="120" value=jsonServiceDef placeholder="Service JSON configuration here..."}} +
+ {{/if}} +
+ +
+ + + +
+
+
+
+
+
+ + diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/fileconfig-viewer-dialog.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/fileconfig-viewer-dialog.hbs new file mode 100644 index 0000000..1420340 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/fileconfig-viewer-dialog.hbs @@ -0,0 +1,53 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + + diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-component-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-component-table.hbs new file mode 100644 index 0000000..b0590e7 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-component-table.hbs @@ -0,0 +1,119 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + +
+
+ + +
+ + + + + + + + + + + + + + {{#each serviceDef.serviceComponents as |component|}} + + + + + + + + + + {{else}} + + + + {{/each}} + +
Component NameCPUMemory# ContainersArtifact IdLaunch Command
{{component.name}}{{component.cpus}}{{component.memory}}{{component.numOfContainers}}{{component.artifactId}}{{component.launchCommand}} + +
No data available
+
+
+
+ + + +{{config-upload-modal + dialogId="service_component_config_upload_modal" + title="Upload Component Configurations" + configJson=componentConfigJson + uploadConfig="uploadComponentConfig" +}} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-config-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-config-table.hbs new file mode 100644 index 0000000..e03f8fe --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-config-table.hbs @@ -0,0 +1,129 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + +
+
+ + + +
+ + + + + + + + + + + + {{#each serviceDef.serviceConfigs as |config|}} + + + + + + + + {{else}} + + + + {{/each}} + +
NameValueTypeScope
{{config.name}}{{config.value}}{{config.capitalizedType}}{{config.formattedScope}} + +
No data available
+
+
+
+ + + +{{config-upload-modal + dialogId="service_config_upload_modal" + title="Upload Service Configurations" + configJson=serviceConfigJson + uploadConfig="uploadServiceConfig" +}} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-fileconfig-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-fileconfig-table.hbs new file mode 100644 index 0000000..d3e6b86 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-fileconfig-table.hbs @@ -0,0 +1,140 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + +
+
+ + + +
+ + + + + + + + + + + + {{#each serviceDef.fileConfigs as |file|}} + + {{#if file.props}} + + {{else}} + + {{/if}} + + + + + + {{else}} + + + + {{/each}} + +
Source File / PropertiesDestination FileTypeScope
View Properties{{file.srcFile}}{{file.destFile}}{{file.type}}{{file.formattedScope}} + +
No data available
+
+
+
+ + + +{{config-upload-modal + dialogId="service_file_config_upload_modal" + title="Upload File Configurations" + configJson=fileConfigJson + uploadConfig="uploadFileConfig" +}} + +{{fileconfig-viewer-dialog dialogId="file_config_properties_viewer" props=propertyViewer}} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs index 7aade00..e51916a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs @@ -83,4 +83,4 @@ - \ No newline at end of file + diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs index 7556908..d767f95 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs @@ -16,10 +16,16 @@ limitations under the License. --}} +
+ + New Service + +
+ {{#if model.apps}} {{em-table columns=columns rows=model.apps}} {{else}}

Could not find any applications from this cluster

{{/if}} -{{outlet}} \ No newline at end of file +{{outlet}} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs new file mode 100644 index 0000000..98bc917 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs @@ -0,0 +1,33 @@ +{{! + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +}} + +{{breadcrumb-bar breadcrumbs=breadcrumbs hideRefresh=true}} + +
+
+ {{deploy-service + savedStandardTemplates=savedStandardTemplates + savedJsonTemplates=savedJsonTemplates + serviceDef=model + serviceResp=serviceResponse + isLoading=isLoading + deployServiceDef="deployServiceDef" + deployServiceJson="deployServiceJson" + }} +
+
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs index 649834a..8e3597c 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs @@ -75,6 +75,10 @@ + +
+ New Service +
{{#if model.apps}} {{em-table columns=serviceColumns rows=model.apps definition=tableDefinition}} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env index 04577c9..a795fc5 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env @@ -40,6 +40,13 @@ ENV = { */ //rmWebAddress: "localhost:8088", + /* + * Dash server web interface can be configured below. + * By default dash web address is set as localhost:9191, uncomment and change + * the following value for pointing to a different address. + */ + //dashWebAddress: "localhost:9191", + /* * Protocol scheme. It can be "http:" or "https:". By default, http is used. */ diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js index 70d4ebc..fc279d4 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js @@ -21,12 +21,14 @@ module.exports = { // Yarn UI App configurations localBaseAddress: "", timelineWebAddress: "localhost:8188", rmWebAddress: "localhost:8088", + dashWebAddress: "localhost:9191", protocolScheme: "http:" }, namespaces: { timeline: 'ws/v1/applicationhistory', cluster: 'ws/v1/cluster', metrics: 'ws/v1/cluster/metrics', + dashService: 'services/v1/applications', node: '{nodeAddress}/ws/v1/node' }, }; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/config-tooltip-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/config-tooltip-test.js new file mode 100644 index 0000000..c3c3d31 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/config-tooltip-test.js @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('config-tooltip', 'Integration | Component | config tooltip', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{config-tooltip}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#config-tooltip}} + template block text + {{/config-tooltip}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/config-upload-modal-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/config-upload-modal-test.js new file mode 100644 index 0000000..b5acd7d --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/config-upload-modal-test.js @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('config-upload-modal', 'Integration | Component | config upload modal', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{config-upload-modal}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#config-upload-modal}} + template block text + {{/config-upload-modal}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js new file mode 100644 index 0000000..ba855a7 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('deploy-service', 'Integration | Component | deploy service', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{deploy-service}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#deploy-service}} + template block text + {{/deploy-service}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/fileconfig-viewer-dialog-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/fileconfig-viewer-dialog-test.js new file mode 100644 index 0000000..f99e08f --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/fileconfig-viewer-dialog-test.js @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('fileconfig-viewer-dialog', 'Integration | Component | fileconfig viewer dialog', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{fileconfig-viewer-dialog}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#fileconfig-viewer-dialog}} + template block text + {{/fileconfig-viewer-dialog}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-component-table-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-component-table-test.js new file mode 100644 index 0000000..3ea27a5 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-component-table-test.js @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('service-component-table', 'Integration | Component | service component table', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{service-component-table}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#service-component-table}} + template block text + {{/service-component-table}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-config-table-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-config-table-test.js new file mode 100644 index 0000000..39f269a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-config-table-test.js @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('service-config-table', 'Integration | Component | service config table', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{service-config-table}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#service-config-table}} + template block text + {{/service-config-table}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-fileconfig-table-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-fileconfig-table-test.js new file mode 100644 index 0000000..a486fa0 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-fileconfig-table-test.js @@ -0,0 +1,43 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('service-fileconfig-table', 'Integration | Component | service fileconfig table', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{service-fileconfig-table}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#service-fileconfig-table}} + template block text + {{/service-fileconfig-table}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js new file mode 100644 index 0000000..ea12bc5 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('adapter:yarn-servicedef', 'Unit | Adapter | yarn servicedef', { + // Specify the other units that are required for this test. + // needs: ['serializer:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let adapter = this.subject(); + assert.ok(adapter); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js new file mode 100644 index 0000000..c3918f4 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:yarn-deploy-service', 'Unit | Controller | yarn deploy service', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js new file mode 100644 index 0000000..141a94b --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('yarn-servicedef', 'Unit | Model | yarn servicedef', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('it exists', function(assert) { + let model = this.subject(); + // let store = this.store(); + assert.ok(!!model); +}); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js new file mode 100644 index 0000000..4e2dcf1 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js @@ -0,0 +1,29 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:yarn-deploy-service', 'Unit | Route | yarn deploy service', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +}); -- 2.5.1.windows.1