You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2015/09/23 06:57:27 UTC

ambari git commit: AMBARI-13110. Ambari Capacity Scheduler View: Should disable Access Control setting when Ranger is enabled. (Nitiraj Rathore via yusaku)

Repository: ambari
Updated Branches:
  refs/heads/trunk e4e9c9f5c -> 82418c6d2


AMBARI-13110. Ambari Capacity Scheduler View: Should disable Access Control setting when Ranger is enabled. (Nitiraj Rathore via yusaku)


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

Branch: refs/heads/trunk
Commit: 82418c6d2847a9b85d93bae77485de1e66e32118
Parents: e4e9c9f
Author: Yusaku Sako <yu...@hortonworks.com>
Authored: Tue Sep 22 21:56:57 2015 -0700
Committer: Yusaku Sako <yu...@hortonworks.com>
Committed: Tue Sep 22 21:56:57 2015 -0700

----------------------------------------------------------------------
 .../capacityscheduler/ConfigurationService.java |  24 ++++
 .../src/main/resources/ui/app/adapters.js       | 111 +++++++++++--------
 .../src/main/resources/ui/app/controllers.js    |   1 +
 .../resources/ui/app/controllers/configs.js     |  22 ++++
 .../main/resources/ui/app/controllers/queue.js  |  16 ++-
 .../src/main/resources/ui/app/models.js         |   1 +
 .../src/main/resources/ui/app/models/config.js  |  24 ++++
 .../src/main/resources/ui/app/models/queue.js   |   1 +
 .../src/main/resources/ui/app/router.js         |  16 ++-
 .../src/main/resources/ui/app/serializers.js    |   9 ++
 .../main/resources/ui/app/templates/queue.hbs   |   8 ++
 .../ConfigurationServiceTest.java               | 103 +++++++++++++++++
 12 files changed, 286 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java b/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java
index 968f212..2769931 100644
--- a/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java
+++ b/contrib/views/capacity-scheduler/src/main/java/org/apache/ambari/view/capacityscheduler/ConfigurationService.java
@@ -23,6 +23,7 @@ import org.apache.ambari.view.capacityscheduler.utils.MisconfigurationFormattedE
 import org.apache.ambari.view.capacityscheduler.utils.ServiceFormattedException;
 import org.apache.ambari.view.utils.ambari.AmbariApi;
 import org.apache.commons.io.IOUtils;
+import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
 import org.json.simple.JSONValue;
 import org.slf4j.Logger;
@@ -484,6 +485,29 @@ public class ConfigurationService {
     return ambariApi.getServices().getRMUrl();
   }
 
+  @GET
+  @Consumes(MediaType.APPLICATION_JSON)
+  @Produces(MediaType.APPLICATION_JSON)
+  @Path("/getConfig")
+  public Response getConfigurationValue(@QueryParam("siteName") String siteName,@QueryParam("configName") String configName){
+    try{
+      String configValue = ambariApi.getCluster().getConfigurationValue(siteName,configName);
+      JSONObject res = new JSONObject();
+      JSONArray arr = new JSONArray();
+      JSONObject conf = new JSONObject();
+      conf.put("siteName",siteName);
+      conf.put("configName", configName);
+      conf.put("configValue", configValue);
+      arr.add(conf);
+      res.put("configs" ,arr);
+      return Response.ok(res).build();
+    } catch (WebApplicationException ex) {
+      throw ex;
+    } catch (Exception ex) {
+      throw new ServiceFormattedException(ex.getMessage(), ex);
+    }
+  }
+
   private String getRMHosts() {
     StringBuilder hosts = new StringBuilder();
     boolean first = true;

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
index dd02587..068c241 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/adapters.js
@@ -39,6 +39,62 @@ function _getCapacitySchedulerViewUri(adapter) {
   return '/' + [adapter.namespace,'views',view,'versions',version,'instances',instance,'resources','scheduler','configuration'].join('/');
 }
 
+function _ajaxOptions(url, type, hash) {
+  hash = hash || {};
+  hash.url = url;
+  hash.type = type;
+  hash.dataType = 'json';
+  hash.context = this;
+
+  hash.beforeSend = function (xhr) {
+    xhr.setRequestHeader('X-Requested-By', 'view-capacity-scheduler');
+  };
+  return hash;
+};
+function _ajaxError(jqXHR) {
+  if (jqXHR && typeof jqXHR === 'object') {
+    jqXHR.then = null;
+  }
+
+  return jqXHR;
+};
+function _ajax(url, type, hash) {
+  return new Ember.RSVP.Promise(function(resolve, reject) {
+    hash = _ajaxOptions(url, type, hash);
+
+    hash.success = function(json) {
+      Ember.run(null, resolve, json);
+    };
+
+    hash.error = function(jqXHR, textStatus, errorThrown) {
+      Ember.run(null, reject, _ajaxError(jqXHR));
+    };
+
+    Ember.$.ajax(hash);
+  }, "App: Adapters#ajax " + type + " to " + url);
+};
+
+
+App.ConfigAdapter = DS.Adapter.extend({
+  defaultSerializer:'config',
+  namespace: 'api/v1',
+  findQuery : function(store, type, query){
+    var adapter = this;
+    var uri = [_getCapacitySchedulerViewUri(this),'getConfig'].join('/') + "?siteName=" + query.siteName + "&configName="+ query.configName;
+
+    if (App.testMode)
+      uri = uri + ".json";
+
+    return new Ember.RSVP.Promise(function(resolve, reject) {
+      _ajax(uri ,'GET').then(function(data) {
+        Ember.run(null, resolve, data);
+      }, function(jqXHR) {
+        jqXHR.then = null;
+        Ember.run(null, resolve, false);
+      });
+    }, "App: ConfigAdapter#findQuery siteName : " + query.siteName + ", configName : " + query.configName);
+  }
+});
 
 App.QueueAdapter = DS.Adapter.extend({
   defaultSerializer:'queue',
@@ -102,7 +158,7 @@ App.QueueAdapter = DS.Adapter.extend({
     });
 
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      adapter.ajax(uri,'PUT',{contentType:'application/json; charset=utf-8',data:data}).then(function(data) {
+      _ajax(uri,'PUT',{contentType:'application/json; charset=utf-8',data:data}).then(function(data) {
         store.setProperties({'current_tag':new_tag,'tag':new_tag});
         Ember.run(null, resolve, data.resources.objectAt(0).configurations.objectAt(0).configs);
       }, function(jqXHR) {
@@ -116,7 +172,7 @@ App.QueueAdapter = DS.Adapter.extend({
     if (!opt) return;
     var uri = [_getCapacitySchedulerViewUri(this),opt].join('/');
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      this.ajax(uri,'PUT',{contentType:'application/json; charset=utf-8',data:JSON.stringify({save:true})})
+      _ajax(uri,'PUT',{contentType:'application/json; charset=utf-8',data:JSON.stringify({save:true})})
       .then(function (data) {
         resolve(data);
       },function (error) {
@@ -158,7 +214,7 @@ App.QueueAdapter = DS.Adapter.extend({
       uri = uri + "/scheduler-configuration.json";
 
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      adapter.ajax(uri,'GET').then(function(data) {
+      _ajax(uri,'GET').then(function(data) {
         var config = data.items.objectAt(0);
         if (!store.get('isInitialized')) {
           store.set('current_tag',config.tag);
@@ -178,7 +234,7 @@ App.QueueAdapter = DS.Adapter.extend({
         uri = [_getCapacitySchedulerViewUri(this),'byTag',tag].join('/');
 
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      adapter.ajax(uri,'GET').then(function(data) {
+      _ajax(uri,'GET').then(function(data) {
         Ember.run(null, resolve, data);
       }, function(jqXHR) {
         jqXHR.then = null;
@@ -193,7 +249,7 @@ App.QueueAdapter = DS.Adapter.extend({
       uri = uri + ".json";
 
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      this.ajax(uri,'GET').then(function(data) {
+      _ajax(uri,'GET').then(function(data) {
         var parsedData = JSON.parse(data), labels;
 
         if (parsedData && Em.isArray(parsedData.nodeLabels)) {
@@ -217,7 +273,7 @@ App.QueueAdapter = DS.Adapter.extend({
     if (App.testMode)
       uri = uri + ".json";
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      this.ajax(uri,'GET').then(function(data) {
+      _ajax(uri,'GET').then(function(data) {
         Ember.run(null, resolve, data);
       }, function(jqXHR) {
         jqXHR.then = null;
@@ -231,7 +287,7 @@ App.QueueAdapter = DS.Adapter.extend({
     if (App.testMode)
       uri = uri + ".json";
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      this.ajax(uri,'GET').then(function(data) {
+      _ajax(uri,'GET').then(function(data) {
         Ember.run(null, resolve, data);
       }, function(jqXHR) {
         if (jqXHR.status === 404) {
@@ -242,45 +298,6 @@ App.QueueAdapter = DS.Adapter.extend({
         }
       });
     }.bind(this),'App: QueueAdapter#checkCluster');
-  },
-
-  ajax: function(url, type, hash) {
-    var adapter = this;
-
-    return new Ember.RSVP.Promise(function(resolve, reject) {
-      hash = adapter.ajaxOptions(url, type, hash);
-
-      hash.success = function(json) {
-        Ember.run(null, resolve, json);
-      };
-
-      hash.error = function(jqXHR, textStatus, errorThrown) {
-        Ember.run(null, reject, adapter.ajaxError(jqXHR));
-      };
-
-      Ember.$.ajax(hash);
-    }, "App: QueueAdapter#ajax " + type + " to " + url);
-  },
-
-  ajaxOptions: function(url, type, hash) {
-    hash = hash || {};
-    hash.url = url;
-    hash.type = type;
-    hash.dataType = 'json';
-    hash.context = this;
-
-    hash.beforeSend = function (xhr) {
-      xhr.setRequestHeader('X-Requested-By', 'view-capacity-scheduler');
-    };
-    return hash;
-  },
-
-  ajaxError: function(jqXHR) {
-    if (jqXHR && typeof jqXHR === 'object') {
-      jqXHR.then = null;
-    }
-
-    return jqXHR;
   }
 });
 
@@ -305,7 +322,7 @@ App.TagAdapter = App.QueueAdapter.extend({
       uri = uri + ".json";
 
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      adapter.ajax(uri ,'GET').then(function(data) {
+      _ajax(uri ,'GET').then(function(data) {
         Ember.run(null, resolve, data);
       }, function(jqXHR) {
         jqXHR.then = null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
index 0101a82..16b7d0a 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers.js
@@ -19,3 +19,4 @@
 require('controllers/queue');
 require('controllers/queues');
 require('controllers/trace');
+require('controllers/configs');

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/configs.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/configs.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/configs.js
new file mode 100644
index 0000000..b191529
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/configs.js
@@ -0,0 +1,22 @@
+/**
+ * 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.
+ */
+
+    var App = require('app');
+
+App.ConfigsController = Ember.ArrayController.extend({
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js
index 77f8889..521b473 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/controllers/queue.js
@@ -22,7 +22,21 @@ var _runState = 'RUNNING';
 var _stopState = 'STOPPED';
 
 App.QueueController = Ember.ObjectController.extend({
-  needs:['queues'],
+  needs:['queues','configs'],
+  isRangerEnabledForYarn : function() {
+    var isRanger = this.get('controllers.configs.isRangerEnabledForYarn');
+    console.log("controllers.queue : isRanger : ", isRanger);
+    if (isRanger == null || typeof isRanger == 'undefined') {
+      return false;
+    }
+
+    isRanger = isRanger.toLowerCase();
+    if (isRanger == 'yes' || isRanger == 'true') {
+      return true;
+    }
+
+    return false;
+  }.property('controllers.configs.isRangerEnabledForYarn'),
   actions:{
     setState:function (state) {
       this.set('content.state', (state === "running") ? (this.get('content.state') == null) ? null : _runState : _stopState );

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/models.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models.js
index 89bbdaa..c08b244 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models.js
@@ -17,3 +17,4 @@
  */
 
 require('models/queue');
+require('models/config');

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/config.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/config.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/config.js
new file mode 100644
index 0000000..b0e10d1
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/config.js
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var App = require('app');
+
+App.Config =  DS.Model.extend({
+    siteName : DS.attr('string'),
+    configName : DS.attr('string'),
+    configValue : DS.attr('string')
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
index 9aa7f60..46f14ad 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/models/queue.js
@@ -244,3 +244,4 @@ App.Queue = DS.Model.extend({
     }
   }.observes('labels','default_node_label_expression')
 });
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
index 97473fb..a2d50b9 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/router.js
@@ -26,6 +26,8 @@ App.Router.map(function() {
   this.route('refuse');
 });
 
+var RANGER_SITE = 'ranger-yarn-plugin-properties';
+var RANGER_YARN_ENABLED = 'ranger-yarn-plugin-enabled';
 /**
  * The queues route.
  *
@@ -49,13 +51,22 @@ App.QueuesRoute = Ember.Route.extend({
     var store = this.get('store'),
         controller = this.controllerFor('queues'),
         loadingController = this.container.lookup('controller:loading');
+    var _this = this;
     return new Ember.RSVP.Promise(function (resolve,reject) {
       loadingController.set('model', {message:'access check'});
-      store.checkOperator().then(function (isOperator) {
+      store.checkOperator().then(function   (isOperator) {
         controller.set('isOperator', isOperator);
 
         loadingController.set('model', {message:'loading node labels'});
         return store.get('nodeLabels');
+      }).then(function(){
+        return store.findQuery( 'config', {siteName : RANGER_SITE, configName : RANGER_YARN_ENABLED}).then(function(){
+          return store.find( 'config', "siteName_" + RANGER_SITE + "_configName_" + RANGER_YARN_ENABLED)
+              .then(function(data){
+                console.log("router.queuesRoute : data.configValue isRangerEnabled : " + data.get('configValue'));
+                _this.controllerFor('configs').set('isRangerEnabledForYarn', data.get('configValue'));
+              });
+        })
       }).then(function () {
         loadingController.set('model', {message:'loading queues'});
         return store.find('queue');
@@ -90,11 +101,13 @@ App.QueuesRoute = Ember.Route.extend({
  * /queues/:id
  */
 App.QueueRoute = Ember.Route.extend({
+
   model: function(params,tr) {
     var queues = this.modelFor('queues') || this.store.find('queue'),
         filterQueues = function (queues) {
           return queues.findBy('id',params.queue_id);
         };
+
     return (queues instanceof DS.PromiseArray)?queues.then(filterQueues):filterQueues(queues);
   },
   afterModel:function (model) {
@@ -176,4 +189,3 @@ App.ErrorRoute = Ember.Route.extend({
   }
 });
 
-

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/serializers.js
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/serializers.js b/contrib/views/capacity-scheduler/src/main/resources/ui/app/serializers.js
index eaa604d..7fef4be 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/serializers.js
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/serializers.js
@@ -298,3 +298,12 @@ App.TagSerializer = DS.RESTSerializer.extend({
     }
   }
 });
+
+
+App.ConfigSerializer = DS.RESTSerializer.extend({
+  normalize : function(modelclass, resourceHash, prop){
+    resourceHash.id = 'siteName_'+ resourceHash.siteName + "_configName_" + resourceHash.configName;
+    return resourceHash;
+  }
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs
index a6fdfd7..15550d1 100644
--- a/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs
+++ b/contrib/views/capacity-scheduler/src/main/resources/ui/app/templates/queue.hbs
@@ -73,12 +73,14 @@
   </div>
   <div class="row queue-acl-row">
     <div class="col-md-12 col-lg-6 queue-acl">
+
       <div class="panel panel-default">
         <div class="panel-heading">
           <div class="panel-title">
             Access Control and Status
           </div>
         </div>
+        {{#unless isRangerEnabledForYarn}}
         <div class="panel-body">
           <form class="form-horizontal form-acl" role="form">
           <div class="form-group row">
@@ -179,7 +181,13 @@
           {{/if}}
           </form>
         </div>
+        {{else}}
+          <div class="panel-body">
+              Permissions are managed by Ranger
+          </div>
+        {{/unless}}
       </div>
+
     </div>
 
     <div class="col-md-12 col-lg-6 queue-resources">

http://git-wip-us.apache.org/repos/asf/ambari/blob/82418c6d/contrib/views/capacity-scheduler/src/test/java/org/apache/ambari/view/capacityscheduler/ConfigurationServiceTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/capacity-scheduler/src/test/java/org/apache/ambari/view/capacityscheduler/ConfigurationServiceTest.java b/contrib/views/capacity-scheduler/src/test/java/org/apache/ambari/view/capacityscheduler/ConfigurationServiceTest.java
new file mode 100644
index 0000000..62fa21e
--- /dev/null
+++ b/contrib/views/capacity-scheduler/src/test/java/org/apache/ambari/view/capacityscheduler/ConfigurationServiceTest.java
@@ -0,0 +1,103 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.
+ */
+
+package org.apache.ambari.view.capacityscheduler;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.cluster.Cluster;
+import org.apache.ambari.view.utils.ambari.AmbariApi;
+import org.easymock.EasyMock;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.JSONValue;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.easymock.EasyMock.*;
+
+
+public class ConfigurationServiceTest {
+    private ViewContext context;
+    private HttpHeaders httpHeaders;
+    private UriInfo uriInfo;
+    private Cluster ambariCluster;
+    private Map<String, String> properties;
+    private ConfigurationService configurationService;
+
+    public static final String BASE_URI = "http://localhost:8084/myapp/";
+
+
+    @Before
+    public void setUp() throws Exception {
+        context = createNiceMock(ViewContext.class);
+        httpHeaders = createNiceMock(HttpHeaders.class);
+        ambariCluster = createNiceMock(Cluster.class);
+
+        properties = new HashMap<String, String>();
+        properties.put(AmbariApi.AMBARI_SERVER_URL_INSTANCE_PROPERTY, BASE_URI);
+        properties.put(AmbariApi.AMBARI_SERVER_USERNAME_INSTANCE_PROPERTY, "admin");
+        properties.put(AmbariApi.AMBARI_SERVER_PASSWORD_INSTANCE_PROPERTY, "admin");
+
+        EasyMock.expect(ambariCluster.getConfigurationValue("ranger-yarn-plugin-properties", "ranger-yarn-plugin-enabled")).andReturn("Yes").anyTimes();
+        EasyMock.expect(context.getCluster()).andReturn(ambariCluster).anyTimes();
+        EasyMock.expect(context.getProperties()).andReturn(properties).anyTimes();
+        EasyMock.replay(context);
+        EasyMock.replay(ambariCluster);
+        System.out.println("context.getProperties() : " + context.getProperties());
+        configurationService = new ConfigurationService(context);
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    @Test
+    public void testRightConfigurationValue() {
+        Response response = configurationService.getConfigurationValue("ranger-yarn-plugin-properties", "ranger-yarn-plugin-enabled");
+        JSONObject jsonObject = (JSONObject) response.getEntity();
+        JSONArray arr = (JSONArray) jsonObject.get("configs");
+        Assert.assertEquals(arr.size(), 1);
+        JSONObject obj = (JSONObject) arr.get(0);
+
+        Assert.assertEquals(obj.get("siteName"), "ranger-yarn-plugin-properties");
+        Assert.assertEquals(obj.get("configName"), "ranger-yarn-plugin-enabled");
+        Assert.assertEquals(obj.get("configValue"), "Yes"); // because I set it myself.
+    }
+
+    @Test
+    public void testExceptionOnWrongConfigurationValue() {
+        Response response = configurationService.getConfigurationValue("random-site", "random-key");
+        JSONObject jsonObject = (JSONObject) response.getEntity();
+        JSONArray arr = (JSONArray) jsonObject.get("configs");
+        Assert.assertEquals(arr.size(), 1);
+        JSONObject obj = (JSONObject) arr.get(0);
+
+        Assert.assertEquals(obj.get("siteName"), "random-site");
+        Assert.assertEquals(obj.get("configName"), "random-key");
+        Assert.assertEquals(obj.get("configValue"), null);
+    }
+}