You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by su...@apache.org on 2017/05/03 07:01:41 UTC

[1/2] hadoop git commit: YARN-6419. Support to launch new native-service from new YARN UI. Contributed by Akhil PB.

Repository: hadoop
Updated Branches:
  refs/heads/yarn-native-services d23a97d4e -> e2384023b


http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/upload-config.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/upload-config.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/upload-config.hbs
new file mode 100644
index 0000000..045fb0f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/upload-config.hbs
@@ -0,0 +1,44 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+<div class="modal fade" tabindex="-1" role="dialog" id="{{dialogId}}">
+  <div class="modal-dialog" role="document">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+        <h4 class="modal-title bold-text">{{title}}</h4>
+      </div>
+      <div class="modal-body">
+        <div class="form-group">
+          {{textarea class="form-control" rows="20" cols="100" value=configJson placeholder="JSON Configuration Here..."}}
+        </div>
+        {{#if isParseError}}
+          <div class="panel panel-default">
+            <div class="panel-body bg-danger">
+              <strong>{{parseErrorMsg}}</strong>
+            </div>
+          </div>
+        {{/if}}
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+        <button type="button" class="btn btn-primary" {{action "uploadConfig"}} disabled={{unless isValidConfigJson "disabled"}}>Upload</button>
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs
index 7aade00..e51916a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps.hbs
@@ -83,4 +83,4 @@
       </div>
     </div>
   </div>
-</div>
\ No newline at end of file
+</div>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs
deleted file mode 100644
index 7556908..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-apps/services.hbs
+++ /dev/null
@@ -1,25 +0,0 @@
-{{!--
-  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 model.apps}}
-  {{em-table columns=columns rows=model.apps}}
-{{else}}
-  <h4 align="center">Could not find any applications from this cluster</h4>
-{{/if}}
-
-{{outlet}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs
new file mode 100644
index 0000000..98bc917
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-deploy-service.hbs
@@ -0,0 +1,33 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+{{breadcrumb-bar breadcrumbs=breadcrumbs hideRefresh=true}}
+
+<div class="col-md-12 container-fluid">
+  <div class="row">
+    {{deploy-service
+      savedStandardTemplates=savedStandardTemplates
+      savedJsonTemplates=savedJsonTemplates
+      serviceDef=model
+      serviceResp=serviceResponse
+      isLoading=isLoading
+      deployServiceDef="deployServiceDef"
+      deployServiceJson="deployServiceJson"
+    }}
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs
index 649834a..8e3597c 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/yarn-services.hbs
@@ -75,6 +75,10 @@
             </div>
           </div>
         </div>
+
+        <div class="col-lg-4 container-fluid">
+          <a class="btn btn-primary pull-right" href="#/yarn-deploy-service">New Service</a>
+        </div>
       </div>
       {{#if model.apps}}
         {{em-table columns=serviceColumns rows=model.apps definition=tableDefinition}}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/info-seeder.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/info-seeder.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/info-seeder.js
new file mode 100644
index 0000000..d63b3c5
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/utils/info-seeder.js
@@ -0,0 +1,26 @@
+/**
+ * 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.
+ */
+
+export default {
+  serviceName: "A unique application name",
+  queueName: "The YARN queue that this application should be submitted to",
+  lifetime: "Life time (in seconds) of the application from the time it reaches the STARTED state (after which it is automatically destroyed by YARN). For unlimited lifetime do not set a lifetime value.",
+  components: "One or more components of the application. If the application is HBase say, then the component can be a simple role like master or regionserver. If the application is a complex business webapp then a component can be other applications say Kafka or Storm. Thereby it opens up the support for complex and nested applications.",
+  configurations: "Set of configuration properties that can be injected into the application components via envs, files and custom pluggable helper docker containers. Files of several standard formats like xml, properties, json, yaml and templates will be supported.",
+  fileConfigs: "Set of file configurations that needs to be created and made available as a volume in an application component container."
+};

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env
index 04577c9..a795fc5 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/configs.env
@@ -40,6 +40,13 @@ ENV = {
      */
       //rmWebAddress: "localhost:8088",
 
+      /*
+       * Dash server web interface can be configured below.
+       * By default dash web address is set as localhost:9191, uncomment and change
+       * the following value for pointing to a different address.
+       */
+      //dashWebAddress: "localhost:9191",
+
     /*
      * Protocol scheme. It can be "http:" or "https:". By default, http is used.
      */

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js
index 70d4ebc..fc279d4 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/config/default-config.js
@@ -21,12 +21,14 @@ module.exports = { // Yarn UI App configurations
       localBaseAddress: "",
       timelineWebAddress: "localhost:8188",
       rmWebAddress: "localhost:8088",
+      dashWebAddress: "localhost:9191",
       protocolScheme: "http:"
     },
     namespaces: {
       timeline: 'ws/v1/applicationhistory',
       cluster: 'ws/v1/cluster',
       metrics: 'ws/v1/cluster/metrics',
+      dashService: 'services/v1/applications',
       node: '{nodeAddress}/ws/v1/node'
     },
 };

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js
new file mode 100644
index 0000000..ba855a7
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/deploy-service-test.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('deploy-service', 'Integration | Component | deploy service', {
+  integration: true
+});
+
+test('it renders', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{deploy-service}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#deploy-service}}
+      template block text
+    {{/deploy-service}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/fileconfig-viewer-dialog-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/fileconfig-viewer-dialog-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/fileconfig-viewer-dialog-test.js
new file mode 100644
index 0000000..f99e08f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/fileconfig-viewer-dialog-test.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('fileconfig-viewer-dialog', 'Integration | Component | fileconfig viewer dialog', {
+  integration: true
+});
+
+test('it renders', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{fileconfig-viewer-dialog}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#fileconfig-viewer-dialog}}
+      template block text
+    {{/fileconfig-viewer-dialog}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/info-tooltip-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/info-tooltip-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/info-tooltip-test.js
new file mode 100644
index 0000000..7b0c1a1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/info-tooltip-test.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('info-tooltip', 'Integration | Component | info tooltip', {
+  integration: true
+});
+
+test('it renders', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{info-tooltip}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#info-tooltip}}
+      template block text
+    {{/info-tooltip}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-component-table-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-component-table-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-component-table-test.js
new file mode 100644
index 0000000..3ea27a5
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-component-table-test.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('service-component-table', 'Integration | Component | service component table', {
+  integration: true
+});
+
+test('it renders', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{service-component-table}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#service-component-table}}
+      template block text
+    {{/service-component-table}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-config-table-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-config-table-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-config-table-test.js
new file mode 100644
index 0000000..39f269a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-config-table-test.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('service-config-table', 'Integration | Component | service config table', {
+  integration: true
+});
+
+test('it renders', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{service-config-table}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#service-config-table}}
+      template block text
+    {{/service-config-table}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-fileconfig-table-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-fileconfig-table-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-fileconfig-table-test.js
new file mode 100644
index 0000000..a486fa0
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/service-fileconfig-table-test.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForComponent, test } from 'ember-qunit';
+import hbs from 'htmlbars-inline-precompile';
+
+moduleForComponent('service-fileconfig-table', 'Integration | Component | service fileconfig table', {
+  integration: true
+});
+
+test('it renders', function(assert) {
+
+  // Set any properties with this.set('myProperty', 'value');
+  // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL +
+
+  this.render(hbs`{{service-fileconfig-table}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#service-fileconfig-table}}
+      template block text
+    {{/service-fileconfig-table}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/upload-config-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/upload-config-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/upload-config-test.js
new file mode 100644
index 0000000..64fdf4a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/integration/components/upload-config-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('upload-config', 'Integration | Component | upload config', {
+  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`{{upload-config}}`);
+
+  assert.equal(this.$().text().trim(), '');
+
+  // Template block usage:" + EOL +
+  this.render(hbs`
+    {{#upload-config}}
+      template block text
+    {{/upload-config}}
+  `);
+
+  assert.equal(this.$().text().trim(), 'template block text');
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js
new file mode 100644
index 0000000..ea12bc5
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/adapters/yarn-servicedef-test.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('adapter:yarn-servicedef', 'Unit | Adapter | yarn servicedef', {
+  // Specify the other units that are required for this test.
+  // needs: ['serializer:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+  let adapter = this.subject();
+  assert.ok(adapter);
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-apps/services-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-apps/services-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-apps/services-test.js
deleted file mode 100644
index d0a1f85..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-apps/services-test.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * 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-apps/services', 'Unit | Controller | yarn apps/services', {
-  // 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);
-});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js
new file mode 100644
index 0000000..c3918f4
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/controllers/yarn-deploy-service-test.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('controller:yarn-deploy-service', 'Unit | Controller | yarn deploy service', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+// Replace this with your real tests.
+test('it exists', function(assert) {
+  let controller = this.subject();
+  assert.ok(controller);
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js
new file mode 100644
index 0000000..141a94b
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/models/yarn-servicedef-test.js
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleForModel, test } from 'ember-qunit';
+
+moduleForModel('yarn-servicedef', 'Unit | Model | yarn servicedef', {
+  // Specify the other units that are required for this test.
+  needs: []
+});
+
+test('it exists', function(assert) {
+  let model = this.subject();
+  // let store = this.store();
+  assert.ok(!!model);
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js
new file mode 100644
index 0000000..4e2dcf1
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/tests/unit/routes/yarn-deploy-service-test.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { moduleFor, test } from 'ember-qunit';
+
+moduleFor('route:yarn-deploy-service', 'Unit | Route | yarn deploy service', {
+  // Specify the other units that are required for this test.
+  // needs: ['controller:foo']
+});
+
+test('it exists', function(assert) {
+  let route = this.subject();
+  assert.ok(route);
+});


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org


[2/2] hadoop git commit: YARN-6419. Support to launch new native-service from new YARN UI. Contributed by Akhil PB.

Posted by su...@apache.org.
YARN-6419. Support to launch new native-service from new YARN UI. Contributed by Akhil PB.


Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo
Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/e2384023
Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/e2384023
Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/e2384023

Branch: refs/heads/yarn-native-services
Commit: e2384023b1ee4006f740f9b71f26a870fb2ceedd
Parents: d23a97d
Author: Sunil G <su...@apache.org>
Authored: Wed May 3 12:30:55 2017 +0530
Committer: Sunil G <su...@apache.org>
Committed: Wed May 3 12:30:55 2017 +0530

----------------------------------------------------------------------
 .../main/webapp/app/adapters/restabstract.js    |  50 ++++
 .../main/webapp/app/adapters/yarn-servicedef.js |  31 +++
 .../webapp/app/components/breadcrumb-bar.js     |   1 +
 .../webapp/app/components/deploy-service.js     | 167 +++++++++++
 .../app/components/fileconfig-viewer-dialog.js  |  36 +++
 .../main/webapp/app/components/info-tooltip.js  |  44 +++
 .../app/components/service-component-table.js   |  56 ++++
 .../app/components/service-config-table.js      |  89 ++++++
 .../app/components/service-fileconfig-table.js  | 112 ++++++++
 .../main/webapp/app/components/upload-config.js |  54 ++++
 .../app/controllers/yarn-apps/services.js       |  22 --
 .../app/controllers/yarn-deploy-service.js      |  69 +++++
 .../main/webapp/app/models/yarn-servicedef.js   | 278 +++++++++++++++++++
 .../src/main/webapp/app/router.js               |   2 +-
 .../webapp/app/routes/yarn-apps/services.js     |  33 ---
 .../webapp/app/routes/yarn-deploy-service.js    |  27 ++
 .../src/main/webapp/app/services/hosts.js       |   4 +
 .../src/main/webapp/app/styles/app.css          | 147 ++++++++++
 .../main/webapp/app/templates/application.hbs   |   4 +-
 .../app/templates/components/breadcrumb-bar.hbs |   4 +-
 .../app/templates/components/deploy-service.hbs | 157 +++++++++++
 .../components/fileconfig-viewer-dialog.hbs     |  53 ++++
 .../app/templates/components/info-tooltip.hbs   |  20 ++
 .../components/service-component-table.hbs      | 113 ++++++++
 .../components/service-config-table.hbs         | 130 +++++++++
 .../components/service-fileconfig-table.hbs     | 152 ++++++++++
 .../app/templates/components/upload-config.hbs  |  44 +++
 .../src/main/webapp/app/templates/yarn-apps.hbs |   2 +-
 .../webapp/app/templates/yarn-apps/services.hbs |  25 --
 .../app/templates/yarn-deploy-service.hbs       |  33 +++
 .../main/webapp/app/templates/yarn-services.hbs |   4 +
 .../src/main/webapp/app/utils/info-seeder.js    |  26 ++
 .../src/main/webapp/config/configs.env          |   7 +
 .../src/main/webapp/config/default-config.js    |   2 +
 .../components/deploy-service-test.js           |  43 +++
 .../components/fileconfig-viewer-dialog-test.js |  43 +++
 .../integration/components/info-tooltip-test.js |  43 +++
 .../components/service-component-table-test.js  |  43 +++
 .../components/service-config-table-test.js     |  43 +++
 .../components/service-fileconfig-table-test.js |  43 +++
 .../components/upload-config-test.js            |  43 +++
 .../tests/unit/adapters/yarn-servicedef-test.js |  30 ++
 .../unit/controllers/yarn-apps/services-test.js |  30 --
 .../controllers/yarn-deploy-service-test.js     |  30 ++
 .../tests/unit/models/yarn-servicedef-test.js   |  30 ++
 .../unit/routes/yarn-deploy-service-test.js     |  29 ++
 46 files changed, 2334 insertions(+), 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/restabstract.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/restabstract.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/restabstract.js
new file mode 100644
index 0000000..df409d6
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/restabstract.js
@@ -0,0 +1,50 @@
+/**
+ * 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.RESTAdapter.extend({
+  address: null, //Must be set by inheriting classes
+  restNameSpace: null, //Must be set by inheriting classes
+  serverName: null, //Must be set by inheriting classes
+
+  headers: {
+    Accept: 'application/json'
+  },
+
+  host: Ember.computed("address", function() {
+    var address = this.get("address");
+    return this.get(`hosts.${address}`);
+  }),
+
+  namespace: Ember.computed("restNameSpace", function() {
+    var nameSpace = this.get("restNameSpace");
+    return this.get(`env.app.namespaces.${nameSpace}`);
+  }),
+
+  ajax(url, method, options) {
+    options = options || {};
+    options.crossDomain = true;
+    options.xhrFields = {
+      withCredentials: true
+    };
+    options.targetServer = this.get('serverName');
+    return this._super(url, method, options);
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.js
new file mode 100644
index 0000000..c362f5e
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/adapters/yarn-servicedef.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';
+import RESTAbstractAdapter from './restabstract';
+
+export default RESTAbstractAdapter.extend({
+  address: "dashWebAddress",
+  restNameSpace: "dashService",
+  serverName: "DASH",
+
+  deployService(request) {
+    var url = this.buildURL();
+    return this.ajax(url, "POST", {data: request});
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js
index 44edb8e..b8d974a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/breadcrumb-bar.js
@@ -21,6 +21,7 @@ import Ember from 'ember';
 export default Ember.Component.extend({
 
   breadcrumbs: null,
+  hideRefresh: false,
 
   actions:{
     refresh: function () {

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js
new file mode 100644
index 0000000..90e10e5
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/deploy-service.js
@@ -0,0 +1,167 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  viewType: 'standard',
+  savedStandardTemplates: null,
+  savedJsonTemplates: null,
+  savedTemplateName: '',
+  serviceDef: null,
+  customServiceDef: '',
+  serviceResp: null,
+  isLoading: false,
+
+  actions: {
+    showSaveTemplateModal() {
+      this.$('#saveListModal').modal('show');
+    },
+
+    deployService() {
+      this.set('serviceResp', null);
+      if (this.get('isStandardViewType')) {
+        this.sendAction("deployServiceDef", this.get('serviceDef'));
+      } else {
+        try {
+          var parsed = JSON.parse(this.get('customServiceDef'));
+          this.sendAction("deployServiceJson", parsed);
+        } catch (err) {
+          this.set('serviceResp', {type: 'error', message: 'Invalid JSON: ' + err.message});
+          throw err;
+        }
+      }
+    },
+
+    updateViewType(type) {
+      this.set('viewType', type);
+    },
+
+    addToSavedList() {
+      this.unselectAllSavedList();
+      if (this.get('isStandardViewType')) {
+        this.get('savedStandardTemplates').addObject({
+          name: this.get('savedTemplateName'),
+          defId: this.get('serviceDef.id'),
+          active: true
+        });
+        this.set('serviceDef.isCached', true);
+      } else {
+        this.get('savedJsonTemplates').addObject({
+          name: this.get('savedTemplateName'),
+          custom: this.get('customServiceDef'),
+          active: true
+        });
+      }
+      this.$('#saveListModal').modal('hide');
+      this.set('savedTemplateName', '');
+    },
+
+    updateServiceDef(def) {
+      this.selectActiveListItem(def);
+      if (this.get('isStandardViewType')) {
+        this.set('serviceDef', this.getStore().peekRecord('yarn-servicedef', def.defId));
+      } else {
+        this.set('customServiceDef', def.custom);
+      }
+    },
+
+    clearConfigs() {
+      this.unselectAllSavedList();
+      this.set('serviceResp', null);
+      if (this.get('isStandardViewType')) {
+        var oldDef = this.get('serviceDef');
+        var def = oldDef.createNewServiceDef();
+        this.set('serviceDef', def);
+        if (!oldDef.get('isCached')) {
+          oldDef.deleteRecord();
+        }
+      } else {
+        this.set('customServiceDef', '');
+      }
+    },
+
+    removeFromSavedList(list) {
+      if (list.active) {
+        this.send('clearConfigs');
+      }
+      if (this.get('isStandardViewType')) {
+        this.get('savedStandardTemplates').removeObject(list);
+      } else {
+        this.get('savedJsonTemplates').removeObject(list);
+      }
+    },
+
+    clearServiceResponse() {
+      this.set('serviceResp', null);
+    }
+  },
+
+  didInsertElement() {
+    var self = this;
+    self.$().find('.modal').on('shown.bs.modal', function() {
+      self.$().find('.modal.in').find('input.form-control:first').focus();
+    });
+  },
+
+  selectActiveListItem(item) {
+    this.unselectAllSavedList();
+    Ember.set(item, 'active', true);
+  },
+
+  unselectAllSavedList() {
+    this.get('getSavedList').forEach(function(item) {
+      Ember.set(item, 'active', false);
+    });
+  },
+
+  getSavedList: Ember.computed('viewType', function() {
+    if (this.get('isStandardViewType')) {
+      return this.get('savedStandardTemplates');
+    } else {
+      return this.get('savedJsonTemplates');
+    }
+  }),
+
+  getStore: function() {
+    return this.get('serviceDef.store');
+  },
+
+  isStandardViewType: Ember.computed.equal('viewType', 'standard'),
+
+  isCustomViewType: Ember.computed.equal('viewType', 'custom'),
+
+  isValidTemplateName: Ember.computed.notEmpty('savedTemplateName'),
+
+  isValidServiceDef: Ember.computed('serviceDef.name', 'serviceDef.queue', 'serviceDef.serviceComponents.[]', function () {
+    return this.get('serviceDef').isValidServiceDef();
+  }),
+
+  isValidCustomServiceDef: Ember.computed.notEmpty('customServiceDef'),
+
+  enableSaveOrDeployBtn: Ember.computed('isValidServiceDef', 'isValidCustomServiceDef', 'viewType', 'isLoading', function() {
+    if (this.get('isLoading')) {
+      return false;
+    }
+    if (this.get('isStandardViewType')) {
+      return this.get('isValidServiceDef');
+    } else {
+      return this.get('isValidCustomServiceDef');
+    }
+  })
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/fileconfig-viewer-dialog.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/fileconfig-viewer-dialog.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/fileconfig-viewer-dialog.js
new file mode 100644
index 0000000..d4912768
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/fileconfig-viewer-dialog.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  dialogId: "fileconfig_viewer_dialog",
+  title: "File Configuration Properties",
+  props: null,
+  customProps: Ember.computed('props', function() {
+    var custom = [];
+    var props = this.get('props');
+    for (var pro in props) {
+      custom.push({
+        name: pro,
+        value: props[pro]
+      });
+    }
+    return custom;
+  })
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/info-tooltip.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/info-tooltip.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/info-tooltip.js
new file mode 100644
index 0000000..605b611
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/info-tooltip.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 InfoSeeder from 'yarn-ui/utils/info-seeder';
+
+export default Ember.Component.extend({
+  classNames: ['tooltip', 'info-tooltip'],
+  elementId: 'info_tooltip_wrapper',
+
+  didInsertElement() {
+    var $tooltip = Ember.$('#info_tooltip_wrapper');
+    Ember.$('body').on('mouseenter', '.info-icon', function() {
+      var $elem = Ember.$(this);
+      var info = InfoSeeder[$elem.data('info')];
+      var offset = $elem.offset();
+      $tooltip.show();
+      $tooltip.find("#tooltip_content").text(info);
+      $tooltip.offset({top: offset.top + 20, left: offset.left - 10});
+    }).on('mouseleave', '.info-icon', function() {
+      $tooltip.find("#tooltip_content").text('');
+      $tooltip.hide();
+    });
+  },
+
+  WillDestroyElement() {
+    Ember.$('body').off('hover');
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-component-table.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-component-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-component-table.js
new file mode 100644
index 0000000..5a9ae30
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-component-table.js
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  serviceDef: null,
+  currentComponent: null,
+  duplicateNameError: false,
+
+  actions: {
+    showAddComponentModal() {
+      var newComp = this.get('serviceDef').createNewServiceComponent();
+      this.set('currentComponent', newComp);
+      this.set('duplicateNameError', false);
+      this.$('#addComponentModal').modal('show');
+    },
+
+    addNewComponent() {
+      this.set('duplicateNameError', false);
+      if (this.isCurrentNameDuplicate()) {
+        this.set('duplicateNameError', true);
+        return;
+      }
+      this.get('serviceDef.serviceComponents').addObject(this.get('currentComponent'));
+      this.$('#addComponentModal').modal('hide');
+    },
+
+    removeComponent(component) {
+      this.get('serviceDef.serviceComponents').removeObject(component);
+    }
+  },
+
+  isCurrentNameDuplicate() {
+    var currName = this.get('currentComponent.name');
+    var item = this.get('serviceDef.serviceComponents').findBy('name', currName);
+    return !Ember.isNone(item);
+  },
+
+  isValidCurrentComponent: Ember.computed.and('currentComponent', 'currentComponent.name', 'currentComponent.cpus', 'currentComponent.memory', 'currentComponent.numOfContainers', 'currentComponent.artifactId', 'currentComponent.launchCommand')
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-config-table.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-config-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-config-table.js
new file mode 100644
index 0000000..b0a78dd
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-config-table.js
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  serviceDef: null,
+  currentConfig: null,
+  serviceConfigJson: '',
+
+  actions: {
+    showNewConfigurationModal() {
+      var newConfig = this.get('serviceDef').createNewServiceConfig();
+      this.set('currentConfig', newConfig);
+      this.$('#addConfigurationModal').modal('show');
+      if (this.get('isNonEmptyComponents') && this.get('currentConfig.componentName') === '') {
+        this.set('currentConfig.componentName', this.get('componentNames.firstObject'));
+      }
+    },
+
+    removeConfiguration(config) {
+      this.get('serviceDef.serviceConfigs').removeObject(config);
+    },
+
+    configTypeChanged(type) {
+      this.set('currentConfig.type', type);
+      if (type === 'quicklink') {
+        this.set('currentConfig.scope', 'service');
+        this.set('currentConfig.componentName', '');
+      }
+    },
+
+    addNewConfiguration() {
+      this.get('serviceDef.serviceConfigs').addObject(this.get('currentConfig'));
+      this.$('#addConfigurationModal').modal('hide');
+    },
+
+    showServiceConfigUploadModal() {
+      this.set('serviceConfigJson', '');
+      this.$("#service_config_upload_modal").modal('show');
+    },
+
+    uploadServiceConfig(json) {
+      this.get('serviceDef').convertJsonServiceConfigs(json);
+      this.$("#service_config_upload_modal").modal('hide');
+    },
+
+    configScopeChanged(scope) {
+      this.set('currentConfig.scope', scope);
+    },
+
+    scopeComponentChanged(name) {
+      this.set('currentConfig.componentName', name);
+    }
+  },
+
+  isNonEmptyComponents: Ember.computed('serviceDef.serviceComponents.length', function() {
+    return this.get('serviceDef.serviceComponents.length') > 0;
+  }),
+
+  isNotQuicklink: Ember.computed('currentConfig.type', function() {
+    return this.get('currentConfig.type') !== "quicklink";
+  }),
+
+  componentNames: Ember.computed('serviceDef.serviceComponents.[]', function() {
+    var names = [];
+    this.get('serviceDef.serviceComponents').forEach(function(cmp) {
+      names.push(cmp.get('name'));
+    });
+    return names;
+  }),
+
+  isValidCurrentConfig: Ember.computed.and('currentConfig', 'currentConfig.name', 'currentConfig.value')
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-fileconfig-table.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-fileconfig-table.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-fileconfig-table.js
new file mode 100644
index 0000000..7c06152
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/service-fileconfig-table.js
@@ -0,0 +1,112 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  serviceDef: null,
+  currentFileConfig: null,
+  fileConfigJson: '',
+  fileConfigProps: '',
+  propertyViewer: null,
+  parseError: '',
+
+  actions: {
+    showNewConfigFileModal() {
+      var newFile = this.get('serviceDef').createNewFileConfig();
+      this.set('currentFileConfig', newFile);
+      this.set('fileConfigProps', '');
+      this.set('parseError', '');
+      this.$('#addFileConfigModal').modal('show');
+      if (this.get('isNonEmptyComponents') && this.get('currentFileConfig.componentName') === '') {
+        this.set('currentFileConfig.componentName', this.get('componentNames.firstObject'));
+      }
+    },
+
+    removeFileConfiguration(file) {
+      this.get('serviceDef.fileConfigs').removeObject(file);
+    },
+
+    addNewFileConfig() {
+      this.set('parseError', '');
+      var props = this.get('fileConfigProps');
+      if (props) {
+        try {
+          var parsed = JSON.parse(props);
+          this.set('currentFileConfig.props', parsed);
+        } catch (err) {
+          this.set('parseError', `Invalid JSON: ${err.message}`);
+          throw err;
+        }
+      }
+      this.get('serviceDef.fileConfigs').addObject(this.get('currentFileConfig'));
+      this.$('#addFileConfigModal').modal('hide');
+    },
+
+    showFileConfigUploadModal() {
+      this.set('fileConfigJson', '');
+      this.$("#service_file_config_upload_modal").modal('show');
+    },
+
+    uploadFileConfig(json) {
+      this.get('serviceDef').convertJsonFileConfigs(json);
+      this.$("#service_file_config_upload_modal").modal('hide');
+    },
+
+    configScopeChanged(scope) {
+      this.set('currentFileConfig.scope', scope);
+    },
+
+    scopeComponentChanged(name) {
+      this.set('currentFileConfig.componentName', name);
+    },
+
+    configTypeChanged(type) {
+      this.set('currentFileConfig.type', type);
+      if (type === "TEMPLATE") {
+        this.set('currentFileConfig.props', null);
+        this.set('fileConfigProps', '');
+      }
+    },
+
+    showFileConfigPropertyViewer(props) {
+      this.set('propertyViewer', props);
+      this.$("#file_config_properties_viewer").modal('show');
+    }
+  },
+
+  isNonEmptyComponents: Ember.computed('serviceDef.serviceComponents.length', function() {
+    return this.get('serviceDef.serviceComponents.length') > 0;
+  }),
+
+  componentNames: Ember.computed('serviceDef.serviceComponents.[]', function() {
+    var names = [];
+    this.get('serviceDef.serviceComponents').forEach(function(cmp) {
+      names.push(cmp.get('name'));
+    });
+    return names;
+  }),
+
+  isValidCurrentFileConfig: Ember.computed('currentFileConfig', 'currentFileConfig.srcFile', 'currentFileConfig.destFile', 'fileConfigProps', function() {
+    return this.get('currentFileConfig') && this.get('currentFileConfig.destFile') && (this.get('currentFileConfig.srcFile') || this.get('fileConfigProps'));
+  }),
+
+  isConfigTypeHadoopXml: Ember.computed('currentFileConfig.type', function() {
+    return this.get('currentFileConfig.type') === 'HADOOP_XML';
+  })
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/upload-config.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/upload-config.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/upload-config.js
new file mode 100644
index 0000000..2f9dc9c
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/upload-config.js
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Component.extend({
+  dialogId: "config_upload_modal",
+  title: "Upload Configuration",
+  configJson: '',
+  parseErrorMsg: '',
+
+  actions: {
+    uploadConfig() {
+      var json = this.get('configJson');
+      try {
+        JSON.parse(json);
+        this.upateParseResults("");
+      } catch (ex) {
+        this.upateParseResults("Invalid JSON: " + ex.message);
+        throw ex;
+      }
+      if (!this.get('parseErrorMsg')) {
+        this.sendAction("uploadConfig", json);
+      }
+    }
+  },
+
+  didInsertElement() {
+    this.$('#' + this.get('dialogId')).on('shown.bs.modal', function() {
+      this.upateParseResults("");
+    }.bind(this));
+  },
+
+  isValidConfigJson: Ember.computed.notEmpty('configJson'),
+
+  upateParseResults(message) {
+    this.set('parseErrorMsg', message);
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps/services.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps/services.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps/services.js
deleted file mode 100644
index 0b0be20..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-apps/services.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * 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 AppTableController from '../app-table-columns';
-
-export default AppTableController.extend({
-});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js
new file mode 100644
index 0000000..25d575f
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/controllers/yarn-deploy-service.js
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Controller.extend({
+  breadcrumbs: [{
+    text: "Home",
+    routeName: 'application'
+  }, {
+    text: "Services",
+    routeName: 'yarn-services',
+  }, {
+    text: "New Service",
+    routeName: 'yarn-deploy-service',
+  }],
+
+  savedStandardTemplates: [],
+  savedJsonTemplates: [],
+  serviceResponse: null,
+  isLoading: false,
+
+  actions: {
+    deployServiceDef(serviceDef) {
+      var defjson = serviceDef.getServiceJSON();
+      this.deployServiceApp(defjson);
+    },
+
+    deployServiceJson(json) {
+      this.deployServiceApp(json);
+    }
+  },
+
+  gotoServices() {
+    Ember.run.later(this, function() {
+      this.set('serviceResponse', null);
+      this.transitionToRoute('yarn-services');
+    }, 1000);
+  },
+
+  deployServiceApp(requestJson) {
+    var self = this;
+    var adapter = this.store.adapterFor('yarn-servicedef');
+    this.set('isLoading', true);
+    adapter.deployService(requestJson).then(function() {
+      self.set('serviceResponse', {message: 'Service has been accepted successfully. Redirecting to services in a second.', type: 'success'});
+      self.gotoServices();
+    }, function(errmsg) {
+      self.set('serviceResponse', {message: errmsg, type: 'error'});
+    }).finally(function() {
+      self.set('isLoading', false);
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js
new file mode 100644
index 0000000..0439fb4
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/models/yarn-servicedef.js
@@ -0,0 +1,278 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DS from 'ember-data';
+import Ember from 'ember';
+
+export default DS.Model.extend({
+  name: DS.attr('string', {defaultValue: ''}),
+  queue: DS.attr('string', {defaultValue: ''}),
+  lifetime: DS.attr('string', {defaultValue: ''}),
+  isCached: DS.attr('boolean', {defaultValue: false}),
+
+  serviceComponents: DS.attr({defaultValue: function() {
+    return Ember.A();
+  }}),
+
+  serviceConfigs: DS.attr({defaultValue: function() {
+    return Ember.A();
+  }}),
+
+  fileConfigs: DS.attr({defaultValue: function() {
+    return Ember.A();
+  }}),
+
+  quicklinks: DS.attr({defaultValue: function() {
+    return {};
+  }}),
+
+  clear() {
+    this.set('name', '');
+    this.set('queue', '');
+    this.set('lifetime', '');
+    this.get('serviceComponents').clear();
+    this.get('serviceConfigs').clear();
+    this.get('fileConfigs').clear();
+    this.set('quicklinks', {});
+  },
+
+  isValidServiceDef() {
+    return this.get('name') !== '' && this.get('queue') !== '' &&  this.get('serviceComponents.length') > 0;
+  },
+
+  createNewServiceComponent() {
+    return Ember.Object.create({
+      name: '',
+      numOfContainers: '',
+      cpus: '',
+      memory: '',
+      artifactId: '',
+      artifactType: 'DOCKER',
+      launchCommand: '',
+      dependencies: [],
+      uniqueComponentSupport: false,
+      configuration: null
+    });
+  },
+
+  createNewServiceConfig(name, value) {
+    var Config = Ember.Object.extend({
+      name: name || '',
+      value: value || '',
+      type: 'property', // property OR env OR quicklink
+      scope: 'service', // service OR component
+      componentName: '',
+      capitalizedType: Ember.computed('type', function() {
+        return Ember.String.capitalize(this.get('type'));
+      }),
+      formattedScope: Ember.computed('scope', 'componentName', function() {
+        if (this.get('scope') !== 'service') {
+          return this.get('componentName') + ' [Component]';
+        }
+        return Ember.String.capitalize(this.get('scope'));
+      })
+    });
+    return Config.create();
+  },
+
+  createNewFileConfig(src, dest) {
+    var FileConfig = Ember.Object.extend({
+      type: 'TEMPLATE', // HADOOP_XML OR TEMPLATE
+      srcFile: src || '',
+      destFile: dest || '',
+      scope: 'service', // service OR component
+      componentName: '',
+      props: null,
+      formattedScope: Ember.computed('scope', 'componentName', function() {
+        if (this.get('scope') !== 'service') {
+          return this.get('componentName') + ' [Component]';
+        }
+        return Ember.String.capitalize(this.get('scope'));
+      })
+    });
+    return FileConfig.create();
+  },
+
+  getServiceJSON() {
+    return this.serializeServiceDef();
+  },
+
+  serializeServiceDef() {
+    var json = {
+      name: "",
+      queue: "",
+      lifetime: "-1",
+      components: [],
+      configuration: {
+        properties: {},
+        env: {},
+        files: []
+      },
+      quicklinks: {}
+    };
+
+    var components = this.get('serviceComponents');
+    var configs = this.get('serviceConfigs');
+    var fileConfigs = this.get('fileConfigs');
+
+    json['name'] = this.get('name');
+    json['queue'] = this.get('queue');
+
+    if (this.get('lifetime')) {
+      json['lifetime'] = this.get('lifetime');
+    }
+
+    components.forEach(function(component) {
+      json.components.push(this.serializeComponent(component));
+    }.bind(this));
+
+    configs.forEach(function(config) {
+      let conf = this.serializeConfiguration(config);
+      if (conf.scope === "service") {
+        if (conf.type === "property") {
+          json.configuration.properties[conf.name] = conf.value;
+        } else if (conf.type === "env") {
+          json.configuration.env[conf.name] = conf.value;
+        } else if (conf.type === "quicklink") {
+          json.quicklinks[conf.name] = conf.value;
+        }
+      } else if (conf.scope === "component") {
+        let requiredCmp = json.components.findBy('name', conf.componentName);
+        if (requiredCmp) {
+          requiredCmp.configuration = requiredCmp.configuration || {};
+          requiredCmp.configuration.properties = requiredCmp.configuration.properties || {};
+          requiredCmp.configuration.env = requiredCmp.configuration.env || {};
+          if (conf.type === "property") {
+            requiredCmp.configuration.properties[conf.name] = conf.value;
+          } else if (conf.type === "env") {
+            requiredCmp.configuration.env[conf.name] = conf.value;
+          }
+        }
+      }
+    }.bind(this));
+
+    fileConfigs.forEach(function(file) {
+      let scope = file.get('scope');
+      if (scope === "service") {
+        json.configuration.files.push(this.serializeFileConfig(file));
+      } else if (scope === "component") {
+        let requiredCmp = json.components.findBy('name', file.get('componentName'));
+        if (requiredCmp) {
+          requiredCmp.configuration = requiredCmp.configuration || {};
+          requiredCmp.configuration.files = requiredCmp.configuration.files || [];
+          requiredCmp.configuration.files.push(this.serializeFileConfig(file));
+        }
+      }
+    }.bind(this));
+
+    return json;
+  },
+
+  serializeComponent(record) {
+    var json = {};
+    json['name'] = record.get('name');
+    json['number_of_containers'] = record.get('numOfContainers');
+    json['launch_command'] = record.get('launchCommand');
+    json['dependencies'] = [];
+    json['artifact'] = {
+      id: record.get('artifactId'),
+      type: record.get('artifactType')
+    };
+    json['resource'] = {
+      cpus: record.get('cpus'),
+      memory: record.get('memory')
+    };
+    if (record.get('uniqueComponentSupport')) {
+      json['unique_component_support'] = "true";
+    }
+    if (record.get('configuration')) {
+      json['configuration'] = record.get('configuration');
+    }
+    return json;
+  },
+
+  serializeConfiguration(config) {
+    var json = {};
+    json["type"] = config.get('type');
+    json["scope"] = config.get('scope');
+    json["componentName"] = config.get('componentName');
+    json["name"] = config.get('name');
+    json["value"] = config.get('value');
+    return json;
+  },
+
+  serializeFileConfig(file) {
+    var json = {};
+    json["type"] = file.get('type');
+    json["dest_file"] = file.get('destFile');
+    json["src_file"] = file.get('srcFile');
+    if (file.get('type') === "HADOOP_XML" && file.get('props')) {
+      json["props"] = file.get('props');
+    }
+    return json;
+  },
+
+  createNewServiceDef() {
+    return this.get('store').createRecord('yarn-servicedef', {
+      id: 'yarn_servicedef_' + Date.now()
+    });
+  },
+
+  convertJsonServiceConfigs(json) {
+    var parsedJson = JSON.parse(json);
+    if (parsedJson.properties) {
+      for (let prop in parsedJson.properties) {
+        if (parsedJson.properties.hasOwnProperty(prop)) {
+          let newPropObj = this.createNewServiceConfig(prop, parsedJson.properties[prop]);
+          this.get('serviceConfigs').addObject(newPropObj);
+        }
+      }
+    }
+    if (parsedJson.env) {
+      for (let envprop in parsedJson.env) {
+        if (parsedJson.env.hasOwnProperty(envprop)) {
+          let newEnvObj = this.createNewServiceConfig(envprop, parsedJson.env[envprop]);
+          newEnvObj.set('type', 'env');
+          this.get('serviceConfigs').addObject(newEnvObj);
+        }
+      }
+    }
+  },
+
+  convertJsonFileConfigs(json) {
+    var parsedJson = JSON.parse(json);
+    if (parsedJson.files) {
+      parsedJson.files.forEach(function(file) {
+        let newFileObj = this.createNewFileConfig(file.src_file, file.dest_file);
+        this.get('fileConfigs').addObject(newFileObj);
+      }.bind(this));
+    }
+  },
+
+  cloneServiceDef() {
+    var clone = this.createNewServiceDef();
+    clone.set('name', this.get('name'));
+    clone.set('queue', this.get('queue'));
+    clone.set('lifetime', this.get('lifetime'));
+    clone.get('serviceComponents', this.get('serviceComponents'));
+    clone.get('serviceConfigs', this.get('serviceConfigs'));
+    clone.get('fileConfigs', this.get('fileConfigs'));
+    clone.set('quicklinks', this.get('quicklinks'));
+    return clone;
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
index a45861e..5710627 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/router.js
@@ -26,7 +26,6 @@ var Router = Ember.Router.extend({
 Router.map(function() {
   this.route('yarn-apps', function () {
     this.route('apps');
-    this.route('services');
   });
   this.route('yarn-services');
   this.route('yarn-nodes', function(){
@@ -49,6 +48,7 @@ Router.map(function() {
   this.route('yarn-container-log', { path:
       '/yarn-container-log/:node_id/:node_addr/:container_id/:filename' });
 
+  this.route('yarn-deploy-service');
   this.route('cluster-overview');
   this.route('yarn-app', { path: '/yarn-app/:app_id' });
   this.route('yarn-app-attempt', { path: '/yarn-app-attempt/:app_attempt_id'});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/services.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/services.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/services.js
deleted file mode 100644
index 34ad1ad..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-apps/services.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import Ember from 'ember';
-
-export default Ember.Route.extend({
-  model() {
-      return Ember.RSVP.hash({
-        apps: this.store.query('yarn-app', {
-          applicationTypes: "org-apache-slider"
-      }),
-    });
-  },
-
-  unloadAll() {
-    this.store.unloadAll('yarn-app');
-  }
-});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js
new file mode 100644
index 0000000..05ef600
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/routes/yarn-deploy-service.js
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Ember from 'ember';
+
+export default Ember.Route.extend({
+  model() {
+    return this.store.createRecord('yarn-servicedef', {
+      id: 'yarn_servicedef_' + Date.now()
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js
index 807844e..9359530 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/services/hosts.js
@@ -75,4 +75,8 @@ export default Ember.Service.extend({
   rmWebAddress: Ember.computed(function () {
     return this.normalizeURL(this.get("env.app.hosts.rmWebAddress"));
   }),
+
+  dashWebAddress: Ember.computed(function () {
+    return this.normalizeURL(this.get("env.app.hosts.dashWebAddress"));
+  })
 });

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css
index e3dfcd9..2a23993 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/styles/app.css
@@ -314,3 +314,150 @@ div.attempt-info-panel table > tbody > tr > td:last-of-type {
   overflow: hidden;
   text-overflow: ellipsis;
 }
+
+.deploy-service textarea {
+  border-radius: 5px !important;
+  resize: none;
+  word-wrap: break-word;
+}
+
+.deploy-service .loading-state {
+  opacity: 0.5;
+}
+
+.deploy-service .loading-state img {
+  width: 80px;
+  height: 80px;
+  margin: 40px auto;
+  left: 50% !important;
+  position: absolute;
+  z-index: 9999;
+}
+
+.align-center {
+  text-align: center !important;
+}
+
+.bold-text {
+  font-weight: bold !important;
+}
+
+.deploy-service .saved-list {
+  min-height: 600px;
+}
+
+.deploy-service .glyphicon {
+  cursor: pointer;
+}
+
+.deploy-service .remove-icon:hover {
+  color: #d9534f;
+}
+
+.deploy-service .savedlist-column {
+  padding-top: 10px;
+}
+
+.deploy-service .definition-column {
+  padding-top: 10px;
+  border-left: 1px solid #ddd;
+}
+
+.deploy-service .content-area {
+  padding: 15px 0px;
+  border-top: 1px solid #ddd;
+}
+
+.deploy-service .custom-json-area {
+  padding: 10px 0;
+  margin-top: -26px;
+}
+
+.deploy-service-modal .modal-dialog {
+  width: 400px;
+}
+
+.deploy-service-modal .form-group {
+  margin-bottom: 5px;
+}
+
+.deploy-service .action-btns {
+  text-align: right;
+  padding-bottom: 15px;
+  padding-right: 0;
+}
+
+table.table-custom-action > thead > tr > th:last-of-type, table.table-custom-action > tbody > tr > td:last-of-type {
+  width: 50px !important;
+}
+
+.deploy-service .toggle-btn.active {
+  color: #fff;
+  background-color: #337ab7;
+  border-color: #337ab7;
+  text-shadow: none;
+}
+
+.deploy-service .service-resp {
+  word-wrap: break-word;
+}
+
+table.table-custom-bordered {
+  border: 1px solid #ddd !important;
+  border-radius: 3px !important;
+}
+
+table.table-custom-bordered > thead > tr > th, table.table-custom-bordered > tbody > tr > td {
+  border-bottom: 1px solid #ddd !important;
+  border-right: 1px solid #ddd !important;
+}
+
+table.table-custom-striped > thead > tr, .table-custom-striped > tbody > tr:nth-of-type(even) {
+  background-color: #f9f9f9 !important;
+}
+
+.deploy-service label.required:after, .deploy-service-modal label.required:after {
+  content: '*';
+  color: #d9534f;
+}
+
+.deploy-service .form-group.shrink-height {
+  margin-bottom: -8px;
+}
+
+table.fix-table-overflow {
+  table-layout: fixed;
+}
+
+table.fix-table-overflow > tbody > tr > td:last-of-type {
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+div.tooltip.info-tooltip {
+  font: 14px sans-serif !important;
+  background: lightsteelblue;
+  word-wrap: break-word;
+  position: absolute;
+  text-align: justify;
+  border-radius: 3px;
+  z-index: 9999;
+  padding: 10px;
+  display: none;
+  min-width: 200px;
+  max-width: 500px;
+  opacity: 1;
+  top: 10px;
+  left: 0;
+}
+
+div.tooltip.info-tooltip > span.top-arrow {
+  color: lightsteelblue;
+  position: absolute;
+  top: -10px;
+  left: 10px;
+}
+
+span.info-icon {
+  color: #337ab7 !important;
+}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs
index a6d247b..e38fc39 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/application.hbs
@@ -46,7 +46,7 @@
               <span class="sr-only">(current)</span>
             {{/link-to}}
           {{/link-to}}
-          {{#link-to 'yarn-apps.apps' tagName="li" current-when="yarn-apps.apps yarn-apps.services"}}
+          {{#link-to 'yarn-apps.apps' tagName="li" current-when="yarn-apps.apps"}}
             {{#link-to 'yarn-apps.apps' class="navigation-link"}}Applications
               <span class="sr-only">(current)</span>
             {{/link-to}}
@@ -88,3 +88,5 @@
     </div>
   </div>
 </div>
+
+{{info-tooltip}}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs
index 24acbd9..54229cc 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/breadcrumb-bar.hbs
@@ -18,5 +18,7 @@
 
 <div class="col-md-12 container-fluid breadcrumb-bar">
   {{em-breadcrumbs items=breadcrumbs}}
-  <button type="button" class="btn btn-sm btn-primary refresh" {{action "refresh"}}>Refresh</button>
+  {{#unless hideRefresh}}
+    <button type="button" class="btn btn-sm btn-primary refresh" {{action "refresh"}}>Refresh</button>
+  {{/unless}}
 </div>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs
new file mode 100644
index 0000000..a098ec3
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/deploy-service.hbs
@@ -0,0 +1,157 @@
+{{!
+ * 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="container-fluid deploy-service">
+  {{#if serviceResp}}
+    <div class="row">
+      <div class="col-md-12">
+        <div class="panel panel-default service-resp">
+          <div class="panel-body {{if (eq serviceResp.type 'error') 'bg-danger' 'bg-success'}}">
+            <span class="glyphicon glyphicon-remove pull-right remove-icon" {{action "clearServiceResponse"}}></span>
+            <strong class="{{if (eq serviceResp.type 'error') 'text-danger' 'text-success'}}">{{serviceResp.message}}</strong>
+          </div>
+        </div>
+      </div>
+    </div>
+  {{/if}}
+  <div class="panel panel-default {{if isLoading 'loading-state'}}">
+    {{#if isLoading}}
+      <img src="assets/images/spinner.gif" alt="Loading...">
+    {{/if}}
+    <div class="row">
+      <div class="col-md-12">
+        <div class="col-md-2 savedlist-column">
+          <label>Saved Templates</label>
+          <div class="panel panel-default saved-list">
+            <ul class="list-group">
+              {{#each getSavedList as |list|}}
+                <a href="#" class="list-group-item {{if list.active 'active'}}" {{action "updateServiceDef" list}}>
+                  {{list.name}}
+                  <span class="glyphicon glyphicon-remove pull-right remove-icon" {{action "removeFromSavedList" list}}></span>
+                </a>
+              {{else}}
+                <li class="list-group-item align-center">No saved templates</li>
+              {{/each}}
+            </ul>
+          </div>
+        </div>
+
+        <div class="col-md-10 definition-column">
+          <label>Service Definition</label>
+          <div class="btn-group pull-right" data-toggle="buttons">
+            <label class="btn btn-default btn-sm toggle-btn active" {{action "updateViewType" "standard"}}>
+              <input type="radio" name="custom" checked><b>Standard</b>
+            </label>
+            <label class="btn btn-default btn-sm toggle-btn" {{action "updateViewType" "custom"}}>
+              <input type="radio" name="custom"><b>Custom</b>
+            </label>
+          </div>
+
+          <div class="col-md-12 content-area">
+            {{#if isStandardViewType}}
+
+              <div class="row">
+                <div class="col-md-4">
+                  <div class="form-group shrink-height">
+                    <label class="required">Service Name</label>
+                    <span class="glyphicon glyphicon-info-sign info-icon" data-info="serviceName"></span>
+                    {{input type="text" class="form-control" placeholder="Service Name" value=serviceDef.name}}
+                  </div>
+                  <br>
+                </div>
+              </div>
+
+              <div class="row">
+                <div class="col-md-4">
+                  <div class="form-group shrink-height">
+                    <label class="required">Queue Name</label>
+                    <span class="glyphicon glyphicon-info-sign info-icon" data-info="queueName"></span>
+                    {{input type="text" class="form-control" placeholder="Queue Name" value=serviceDef.queue}}
+                  </div>
+                  <br>
+                </div>
+              </div>
+
+              <div class="row">
+                <div class="col-md-4">
+                  <div class="form-group">
+                    <label>Service Lifetime</label>
+                    <span class="glyphicon glyphicon-info-sign info-icon" data-info="lifetime"></span>
+                    {{input type="number" min="0" class="form-control" placeholder="Service Lifetime (Seconds)" value=serviceDef.lifetime}}
+                  </div>
+                  <br>
+                </div>
+              </div>
+
+              <div class="row">
+                {{service-component-table serviceDef=serviceDef applicationCtrl=applicationCtrl}}
+              </div>
+
+              <div class="row">
+                {{service-config-table serviceDef=serviceDef}}
+              </div>
+
+              <div class="row">
+                {{service-fileconfig-table serviceDef=serviceDef}}
+              </div>
+            {{/if}}
+
+            {{#if isCustomViewType}}
+            <div class="form-group custom-json-area">
+              {{textarea class="form-control" rows="29" cols="120" value=customServiceDef placeholder="Service JSON configuration here..."}}
+            </div>
+            {{/if}}
+          </div>
+
+          <div class="col-md-12 action-btns">
+            <button class="btn btn-default btn-sm" {{action "clearConfigs"}} disabled={{if isLoading "disabled"}}>
+              Reset
+            </button>
+            <button class="btn btn-primary btn-sm" disabled={{unless enableSaveOrDeployBtn "disabled"}} {{action "showSaveTemplateModal"}}>
+              Save
+            </button>
+            <button class="btn btn-success btn-sm" disabled={{unless enableSaveOrDeployBtn "disabled"}} {{action "deployService"}}>
+              Deploy
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+
+<div class="modal fade deploy-service-modal" tabindex="-1" role="dialog" id="saveListModal">
+  <div class="modal-dialog" role="document">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+        <h4 class="modal-title">Save Template As</h4>
+      </div>
+      <div class="modal-body">
+        <div class="form-group">
+          <label>Template Name</label>
+          {{input type="text" class="form-control" id="templateNameInput" value=savedTemplateName}}
+        </div>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+        <button type="button" class="btn btn-primary" {{action "addToSavedList"}} disabled={{unless isValidTemplateName "disabled"}}>Add</button>
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/fileconfig-viewer-dialog.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/fileconfig-viewer-dialog.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/fileconfig-viewer-dialog.hbs
new file mode 100644
index 0000000..1420340
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/fileconfig-viewer-dialog.hbs
@@ -0,0 +1,53 @@
+{{!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+}}
+
+<div class="modal fade" tabindex="-1" role="dialog" id="{{dialogId}}">
+  <div class="modal-dialog" role="document" style="width: 700px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+        <h4 class="modal-title bold-text">{{title}}</h4>
+      </div>
+      <div class="modal-body" style="padding: 0;">
+        <table class="table table-hover table-custom-bordered table-custom-striped fix-table-overflow" style="max-width: 700px;">
+          <thead>
+            <tr>
+              <th>Name</th>
+              <th>Value</th>
+            </tr>
+          </thead>
+          <tbody>
+            {{#each customProps as |prop|}}
+              <tr>
+                <td>{{prop.name}}</td>
+                <td title="{{prop.value}}">{{prop.value}}</td>
+              </tr>
+            {{else}}
+              <tr>
+                <td colspan="2">No data available</td>
+              </tr>
+            {{/each}}
+          </tbody>
+        </table>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/info-tooltip.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/info-tooltip.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/info-tooltip.hbs
new file mode 100644
index 0000000..faba135
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/info-tooltip.hbs
@@ -0,0 +1,20 @@
+{{!
+ * 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.
+}}
+
+<span class="glyphicon glyphicon-triangle-top top-arrow"></span>
+<div id="tooltip_content"></div>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-component-table.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-component-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-component-table.hbs
new file mode 100644
index 0000000..8f3904d
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-component-table.hbs
@@ -0,0 +1,113 @@
+{{!
+ * 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">
+  <div class="form-group">
+    <label>Service Components</label>
+    <span class="glyphicon glyphicon-info-sign info-icon" data-info="components"></span>
+    <button class="btn btn-primary btn-xs pull-right" {{action "showAddComponentModal"}}>
+      <span class="glyphicon glyphicon-plus"></span>
+    </button>
+    <div class="panel panel-default">
+      <table class="table table-hover table-custom-bordered table-custom-striped table-custom-action">
+        <thead>
+          <tr>
+            <th>Component Name</th>
+            <th>CPU</th>
+            <th>Memory</th>
+            <th># Containers</th>
+            <th>Artifact Id</th>
+            <th>Launch Command</th>
+            <th></th>
+          </tr>
+        </thead>
+        <tbody>
+          {{#each serviceDef.serviceComponents as |component|}}
+            <tr>
+              <td>{{component.name}}</td>
+              <td>{{component.cpus}}</td>
+              <td>{{component.memory}}</td>
+              <td>{{component.numOfContainers}}</td>
+              <td>{{component.artifactId}}</td>
+              <td>{{component.launchCommand}}</td>
+              <td class="align-center">
+                <span class="glyphicon glyphicon-remove remove-icon" {{action "removeComponent" component}}></span>
+              </td>
+            </tr>
+          {{else}}
+            <tr class="align-center">
+              <td colspan="7">No data available</td>
+            </tr>
+          {{/each}}
+        </tbody>
+      </table>
+    </div>
+  </div>
+</div>
+
+<div class="modal fade deploy-service-modal" tabindex="-1" role="dialog" id="addComponentModal">
+  <div class="modal-dialog" role="document">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+        <h4 class="modal-title">Add Component</h4>
+      </div>
+      <div class="modal-body">
+        {{#if duplicateNameError}}
+          <div class="alert alert-danger alert-dismissible" role="alert">
+            <strong>Component name already exists</strong>
+          </div>
+        {{/if}}
+        <div class="form-group">
+          <label class="required">Component Name</label>
+          {{input type="text" class="form-control" value=currentComponent.name}}
+        </div>
+        <div class="form-group">
+          <label class="required">CPU</label>
+          {{input type="number" min="0" class="form-control" value=currentComponent.cpus}}
+        </div>
+        <div class="form-group">
+          <label class="required">Memory</label>
+          {{input type="number" min="0" class="form-control" value=currentComponent.memory}}
+        </div>
+        <div class="form-group">
+          <label class="required"># Containers</label>
+          {{input type="number" min="0" class="form-control" value=currentComponent.numOfContainers}}
+        </div>
+        <div class="form-group">
+          <label class="required">Artifact Id</label>
+          {{input type="text" class="form-control" value=currentComponent.artifactId}}
+        </div>
+        <div class="form-group">
+          <label class="required">Launch Command</label>
+          {{input type="text" class="form-control" value=currentComponent.launchCommand}}
+        </div>
+        <div class="form-group">
+          <label class="checkbox-inline">
+            {{input type="checkbox" checked=currentComponent.uniqueComponentSupport}}
+            Unique Component Support
+          </label>
+        </div>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+        <button type="button" class="btn btn-primary" {{action "addNewComponent"}} disabled={{unless isValidCurrentComponent "disabled"}}>Add</button>
+      </div>
+    </div>
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-config-table.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-config-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-config-table.hbs
new file mode 100644
index 0000000..46a66ee
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-config-table.hbs
@@ -0,0 +1,130 @@
+{{!
+ * 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">
+  <div class="form-group">
+    <label>Service Configurations</label>
+    <span class="glyphicon glyphicon-info-sign info-icon" data-info="configurations"></span>
+    <button class="btn btn-primary btn-xs pull-right" {{action "showNewConfigurationModal"}}>
+      <span class="glyphicon glyphicon-plus"></span>
+    </button>
+    <button class="btn btn-primary btn-xs pull-right" style="margin-right: 5px;" {{action "showServiceConfigUploadModal"}}>
+      <span class="glyphicon glyphicon-open"></span>
+    </button>
+    <div class="panel panel-default">
+      <table class="table table-hover table-custom-bordered table-custom-striped table-custom-action">
+        <thead>
+          <tr>
+            <th>Name</th>
+            <th>Value</th>
+            <th>Type</th>
+            <th>Scope</th>
+            <th></th>
+          </tr>
+        </thead>
+        <tbody>
+          {{#each serviceDef.serviceConfigs as |config|}}
+            <tr>
+              <td>{{config.name}}</td>
+              <td>{{config.value}}</td>
+              <td>{{config.capitalizedType}}</td>
+              <td>{{config.formattedScope}}</td>
+              <td>
+                <span class="glyphicon glyphicon-remove remove-icon" {{action "removeConfiguration" config}}></span>
+              </td>
+            </tr>
+          {{else}}
+            <tr class="align-center">
+              <td colspan="5">No data available</td>
+            </tr>
+          {{/each}}
+        </tbody>
+      </table>
+    </div>
+  </div>
+</div>
+
+<div class="modal fade deploy-service-modal" tabindex="-1" role="dialog" id="addConfigurationModal">
+  <div class="modal-dialog" role="document">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+        <h4 class="modal-title bold-text">Add Configuration</h4>
+      </div>
+      <div class="modal-body">
+        <div class="form-group">
+          <label class="required">Name</label>
+          {{input type="text" class="form-control" value=currentConfig.name}}
+        </div>
+        <div class="form-group">
+          <label class="required">Value</label>
+          {{input type="text" class="form-control" value=currentConfig.value}}
+        </div>
+        <div class="form-group">
+          <label class="required">Type</label>
+          <div>
+            <label class="radio-inline">
+              <input type="radio" name="type" value="property" checked={{eq currentConfig.type "property"}} onchange={{action "configTypeChanged" "property"}}>Property
+            </label>
+            <label class="radio-inline">
+              <input type="radio" name="type" value="env" checked={{eq currentConfig.type "env"}} onchange={{action "configTypeChanged" "env"}}>Env
+            </label>
+            <label class="radio-inline">
+              <input type="radio" name="type" value="quicklink" checked={{eq currentConfig.type "quicklink"}} onchange={{action "configTypeChanged" "quicklink"}}>Quicklink
+            </label>
+          </div>
+        </div>
+        {{#if isNotQuicklink}}
+          <div class="form-group">
+            <label class="required">Scope</label>
+            <div>
+              <label class="radio-inline">
+                <input type="radio" name="scope" value="service" checked={{eq currentConfig.scope "service"}} onchange={{action "configScopeChanged" "service"}}>Service
+              </label>
+              {{#if isNonEmptyComponents}}
+                <label class="radio-inline">
+                  <input type="radio" name="scope" value="component" checked={{eq currentConfig.scope "component"}} onchange={{action "configScopeChanged" "component"}}>Component
+                </label>
+              {{/if}}
+            </div>
+          </div>
+          {{#if (eq currentConfig.scope "component")}}
+            <div class="form-group">
+              <select class="form-control" onchange={{action "scopeComponentChanged" value="target.value"}}>
+                {{#each componentNames as |name|}}
+                  <option value="{{name}}" selected={{eq currentConfig.componentName name}}>{{name}}</option>
+                {{/each}}
+              </select>
+            </div>
+          {{/if}}
+        {{/if}}
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+        <button type="button" class="btn btn-primary" {{action "addNewConfiguration"}} disabled={{unless isValidCurrentConfig "disabled"}}>Add</button>
+      </div>
+    </div>
+  </div>
+</div>
+
+{{upload-config
+  dialogId="service_config_upload_modal"
+  title="Upload Service Configurations"
+  configJson=serviceConfigJson
+  uploadConfig="uploadServiceConfig"
+}}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/e2384023/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-fileconfig-table.hbs
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-fileconfig-table.hbs b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-fileconfig-table.hbs
new file mode 100644
index 0000000..97442c6
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/templates/components/service-fileconfig-table.hbs
@@ -0,0 +1,152 @@
+{{!
+ * 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">
+  <div class="form-group">
+    <label>File Configurations</label>
+    <span class="glyphicon glyphicon-info-sign info-icon" data-info="fileConfigs"></span>
+    <button class="btn btn-primary btn-xs pull-right" {{action "showNewConfigFileModal"}}>
+      <span class="glyphicon glyphicon-plus"></span>
+    </button>
+    <button class="btn btn-primary btn-xs pull-right" style="margin-right: 5px;" {{action "showFileConfigUploadModal"}}>
+      <span class="glyphicon glyphicon-open"></span>
+    </button>
+    <div class="panel panel-default">
+      <table class="table table-hover table-custom-bordered table-custom-striped table-custom-action">
+        <thead>
+          <tr>
+            <th>Source File</th>
+            <th>Properties</th>
+            <th>Destination File</th>
+            <th>Type</th>
+            <th>Scope</th>
+            <th></th>
+          </tr>
+        </thead>
+        <tbody>
+          {{#each serviceDef.fileConfigs as |file|}}
+            <tr>
+              <td>
+                {{#if file.srcFile}}
+                  {{file.srcFile}}
+                {{else}}
+                  <span>N/A</span>
+                {{/if}}
+              </td>
+              <td>
+                {{#if file.props}}
+                  <a href="#" {{action "showFileConfigPropertyViewer" file.props}}>View Properties</a>
+                {{else}}
+                  <span>N/A</span>
+                {{/if}}
+              </td>
+              <td>{{file.destFile}}</td>
+              <td>{{file.type}}</td>
+              <td>{{file.formattedScope}}</td>
+              <td class="align-center">
+                <span class="glyphicon glyphicon-remove remove-icon" {{action "removeFileConfiguration" file}}></span>
+              </td>
+            </tr>
+          {{else}}
+            <tr class="align-center">
+              <td colspan="6">No data available</td>
+            </tr>
+          {{/each}}
+        </tbody>
+      </table>
+    </div>
+  </div>
+</div>
+
+<div class="modal fade deploy-service-modal" tabindex="-1" role="dialog" id="addFileConfigModal">
+  <div class="modal-dialog" role="document" style="width: 500px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+        <h4 class="modal-title bold-text">Add File Configuration</h4>
+      </div>
+      <div class="modal-body">
+        {{#if parseError}}
+          <div class="alert alert-danger alert-dismissible" role="alert">
+            <strong>{{parseError}}</strong>
+          </div>
+        {{/if}}
+        <div class="form-group">
+          <label class="required">Type</label>
+          <div>
+            <label class="radio-inline">
+              <input type="radio" name="type" value="TEMPLATE" checked={{eq currentFileConfig.type "TEMPLATE"}} onchange={{action "configTypeChanged" "TEMPLATE"}}>TEMPLATE
+            </label>
+            <label class="radio-inline">
+              <input type="radio" name="type" value="HADOOP_XML" checked={{eq currentFileConfig.type "HADOOP_XML"}} onchange={{action "configTypeChanged" "HADOOP_XML"}}>HADOOP_XML
+            </label>
+          </div>
+        </div>
+        <div class="form-group">
+          <label class={{unless isConfigTypeHadoopXml "required"}}>Source File</label>
+          {{input type="text" class="form-control" value=currentFileConfig.srcFile}}
+        </div>
+        {{#if isConfigTypeHadoopXml}}
+          <div class="form-group">
+            <label>Properties</label> <span>(Source File and/or Properties are required)</span>
+            {{textarea class="form-control" rows="15" value=fileConfigProps placeholder="Configuration file properties here..."}}
+          </div>
+        {{/if}}
+        <div class="form-group">
+          <label class="required">Destination File</label>
+          {{input type="text" class="form-control" value=currentFileConfig.destFile}}
+        </div>
+        <div class="form-group">
+          <label class="required">Scope</label>
+          <div>
+            <label class="radio-inline">
+              <input type="radio" name="scope" value="service" checked={{eq currentFileConfig.scope "service"}} onchange={{action "configScopeChanged" "service"}}>Service
+            </label>
+            {{#if isNonEmptyComponents}}
+              <label class="radio-inline">
+                <input type="radio" name="scope" value="component" checked={{eq currentFileConfig.scope "component"}} onchange={{action "configScopeChanged" "component"}}>Component
+              </label>
+            {{/if}}
+          </div>
+        </div>
+        {{#if (eq currentFileConfig.scope "component")}}
+          <div class="form-group">
+            <select class="form-control" onchange={{action "scopeComponentChanged" value="target.value"}}>
+              {{#each componentNames as |name|}}
+                <option value="{{name}}" selected={{eq currentFileConfig.componentName name}}>{{name}}</option>
+              {{/each}}
+            </select>
+          </div>
+        {{/if}}
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+        <button type="button" class="btn btn-primary" {{action "addNewFileConfig"}} disabled={{unless isValidCurrentFileConfig "disabled"}}>Add</button>
+      </div>
+    </div>
+  </div>
+</div>
+
+{{upload-config
+  dialogId="service_file_config_upload_modal"
+  title="Upload File Configurations"
+  configJson=fileConfigJson
+  uploadConfig="uploadFileConfig"
+}}
+
+{{fileconfig-viewer-dialog dialogId="file_config_properties_viewer" props=propertyViewer}}


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org