Prechádzať zdrojové kódy

YARN-6398. Support to add native-service specific details in new YARN UI. Contributed by Akhil PB.

Sunil G 8 rokov pred
rodič
commit
399525c2e0
70 zmenil súbory, kde vykonal 2666 pridanie a 29 odobranie
  1. 32 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-component-instance.js
  2. 32 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-service-component.js
  3. 32 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-service-info.js
  4. 13 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js
  5. 31 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/confirm-dialog.js
  6. 24 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/metrics-table.js
  7. 63 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app/components.js
  8. 24 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app/configs.js
  9. 60 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app/info.js
  10. 59 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instance.js
  11. 25 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instance/info.js
  12. 59 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instances.js
  13. 25 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instances/configs.js
  14. 62 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instances/info.js
  15. 28 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/check-availability.js
  16. 51 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-component-instance.js
  17. 46 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-service-component.js
  18. 57 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-service-info.js
  19. 9 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
  20. 49 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app/components.js
  21. 52 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app/configs.js
  22. 11 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app/info.js
  23. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instance.js
  24. 45 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instance/info.js
  25. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instances.js
  26. 44 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instances/configs.js
  27. 53 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instances/info.js
  28. 72 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-component-instance.js
  29. 77 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-service-component.js
  30. 87 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-service-info.js
  31. 13 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css
  32. 37 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/confirm-dialog.hbs
  33. 82 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/metrics-table.hbs
  34. 8 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs
  35. 23 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app/components.hbs
  36. 57 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app/configs.hbs
  37. 85 26
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app/info.hbs
  38. 43 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instance.hbs
  39. 81 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instance/info.hbs
  40. 46 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instances.hbs
  41. 53 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instances/configs.hbs
  42. 28 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instances/info.hbs
  43. 23 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instances/loading.hbs
  44. 1 1
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js
  45. 43 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/confirm-dialog-test.js
  46. 43 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/metrics-table-test.js
  47. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-component-instance-test.js
  48. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-service-component-test.js
  49. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-service-info-test.js
  50. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app/components-test.js
  51. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app/configs-test.js
  52. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instance-test.js
  53. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instance/info-test.js
  54. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instances-test.js
  55. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instances/configs-test.js
  56. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instances/info-test.js
  57. 28 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/check-availability-test.js
  58. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-component-instance-test.js
  59. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-service-component-test.js
  60. 30 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-service-info-test.js
  61. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-app/components-test.js
  62. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-app/configs-test.js
  63. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instance-test.js
  64. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instance/info-test.js
  65. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instances-test.js
  66. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instances/configs-test.js
  67. 29 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instances/info-test.js
  68. 33 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-component-instance-test.js
  69. 33 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-service-component-test.js
  70. 33 0
      hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-service-info-test.js

+ 32 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-component-instance.js

@@ -0,0 +1,32 @@
+/**
+ * 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 AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  address: "timelineWebAddress",
+  restNameSpace: "timelineService",
+  serverName: "ATS",
+
+  urlForQuery(query/*, modelName*/) {
+    var url = this.buildURL();
+    url += '/' + query.appId + '/entities/COMPONENT_INSTANCE?fields=ALL';
+    delete query.appId;
+    return url;
+  }
+});

+ 32 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-service-component.js

@@ -0,0 +1,32 @@
+/**
+ * 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 AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  address: "timelineWebAddress",
+  restNameSpace: "timelineService",
+  serverName: "ATS",
+
+  urlForQuery(query/*, modelName*/) {
+    var url = this.buildURL();
+    url += '/' + query.appId + '/entities/COMPONENT?fields=ALL';
+    delete query.appId;
+    return url;
+  }
+});

+ 32 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-service-info.js

@@ -0,0 +1,32 @@
+/**
+ * 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 AbstractAdapter from './abstract';
+
+export default AbstractAdapter.extend({
+  address: "timelineWebAddress",
+  restNameSpace: "timelineService",
+  serverName: "ATS",
+
+  urlForQueryRecord(query/*, modelName*/) {
+    var url = this.buildURL();
+    url += '/' + query.appId + '/entities/SERVICE_ATTEMPT?fields=ALL';
+    delete query.appId;
+    return url;
+  }
+});

+ 13 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js

@@ -27,5 +27,18 @@ export default RESTAbstractAdapter.extend({
   deployService(request) {
     var url = this.buildURL();
     return this.ajax(url, "POST", {data: request});
+  },
+
+  stopService(serviceName) {
+    var url = this.buildURL();
+    url += "/" + serviceName;
+    var data = {"state": "STOPPED", "name": serviceName};
+    return this.ajax(url, "PUT", {data: data});
+  },
+
+  deleteService(serviceName) {
+    var url = this.buildURL();
+    url += "/" + serviceName;
+    return this.ajax(url, "DELETE", {data: {}});
   }
 });

+ 31 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/confirm-dialog.js

@@ -0,0 +1,31 @@
+/**
+ * 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: "confirmModalDialog",
+  title: "Confirm",
+  message: "Are you sure?",
+
+  actions: {
+    yesConfirmed() {
+      this.sendAction();
+    }
+  }
+});

+ 24 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/metrics-table.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({
+  metrics: null,
+  type: ''
+});

+ 63 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app/components.js

@@ -0,0 +1,63 @@
+/**
+ * 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 ColumnDef from 'em-table/utils/column-definition';
+
+export default Ember.Controller.extend({
+  queryParams: ["service"],
+  service: undefined,
+
+  tableColumns: Ember.computed('model.appId', 'model.serviceName', function() {
+    var cols = [];
+    var service = this.get('model.serviceName');
+    var appId = this.get('model.appId');
+
+    cols.push({
+      id: 'name',
+      headerTitle: 'Component Group',
+      contentPath: 'name',
+      cellComponentName: 'em-table-linked-cell',
+      getCellContent: function(row) {
+        return {
+          displayText: row.get('name'),
+          href: `#/yarn-component-instances/${row.get('name')}/info?service=${service}&&appid=${appId}`
+        };
+      }
+    }, {
+      id: 'vcores',
+      headerTitle: 'VCores',
+      contentPath: 'vcores'
+    }, {
+      id: 'memory',
+      headerTitle: 'Memory (MB)',
+      contentPath: 'memory'
+    }, {
+      id: 'instances',
+      headerTitle: '# Components',
+      contentPath: 'instances',
+      observePath: true
+    }, {
+      id: 'createdDate',
+      headerTitle: 'Created Time',
+      contentPath: 'createdDate'
+    });
+
+    return ColumnDef.make(cols);
+  })
+});

+ 24 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app/configs.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.Controller.extend({
+  queryParams: ["service"],
+  service: undefined
+});

+ 60 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-app/info.js

@@ -21,6 +21,66 @@ import Ember from 'ember';
 export default Ember.Controller.extend({
   queryParams: ["service"],
   service: undefined,
+  isLoading: false,
+  actionResponse: null,
+
+  actions: {
+    showStopServiceConfirm() {
+      this.set('actionResponse', null);
+      Ember.$("#stopServiceConfirmDialog").modal('show');
+    },
+
+    stopService() {
+      var self = this;
+      Ember.$("#stopServiceConfirmDialog").modal('hide');
+      var adapter = this.store.adapterFor('yarn-servicedef');
+      self.set('isLoading', true);
+      adapter.stopService(this.get('service')).then(function() {
+        self.set('actionResponse', {msg: 'Service stopped successfully. Auto refreshing in 5 seconds.', type: 'success'});
+        Ember.run.later(self, function() {
+          this.set('actionResponse', null);
+          this.send("refresh");
+        }, 5000);
+      }, function(errr) {
+        let messg = errr.diagnostics || 'Error: Stop service failed!';
+        self.set('actionResponse', {msg: messg, type: 'error'});
+      }).finally(function() {
+        self.set('isLoading', false);
+      });
+    },
+
+    showDeleteServiceConfirm() {
+      this.set('actionResponse', null);
+      Ember.$("#deleteServiceConfirmDialog").modal('show');
+    },
+
+    deleteService() {
+      var self = this;
+      Ember.$("#deleteServiceConfirmDialog").modal('hide');
+      var adapter = this.store.adapterFor('yarn-servicedef');
+      self.set('isLoading', true);
+      adapter.deleteService(this.get('service')).then(function() {
+        self.set('actionResponse', {msg: 'Service deleted successfully. Redirecting to services in 5 seconds.', type: 'success'});
+        Ember.run.later(self, function() {
+          this.set('actionResponse', null);
+          this.transitionToRoute("yarn-services");
+        }, 5000);
+      }, function(errr) {
+        let messg = errr.diagnostics || 'Error: Delete service failed!';
+        self.set('actionResponse', {msg: messg, type: 'error'});
+      }).finally(function() {
+        self.set('isLoading', false);
+      });
+    },
+
+    resetActionResponse() {
+      this.set('actionResponse', null);
+    }
+  },
+
+  isRunningService: Ember.computed('model.serviceName', 'model.app.state', function() {
+    return this.get('service') !== undefined && this.get('model.app.state') === 'RUNNING';
+  }),
 
   amHostHttpAddressFormatted: Ember.computed('model.app.amHostHttpAddress', function() {
     var amHostAddress = this.get('model.app.amHostHttpAddress');

+ 59 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instance.js

@@ -0,0 +1,59 @@
+/**
+ * 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({
+  componentName: '',
+  instanceName: '',
+  serviceName: '',
+  appId: '',
+
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Services",
+    routeName: 'yarn-services',
+  }],
+
+  updateBreadcrumbs(appId, serviceName, componentName, instanceName) {
+    var crumbs =  [{
+      text: "Home",
+      routeName: 'application'
+    }, {
+      text: "Services",
+      routeName: 'yarn-services',
+    }];
+    if (appId && serviceName && componentName && instanceName) {
+      crumbs.push({
+        text: `${serviceName} [${appId}]`,
+        href: `#/yarn-app/${appId}/info?service=${serviceName}`
+      }, {
+        text: 'Components',
+        href: `#/yarn-app/${appId}/components?service=${serviceName}`
+      }, {
+        text: `${componentName}`,
+        href: `#/yarn-component-instances/${componentName}/info?service=${serviceName}&&appid=${appId}`
+      }, {
+        text: `${instanceName}`
+      });
+    }
+    this.set('breadcrumbs', crumbs);
+  }
+});

+ 25 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instance/info.js

@@ -0,0 +1,25 @@
+/**
+ * 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({
+  queryParams: ["appid", "service"],
+  appid: undefined,
+  service: undefined
+});

+ 59 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instances.js

@@ -0,0 +1,59 @@
+/**
+ * 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({
+  componentName: '',
+  serviceName: '',
+  appId: '',
+
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Services",
+    routeName: 'yarn-services',
+  }],
+
+  updateBreadcrumbs(appId, serviceName, componentName, tailCrumbs) {
+    var crumbs =  [{
+      text: "Home",
+      routeName: 'application'
+    }, {
+      text: "Services",
+      routeName: 'yarn-services',
+    }];
+    if (appId && serviceName && componentName) {
+      crumbs.push({
+        text: `${serviceName} [${appId}]`,
+        href: `#/yarn-app/${appId}/info?service=${serviceName}`
+      }, {
+        text: 'Components',
+        href: `#/yarn-app/${appId}/components?service=${serviceName}`
+      }, {
+        text: `${componentName}`,
+        href: `#/yarn-component-instances/${componentName}/info?service=${serviceName}&&appid=${appId}`
+      });
+    }
+    if (tailCrumbs) {
+      crumbs.pushObjects(tailCrumbs);
+    }
+    this.set('breadcrumbs', crumbs);
+  }
+});

+ 25 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instances/configs.js

@@ -0,0 +1,25 @@
+/**
+ * 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({
+  queryParams: ["service", "appid"],
+  appid: undefined,
+  service: undefined
+});

+ 62 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-component-instances/info.js

@@ -0,0 +1,62 @@
+/**
+ * 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 ColumnDef from 'em-table/utils/column-definition';
+
+export default Ember.Controller.extend({
+  queryParams: ["service", "appid"],
+  appid: undefined,
+  service: undefined,
+
+  tableColumns: Ember.computed('model.appId', 'model.serviceName', function() {
+    var cols = [];
+    var appId = this.get('model.appId');
+    var serviceName = this.get('model.serviceName');
+
+    cols.push({
+      id: 'instanceName',
+      headerTitle: 'Component Name',
+      contentPath: 'instanceName',
+      cellComponentName: 'em-table-linked-cell',
+      getCellContent: function(row) {
+        var component = row.get('component');
+        var instance = row.get('instanceName');
+        return {
+          text: instance,
+          href: `#/yarn-component-instance/${component}/instances/${instance}/info?appid=${appId}&&service=${serviceName}`
+        };
+      }
+    }, {
+      id: 'containerId',
+      headerTitle: 'Current Container Id',
+      contentPath: 'containerId',
+      minWidth: '350px'
+    }, {
+      id: 'state',
+      headerTitle: 'State',
+      contentPath: 'state'
+    }, {
+      id: 'startedDate',
+      headerTitle: 'Started Time',
+      contentPath: 'startedDate'
+    });
+
+    return ColumnDef.make(cols);
+  })
+});

+ 28 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/helpers/check-availability.js

@@ -0,0 +1,28 @@
+/**
+ * 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 function checkAvailability(params/*, hash*/) {
+  if (params[0] !== undefined && params[0] !== null && params[0] !== '') {
+    return params[0];
+  }
+  return 'N/A';
+}
+
+export default Ember.Helper.helper(checkAvailability);

+ 51 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-component-instance.js

@@ -0,0 +1,51 @@
+/**
+ * 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';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.Model.extend({
+  containerId: DS.attr('string'),
+  component: DS.attr('string'),
+  instanceName: DS.attr('string'),
+  state: DS.attr('number'),
+  createdTimestamp: DS.attr('number'),
+  startedTimestamp: DS.attr('number'),
+  host: DS.attr('string'),
+  node: DS.attr('string'),
+  hostUrl: DS.attr('string'),
+  ipAddr: DS.attr('string'),
+  exitStatusCode: DS.attr('string'),
+
+  createdDate: Ember.computed('createdTimestamp', function() {
+    var timestamp = this.get('createdTimestamp');
+    if (timestamp > 0) {
+      return Converter.timeStampToDate(timestamp);
+    }
+    return 'N/A';
+  }),
+
+  startedDate: Ember.computed('startedTimestamp', function() {
+    var timestamp = this.get('startedTimestamp');
+    if (timestamp > 0) {
+      return Converter.timeStampToDate(timestamp);
+    }
+    return 'N/A';
+  })
+});

+ 46 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-service-component.js

@@ -0,0 +1,46 @@
+/**
+ * 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';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.Model.extend({
+  name: DS.attr('string'),
+  vcores: DS.attr('string'),
+  memory: DS.attr('string'),
+  priority: DS.attr('string'),
+  instances: DS.attr('string'),
+  createdTimestamp: DS.attr('number'),
+
+  configs: DS.attr({defaultValue: function() {
+    return Ember.A();
+  }}),
+
+  metrics: DS.attr({defaultValue: function() {
+    return Ember.Object.create();
+  }}),
+
+  createdDate: Ember.computed('createdTimestamp', function() {
+    var timestamp = this.get('createdTimestamp');
+    if (timestamp > 0) {
+      return Converter.timeStampToDate(timestamp);
+    }
+    return 'N/A';
+  })
+});

+ 57 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-service-info.js

@@ -0,0 +1,57 @@
+/**
+ * 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';
+import Converter from 'yarn-ui/utils/converter';
+
+export default DS.Model.extend({
+  name: DS.attr('string'),
+  appId: DS.attr('string'),
+  state: DS.attr('string'),
+  createdTimestamp: DS.attr('number'),
+  launchTimestamp: DS.attr('number'),
+
+  quicklinks: DS.attr({defaultValue: function() {
+    return Ember.A();
+  }}),
+
+  configs: DS.attr({defaultValue: function() {
+    return Ember.A();
+  }}),
+
+  metrics: DS.attr({defaultValue: function() {
+    return Ember.Object.create();
+  }}),
+
+  createdDate: Ember.computed('createdTimestamp', function() {
+    var timestamp = this.get('createdTimestamp');
+    if (timestamp > 0) {
+      return Converter.timeStampToDate(timestamp);
+    }
+    return 'N/A';
+  }),
+
+  launchDate: Ember.computed('launchTimestamp', function() {
+    var timestamp = this.get('launchTimestamp');
+    if (timestamp > 0) {
+      return Converter.timeStampToDate(timestamp);
+    }
+    return 'N/A';
+  })
+});

+ 9 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js

@@ -53,7 +53,16 @@ Router.map(function() {
   this.route('yarn-app', function() {
     this.route('info', {path: '/:app_id/info'});
     this.route('attempts', {path: '/:app_id/attempts'});
+    this.route('components', {path: '/:app_id/components'});
     this.route('charts', {path: '/:app_id/charts'});
+    this.route('configs', {path: '/:app_id/configs'});
+  });
+  this.route('yarn-component-instances', function() {
+    this.route('info', {path: '/:component_name/info'});
+    this.route('configs', {path: '/:component_name/configs'});
+  });
+  this.route('yarn-component-instance', function() {
+    this.route('info', {path: '/:component_name/instances/:instance_name/info'});
   });
   this.route('yarn-app-attempt', { path: '/yarn-app-attempt/:app_attempt_id'});
   this.route('error');

+ 49 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app/components.js

@@ -0,0 +1,49 @@
+/**
+ * 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 AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  model(param, transition) {
+    transition.send('updateBreadcrumbs', param.app_id, param.service, [{text: 'Components'}]);
+    return Ember.RSVP.hash({
+      appId: param.app_id,
+      serviceName: param.service,
+      components: this.store.query('yarn-service-component', {appId: param.app_id, type: 'COMPONENT'}).catch(function() {
+        return [];
+      }),
+      instances: this.store.query('yarn-component-instance', {appId: param.app_id}).catch(function() {
+        return [];
+      })
+    });
+  },
+
+  afterModel(model) {
+    let instances = model.instances;
+    model.components.forEach(function(component) {
+      var num = instances.filterBy('component', component.get('name')).length;
+      component.set('instances', num);
+    });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-service-component');
+    this.store.unloadAll('yarn-component-instance');
+  }
+});

+ 52 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app/configs.js

@@ -0,0 +1,52 @@
+/**
+ * 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 AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  model(param, transition) {
+    transition.send('updateBreadcrumbs', param.app_id, param.service, [{text: "Configurations & Metrics"}]);
+    return Ember.RSVP.hash({
+      appId: param.app_id,
+      serviceName: param.service,
+
+      configs: this.store.queryRecord('yarn-service-info', {appId: param.app_id}).then(function(info) {
+        if (info && info.get('configs')) {
+          return info.get('configs');
+        }
+        return [];
+      }, function() {
+        return [];
+      }),
+
+      metrics: this.store.queryRecord('yarn-service-info', {appId: param.app_id}).then(function(info) {
+        if (info && info.get('metrics')) {
+          return info.get('metrics');
+        }
+        return null;
+      }, function() {
+        return null;
+      })
+    });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-service-info');
+  }
+});

+ 11 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-app/info.js

@@ -26,12 +26,22 @@ export default AbstractRoute.extend(AppAttemptMixin, {
     return Ember.RSVP.hash({
       appId: param.app_id,
       serviceName: param.service,
-      app: this.fetchAppInfoFromRMorATS(param.app_id, this.store)
+      app: this.fetchAppInfoFromRMorATS(param.app_id, this.store),
+
+      quicklinks: this.store.queryRecord('yarn-service-info', {appId: param.app_id}).then(function(info) {
+        if (info && info.get('quicklinks')) {
+          return info.get('quicklinks');
+        }
+        return [];
+      }, function() {
+        return [];
+      })
     });
   },
 
   unloadAll() {
     this.store.unloadAll('yarn-app');
     this.store.unloadAll('yarn-app-timeline');
+    this.store.unloadAll('yarn-service-info');
   }
 });

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instance.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 AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  actions: {
+    updateBreadcrumbs(appId, serviceName, componentName, instanceName) {
+      var controller = this.controllerFor('yarn-component-instance');
+      controller.setProperties({appId: appId, serviceName: serviceName, componentName: componentName, instanceName: instanceName});
+      controller.updateBreadcrumbs(appId, serviceName, componentName, instanceName);
+    }
+  }
+});

+ 45 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instance/info.js

@@ -0,0 +1,45 @@
+/**
+ * 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 AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  model(params, transition) {
+    var instanceName = params.instance_name;
+    transition.send('updateBreadcrumbs', params.appid, params.service, params.component_name, instanceName);
+    return Ember.RSVP.hash({
+      appId: params.appid,
+      serviceName: params.service,
+      componentName: params.component_name,
+      instanceName: instanceName,
+      container: this.store.query('yarn-component-instance', {appId: params.appid}).then(function(instances) {
+        if (instances && instances.findBy('instanceName', instanceName)) {
+          return instances.findBy('instanceName', instanceName);
+        }
+        return null;
+      }, function() {
+        return null;
+      }),
+    });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-component-instance');
+  }
+});

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instances.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 AbstractRoute from './abstract';
+
+export default AbstractRoute.extend({
+  actions: {
+    updateBreadcrumbs(appId, serviceName, componentName, tailCrumbs) {
+      var controller = this.controllerFor('yarn-component-instances');
+      controller.setProperties({appId: appId, componentName: componentName, serviceName: serviceName});
+      controller.updateBreadcrumbs(appId, serviceName, componentName, tailCrumbs);
+    }
+  }
+});

+ 44 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instances/configs.js

@@ -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.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  model(params, transition) {
+    var componentName = params.component_name;
+    transition.send('updateBreadcrumbs', params.appid, params.service, componentName, [{text: 'Configurations'}]);
+    return Ember.RSVP.hash({
+      appId: params.appid,
+      serviceName: params.service,
+      componentName: componentName,
+      configs: this.store.query('yarn-service-component', {appId: params.appid}).then(function(components) {
+        if (components && components.findBy('name', componentName)) {
+          return components.findBy('name', componentName).get('configs');
+        }
+        return [];
+      }, function() {
+        return [];
+      })
+    });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-service-component');
+  }
+});

+ 53 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-component-instances/info.js

@@ -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.
+ */
+
+import Ember from 'ember';
+import AbstractRoute from '../abstract';
+
+export default AbstractRoute.extend({
+  model(params, transition) {
+    var componentName = params.component_name;
+    transition.send('updateBreadcrumbs', params.appid, params.service, componentName);
+    return Ember.RSVP.hash({
+      appId: params.appid,
+      serviceName: params.service,
+      componentName: componentName,
+      instances: this.store.query('yarn-component-instance', {appId: params.appid}).then(function(instances) {
+        if (instances && instances.filterBy('component', componentName)) {
+          return instances.filterBy('component', componentName);
+        }
+        return [];
+      }, function() {
+        return [];
+      }),
+      metrics: this.store.query('yarn-service-component', {appId: params.appid}).then(function(components) {
+        if (components && components.findBy('name', componentName)) {
+          return components.findBy('name', componentName).get('metrics');
+        }
+        return null;
+      }, function() {
+        return null;
+      })
+    });
+  },
+
+  unloadAll() {
+    this.store.unloadAll('yarn-service-component');
+    this.store.unloadAll('yarn-component-instance');
+  }
+});

+ 72 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-component-instance.js

@@ -0,0 +1,72 @@
+/**
+ * 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';
+
+export default DS.JSONAPISerializer.extend({
+  internalNormalizeSingleResponse(store, primaryModelClass, payload) {
+    var info = payload.info;
+
+    var fixedPayload = {
+      id: 'yarn_component_instance_' + payload.id,
+      type: primaryModelClass.modelName,
+      attributes: {
+        containerId: payload.id,
+        component: info.COMPONENT_NAME,
+        instanceName: info.COMPONENT_NAME + '_' + payload.instanceId,
+        state: info.STATE,
+        createdTimestamp: payload.createdtime,
+        startedTimestamp: info.LAUNCH_TIME,
+        host: info.HOSTNAME,
+        node: info.BARE_HOST,
+        hostUrl: 'N/A',
+        ipAddr: info.IP,
+        exitStatusCode: info.EXIT_STATUS_CODE
+      }
+    };
+
+    return fixedPayload;
+  },
+
+  normalizeArrayResponse(store, primaryModelClass, payload/*, id, requestType*/) {
+    var normalizedResponse = {data: []};
+    var instanceUid = {};
+
+    if (payload && Array.isArray(payload)) {
+      this.sortPayloadByCreatedTimeAscending(payload);
+
+      payload.forEach(function(container) {
+        let componentName = container.info.COMPONENT_NAME;
+        if (!instanceUid[componentName]) {
+          instanceUid[componentName] = 0;
+        }
+        container.instanceId = ++instanceUid[componentName];
+        var pl = this.internalNormalizeSingleResponse(store, primaryModelClass, container);
+        normalizedResponse.data.push(pl);
+      }.bind(this));
+    }
+
+    return normalizedResponse;
+  },
+
+  sortPayloadByCreatedTimeAscending(payload) {
+    payload.sort(function(inst1, inst2) {
+      return inst1.createdtime - inst2.createdtime;
+    });
+  }
+});

+ 77 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-service-component.js

@@ -0,0 +1,77 @@
+/**
+ * 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.JSONAPISerializer.extend({
+  internalNormalizeSingleResponse(store, primaryModelClass, payload) {
+    var info = payload.info;
+    var configs = payload.configs;
+    var metrics = payload.metrics;
+    var newConfigs = Ember.A();
+    var newMetrics = Ember.Object.create();
+
+    if (configs) {
+      for (let conf in configs) {
+        let confObj = Ember.Object.create({
+          name: conf,
+          value: configs[conf] || 'N/A'
+        });
+        newConfigs.push(confObj);
+      }
+    }
+
+    if (metrics) {
+      metrics.forEach(function(metric) {
+        let val = metric.values[Object.keys(metric.values)[0]];
+        newMetrics.set(metric.id, ((val !== undefined)? val : 'N/A'));
+      });
+    }
+
+    var fixedPayload = {
+      id: 'yarn_service_component_' + payload.id,
+      type: primaryModelClass.modelName,
+      attributes: {
+        name: payload.id,
+        vcores: info.RESOURCE_CPU,
+        memory: info.RESOURCE_MEMORY,
+        priority: 'N/A',
+        instances: 'N/A',
+        createdTimestamp: payload.createdtime,
+        configs: newConfigs,
+        metrics: newMetrics
+      }
+    };
+
+    return fixedPayload;
+  },
+
+  normalizeArrayResponse(store, primaryModelClass, payload/*, id, requestType*/) {
+    var normalizedResponse = {data: []};
+
+    if (payload && Array.isArray(payload)) {
+      payload.forEach(function(component) {
+        var pl = this.internalNormalizeSingleResponse(store, primaryModelClass, component);
+        normalizedResponse.data.push(pl);
+      }.bind(this));
+    }
+
+    return normalizedResponse;
+  }
+});

+ 87 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/serializers/yarn-service-info.js

@@ -0,0 +1,87 @@
+/**
+ * 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.JSONAPISerializer.extend({
+  internalNormalizeSingleResponse(store, primaryModelClass, payload) {
+    var info = payload.info;
+    var configs = payload.configs;
+    var quicklinks = info.QUICK_LINKS;
+    var metrics = payload.metrics;
+    var newConfigs = Ember.A();
+    var newQuicklinks = Ember.A();
+    var newMetrics = Ember.Object.create();
+
+    if (configs) {
+      for (let conf in configs) {
+        let confObj = Ember.Object.create({
+          name: conf,
+          value: configs[conf] || 'N/A'
+        });
+        newConfigs.push(confObj);
+      }
+    }
+
+    if (quicklinks) {
+      for (let link in quicklinks) {
+        let linkObj = Ember.Object.create({
+          name: link,
+          value: quicklinks[link] || 'N/A'
+        });
+        newQuicklinks.push(linkObj);
+      }
+    }
+
+    if (metrics) {
+      metrics.forEach(function(metric) {
+        let val = metric.values[Object.keys(metric.values)[0]];
+        newMetrics.set(metric.id, ((val !== undefined)? val : 'N/A'));
+      });
+    }
+
+    var fixedPayload = {
+      id: 'yarn_service_info_' + payload.id,
+      type: primaryModelClass.modelName,
+      attributes: {
+        name: info.NAME,
+        appId: payload.id,
+        state: info.STATE,
+        createdTimestamp: payload.createdtime,
+        launchTimestamp: info.LAUNCH_TIME,
+        quicklinks: newQuicklinks,
+        configs: newConfigs,
+        metrics: newMetrics
+      }
+    };
+
+    return fixedPayload;
+  },
+
+  normalizeSingleResponse(store, primaryModelClass, payload/*, id, requestType*/) {
+    var normalizedResponse = {data: []};
+
+    if (payload && payload[0]) {
+      var pl = this.internalNormalizeSingleResponse(store, primaryModelClass, payload[0]);
+      normalizedResponse.data = pl;
+    }
+
+    return normalizedResponse;
+  }
+});

+ 13 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css

@@ -544,7 +544,7 @@ table.table-custom-action > thead > tr > th:last-of-type, table.table-custom-act
 
 table.table-custom-bordered {
   border: 1px solid #ddd !important;
-  border-radius: 3px !important;
+  border-radius: 4px !important;
 }
 
 table.table-custom-bordered > thead > tr > th, table.table-custom-bordered > tbody > tr > td {
@@ -556,6 +556,18 @@ table.table-custom-striped > thead > tr, .table-custom-striped > tbody > tr:nth-
   background-color: #f9f9f9 !important;
 }
 
+table.table-custom-header > thead > tr > th {
+  background-color: #f5f5f5 !important;
+}
+
+table.table-radius-none {
+  border-radius: 0 !important;
+}
+
+table.table-border-none {
+  border: none !important;
+}
+
 .deploy-service label.required:after, .deploy-service-modal label.required:after {
   content: '*';
   color: #d9534f;

+ 37 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/confirm-dialog.hbs

@@ -0,0 +1,37 @@
+{{!
+ * 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.
+}}
+
+<div class="modal fade" tabindex="-1" role="dialog" id="{{dialogId}}">
+  <div class="modal-dialog" role="document">
+    <div class="modal-content" style="width: 500px;">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+          <span aria-hidden="true">&times;</span>
+        </button>
+        <h3 class="modal-title">{{title}}</h3>
+      </div>
+      <div class="modal-body">
+        {{message}}
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">No</button>
+        <button type="button" class="btn btn-primary" {{action "yesConfirmed"}}>Yes</button>
+      </div>
+    </div>
+  </div>
+</div>

+ 82 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/metrics-table.hbs

@@ -0,0 +1,82 @@
+{{!
+ * 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 metrics}}
+  <div class="row">
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <div class="panel-title">{{type}} Metrics: Success Information</div>
+      </div>
+      <div class="">
+        <table class="table table-hover table-custom-bordered table-custom-stripped table-radius-none table-border-none">
+          <thead>
+            <tr>
+              <th>Desired Containers</th>
+              <th>Running Containers</th>
+              <th>Completed Containers</th>
+              <th>Pending Containers</th>
+              <th>Surplus Containers</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>{{metrics.ContainersDesired}}</td>
+              <td>{{metrics.ContainersRunning}}</td>
+              <td>{{metrics.ContainersCompleted}}</td>
+              <td>{{metrics.ContainersPending}}</td>
+              <td>{{metrics.SurplusContainers}}</td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+    </div>
+  </div>
+  <div class="row">
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <div class="panel-title">{{type}} Metrics: Failure Information</div>
+      </div>
+      <div class="">
+        <table class="table table-hover table-custom-bordered table-custom-stripped table-radius-none table-border-none">
+          <thead>
+            <tr>
+              <th>Failed Containers</th>
+              <th>Containers Failed Since Last Threshold</th>
+              <th>Preempted Containers</th>
+              <th>Pending Anti-Affinity Containers</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>{{metrics.ContainersFailed}}</td>
+              <td>{{metrics.FailedSinceLastThreshold}}</td>
+              <td>{{metrics.ContainersPreempted}}</td>
+              <td>{{metrics.PendingAAContainers}}</td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+    </div>
+  </div>
+{{else}}
+  <div class="row">
+    <div class="panel panel-default">
+      <h4 class="text-center">No {{type}} metrics available!</h4>
+    </div>
+  </div>
+{{/if}}

+ 8 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app.hbs

@@ -42,6 +42,14 @@
               {{#link-to 'yarn-app.charts' tagName="li" class=(if (eq target.currentPath 'yarn-app.charts') "active")}}
                 {{#link-to 'yarn-app.charts' appId (query-params service=serviceName)}}Resource Usage{{/link-to}}
               {{/link-to}}
+              {{#if serviceName}}
+                {{#link-to 'yarn-app.components' tagName="li" class=(if (eq target.currentPath 'yarn-app.components') "active")}}
+                  {{#link-to 'yarn-app.components' appId (query-params service=serviceName)}}Components{{/link-to}}
+                {{/link-to}}
+                {{#link-to 'yarn-app.configs' tagName="li" class=(if (eq target.currentPath 'yarn-app.configs') "active")}}
+                  {{#link-to 'yarn-app.configs' appId (query-params service=serviceName)}}Configurations &amp; Metrics{{/link-to}}
+                {{/link-to}}
+              {{/if}}
             </ul>
           </ul>
         </div>

+ 23 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app/components.hbs

@@ -0,0 +1,23 @@
+{{!
+ * 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.
+}}
+
+<div class="row">
+  <div class="col-md-12">
+    {{em-table columns=tableColumns rows=model.components}}
+  </div>
+</div>

+ 57 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app/configs.hbs

@@ -0,0 +1,57 @@
+{{!
+ * 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.
+}}
+
+<div class="col-md-12">
+  {{metrics-table metrics=model.metrics type="Service"}}
+</div>
+
+<div class="row">
+  {{#if model.configs}}
+    <div class="col-md-12">
+      <div class="panel panel-default">
+        <div class="panel-heading">
+          <div class="panel-title">Service Configurations</div>
+        </div>
+        <div class="">
+          <table class="table table-hover table-custom-bordered table-custom-stripped table-radius-none table-border-none">
+            <thead>
+              <tr>
+                <th>Name</th>
+                <th>Value</th>
+              </tr>
+            </thead>
+            <tbody>
+              {{#each model.configs as |config|}}
+                <tr>
+                  <td>{{config.name}}</td>
+                  <td>{{config.value}}</td>
+                </tr>
+              {{/each}}
+            </tbody>
+          </table>
+        </div>
+      </div>
+    </div>
+  {{else}}
+    <div class="col-md-12">
+      <div class="panel panel-default">
+        <h4 class="text-center">No service configurations available!</h4>
+      </div>
+    </div>
+  {{/if}}
+</div>

+ 85 - 26
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-app/info.hbs

@@ -22,11 +22,34 @@
   </div>
 </div>
 
+{{#if actionResponse}}
+  <div class="row">
+    <div class="col-md-12">
+      <div class="alert alert-dismissible {{if (eq actionResponse.type 'error') 'alert-danger' 'alert-success'}}" role="alert">
+        <button class="close" data-dismiss="alert" aria-label="Close" {{action "resetActionResponse"}}><span aria-hidden="true">&times;</span></button>
+        <strong>{{actionResponse.msg}}</strong>
+      </div>
+    </div>
+  </div>
+{{/if}}
+
+{{#if isLoading}}
+  <div class="panel panel-default service-action-mask">
+    <img src="assets/images/spinner.gif" alt="Loading...">
+  </div>
+{{/if}}
+
 <div class="row">
   <div class="col-md-12 container-fluid">
     <div class="panel panel-default">
       <div class="panel-heading">
         Basic Info
+        {{#if isRunningService}}
+          <div class="pull-right" style="display: inline-block; margin: -4px -10px 0 0;">
+            <button class="btn btn-sm btn-danger" disabled="{{if isLoading 'disabled'}}" {{action "showStopServiceConfirm"}}> Stop </button>
+            <button class="btn btn-sm btn-danger" disabled="{{if isLoading 'disabled'}}" {{action "showDeleteServiceConfirm"}}> Delete </button>
+          </div>
+        {{/if}}
       </div>
       <div class="x-scroll">
         <table class="display table table-striped table-bordered"
@@ -116,24 +139,25 @@
       <table class="display table table-striped table-bordered"
              cellspacing="0" width="100%">
         <thead>
-          <tr>
-            <th>Allocated Resource</th>
-            <th>Running Containers</th>
-            <th>Preempted Resource</th>
-            <th>Num Non-AM container preempted</th>
-            <th>Num AM container preempted</th>
-            <th>Aggregated Resource Usage</th>
-          </tr>
+        <tr>
+          <th>Allocated Resource</th>
+          <th>Running Containers</th>
+          <th>Preempted Resource</th>
+          <th>Num Non-AM container preempted</th>
+          <th>Num AM container preempted</th>
+          <th>Aggregated Resource Usage</th>
+        </tr>
         </thead>
+
         <tbody>
-          <tr>
-            <td>{{model.app.allocatedResource}}</td>
-            <td>{{model.app.runningContainersNumber}}</td>
-            <td>{{model.app.preemptedResource}}</td>
-            <td>{{model.app.numAMContainerPreempted}}</td>
-            <td>{{model.app.numAMContainerPreempted}}</td>
-            <td>{{model.app.aggregatedResourceUsage}}</td>
-          </tr>
+        <tr>
+          <td>{{model.app.allocatedResource}}</td>
+          <td>{{model.app.runningContainersNumber}}</td>
+          <td>{{model.app.preemptedResource}}</td>
+          <td>{{model.app.numAMContainerPreempted}}</td>
+          <td>{{model.app.numAMContainerPreempted}}</td>
+          <td>{{model.app.aggregatedResourceUsage}}</td>
+        </tr>
         </tbody>
       </table>
     </div>
@@ -148,20 +172,55 @@
       <table class="display table table-striped table-bordered"
              cellspacing="0" width="100%">
         <thead>
-          <tr>
-            <th>Master Container Log</th>
-            <th>Master Node</th>
-            <th>Master Node Label Expression</th>
-          </tr>
+        <tr>
+          <th>Master Container Log</th>
+          <th>Master Node</th>
+          <th>Master Node Label Expression</th>
+        </tr>
         </thead>
+
         <tbody>
-          <tr>
-            <td><a href="{{model.app.amContainerLogs}}" target="_blank">Link</a></td>
-            <td><a href="{{amHostHttpAddressFormatted}}" target="_blank">Link</a></td>
-            <td>{{model.app.amNodeLabelExpression}}</td>
-          </tr>
+        <tr>
+          <td><a href="{{model.app.amContainerLogs}}" target="_blank">Link</a></td>
+          <td><a href="{{amHostHttpAddressFormatted}}" target="_blank">Link</a></td>
+          <td>{{model.app.amNodeLabelExpression}}</td>
+        </tr>
         </tbody>
       </table>
     </div>
   </div>
+
+  {{#if model.serviceName}}
+    <div class="col-md-6 container-fluid">
+      <div class="panel panel-default">
+        <div class="panel-heading">Quick Links</div>
+        <table class="display table table-striped table-bordered">
+          <tbody>
+            {{#each model.quicklinks as |link|}}
+              <tr>
+                <td>{{link.name}}</td>
+                <td><a href="{{link.value}}" target="_blank">{{link.value}}</a></td>
+              </tr>
+            {{else}}
+              <tr class="align-center">
+                <td colspan="2">No quicklinks available!</td>
+              </tr>
+            {{/each}}
+          </tbody>
+        </table>
+      </div>
+    </div>
+  {{/if}}
 </div>
+
+{{confirm-dialog
+  dialogId="stopServiceConfirmDialog"
+  message=(concat 'Are you sure you want to stop service "' model.serviceName '" ?')
+  action="stopService"
+}}
+
+{{confirm-dialog
+  dialogId="deleteServiceConfirmDialog"
+  message=(concat 'Are you sure you want to delete service "' model.serviceName '" ?')
+  action="deleteService"
+}}

+ 43 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instance.hbs

@@ -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.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs}}
+
+<div class="col-md-12 container-fluid">
+  <div class="row">
+
+    <div class="col-md-2 container-fluid">
+      <div class="panel panel-default">
+        <div class="panel-heading">
+          Component
+        </div>
+        <div class="panel-body">
+          <ul class="nav nav-pills nav-stacked collapse in">
+            {{#link-to 'yarn-component-instance.info' tagName="li" class=(if (eq target.currentPath 'yarn-component-instance.info') "active")}}
+              {{#link-to 'yarn-component-instance.info' componentName instanceName (query-params service=serviceName appid=appId)}}Information{{/link-to}}
+            {{/link-to}}
+          </ul>
+        </div>
+      </div>
+    </div>
+
+    <div class="col-md-10 container-fluid">
+      {{outlet}}
+    </div>
+  </div>
+</div>

+ 81 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instance/info.hbs

@@ -0,0 +1,81 @@
+{{!
+ * 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.
+}}
+
+<div class="row">
+  {{#if model.container}}
+  <div class="panel panel-default">
+    <div class="panel-heading">
+      <div class="panel-title">Component Information</div>
+    </div>
+    <div class="">
+      <table class="table table-striped table-bordered table-hover">
+        <tbody>
+          <tr>
+            <td>Component Name</td>
+            <td>{{check-availability model.container.instanceName}}</td>
+          </tr>
+          <tr>
+            <td>Component Group</td>
+            <td>{{check-availability model.container.component}}</td>
+          </tr>
+          <tr>
+            <td>Current Container Id</td>
+            <td>{{check-availability model.container.containerId}}</td>
+          </tr>
+          <tr>
+            <td>State</td>
+            <td>{{check-availability model.container.state}}</td>
+          </tr>
+          <tr>
+            <td>Created Time</td>
+            <td>{{check-availability model.container.createdDate}}</td>
+          </tr>
+          <tr>
+            <td>Started Time</td>
+            <td>{{check-availability model.container.startedDate}}</td>
+          </tr>
+          <tr>
+            <td>Host</td>
+            <td>{{check-availability model.container.host}}</td>
+          </tr>
+          <tr>
+            <td>Host URL</td>
+            <td>{{check-availability model.container.hostUrl}}</td>
+          </tr>
+          <tr>
+            <td>Node</td>
+            <td>{{check-availability model.container.node}}</td>
+          </tr>
+          <tr>
+            <td>IP Address</td>
+            <td>{{check-availability model.container.ip}}</td>
+          </tr>
+          <tr>
+            <td>Exit Status Code</td>
+            <td>{{check-availability model.container.exitStatusCode}}</td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+  </div>
+  {{else}}
+  <div class="panel panel-default">
+    <h4 class="text-center">No component information available!</h4>
+  </div>
+  {{/if}}
+</div>

+ 46 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instances.hbs

@@ -0,0 +1,46 @@
+{{!
+ * 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}}
+
+<div class="col-md-12 container-fluid">
+  <div class="row">
+
+    <div class="col-md-2 container-fluid">
+      <div class="panel panel-default">
+        <div class="panel-heading">
+          Component
+        </div>
+        <div class="panel-body">
+          <ul class="nav nav-pills nav-stacked collapse in">
+            {{#link-to 'yarn-component-instances.info' tagName="li" class=(if (eq target.currentPath 'yarn-component-instances.info') "active")}}
+              {{#link-to 'yarn-component-instances.info' componentName (query-params service=serviceName appid=appId)}}Information{{/link-to}}
+            {{/link-to}}
+            {{#link-to 'yarn-component-instances.configs' tagName="li" class=(if (eq target.currentPath 'yarn-component-instances.configs') "active")}}
+              {{#link-to 'yarn-component-instances.configs' componentName (query-params service=serviceName appid=appId)}}Configurations{{/link-to}}
+            {{/link-to}}
+          </ul>
+        </div>
+      </div>
+    </div>
+
+    <div class="col-md-10 container-fluid">
+      {{outlet}}
+    </div>
+  </div>
+</div>

+ 53 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instances/configs.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.
+}}
+
+<div class="row">
+  {{#if model.configs}}
+    <div class="col-md-12">
+      <div class="panel panel-default">
+        <div class="panel-heading">
+          <div class="panel-title">Component Configurations</div>
+        </div>
+        <div class="">
+          <table class="table table-hover table-custom-bordered table-custom-stripped table-radius-none table-border-none">
+            <thead>
+              <tr>
+                <th>Name</th>
+                <th>Value</th>
+              </tr>
+            </thead>
+            <tbody>
+              {{#each model.configs as |config|}}
+                <tr>
+                  <td>{{config.name}}</td>
+                  <td>{{config.value}}</td>
+                </tr>
+              {{/each}}
+            </tbody>
+          </table>
+        </div>
+      </div>
+    </div>
+  {{else}}
+    <div class="col-md-12">
+      <div class="panel panel-default">
+        <h4 class="text-center">No component configurations available!</h4>
+      </div>
+    </div>
+  {{/if}}
+</div>

+ 28 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instances/info.hbs

@@ -0,0 +1,28 @@
+{{!
+ * 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.
+}}
+
+<div class="row">
+  <div class="col-md-12">
+    <h3>Active Components: {{model.componentName}}</h3>
+    {{em-table columns=tableColumns rows=model.instances}}
+  </div>
+</div>
+
+<div class="col-md-12">
+  {{metrics-table metrics=model.metrics type="Component"}}
+</div>

+ 23 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-component-instances/loading.hbs

@@ -0,0 +1,23 @@
+{{!
+ * 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.
+}}
+
+<div class="col-md-12 container-fluid">
+  <div class="loading-mask">
+    <img src="assets/images/spinner.gif" alt="Loading...">
+  </div>
+</div>

+ 1 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js

@@ -26,9 +26,9 @@ module.exports = { // YARN UI App configurations
     },
     namespaces: {
       timeline: 'ws/v1/applicationhistory',
+      timelineService: 'ws/v2/timeline/apps',
       cluster: 'ws/v1/cluster',
       metrics: 'ws/v1/cluster/metrics',
-      timelineService: 'ws/v2/timeline/apps',
       timelineV2: 'ws/v2/timeline',
       dashService: 'services/v1/applications',
       node: '{nodeAddress}/ws/v1/node'

+ 43 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/confirm-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('confirm-dialog', 'Integration | Component | confirm 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`{{confirm-dialog}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#confirm-dialog}}
+      template block text
+    {{/confirm-dialog}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

+ 43 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/metrics-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('metrics-table', 'Integration | Component | metrics 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`{{metrics-table}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#metrics-table}}
+      template block text
+    {{/metrics-table}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-component-instance-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-component-instance', 'Unit | Adapter | yarn component instance', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-service-component-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-service-component', 'Unit | Adapter | yarn service component', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-service-info-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-service-info', 'Unit | Adapter | yarn service info', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app/components-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-app/components', 'Unit | Controller | yarn app/components', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-app/configs-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-app/configs', 'Unit | Controller | yarn app/configs', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instance-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-component-instance', 'Unit | Controller | yarn component instance', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instance/info-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-component-instance/info', 'Unit | Controller | yarn component instance/info', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instances-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-component-instances', 'Unit | Controller | yarn component instances', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instances/configs-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-component-instances/configs', 'Unit | Controller | yarn component instances/configs', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-component-instances/info-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-component-instances/info', 'Unit | Controller | yarn component instances/info', {
+  // 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);
+});

+ 28 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/helpers/check-availability-test.js

@@ -0,0 +1,28 @@
+/**
+ * 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 { checkAvailability } from '../../../helpers/check-availability';
+import { module, test } from 'qunit';
+
+module('Unit | Helper | check availability');
+
+// Replace this with your real tests.
+test('it works', function(assert) {
+  let result = checkAvailability(42);
+  assert.ok(result);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-component-instance-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-component-instance', 'Unit | Model | yarn component instance', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-service-component-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-service-component', 'Unit | Model | yarn service component', {
+  // 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);
+});

+ 30 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-service-info-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-service-info', 'Unit | Model | yarn service info', {
+  // 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);
+});

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-app/components-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-app/components', 'Unit | Route | yarn app/components', {
+  // 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);
+});

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-app/configs-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-app/configs', 'Unit | Route | yarn app/configs', {
+  // 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);
+});

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instance-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-component-instance', 'Unit | Route | yarn component instance', {
+  // 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);
+});

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instance/info-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-component-instance/info', 'Unit | Route | yarn component instance/info', {
+  // 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);
+});

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instances-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-component-instances', 'Unit | Route | yarn component instances', {
+  // 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);
+});

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instances/configs-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-component-instances/configs', 'Unit | Route | yarn component instances/configs', {
+  // 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);
+});

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-component-instances/info-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-component-instances/info', 'Unit | Route | yarn component instances/info', {
+  // 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);
+});

+ 33 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-component-instance-test.js

@@ -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.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('yarn-component-instance', 'Unit | Serializer | yarn component instance', {
+  // Specify the other units that are required for this test.
+  needs: ['serializer:yarn-component-instance']
+});
+
+// Replace this with your real tests.
+test('it serializes records', function(assert) {
+  let record = this.subject();
+
+  let serializedRecord = record.serialize();
+
+  assert.ok(serializedRecord);
+});

+ 33 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-service-component-test.js

@@ -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.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('yarn-service-component', 'Unit | Serializer | yarn service component', {
+  // Specify the other units that are required for this test.
+  needs: ['serializer:yarn-service-component']
+});
+
+// Replace this with your real tests.
+test('it serializes records', function(assert) {
+  let record = this.subject();
+
+  let serializedRecord = record.serialize();
+
+  assert.ok(serializedRecord);
+});

+ 33 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/serializers/yarn-service-info-test.js

@@ -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.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('yarn-service-info', 'Unit | Serializer | yarn service info', {
+  // Specify the other units that are required for this test.
+  needs: ['serializer:yarn-service-info']
+});
+
+// Replace this with your real tests.
+test('it serializes records', function(assert) {
+  let record = this.subject();
+
+  let serializedRecord = record.serialize();
+
+  assert.ok(serializedRecord);
+});