Repository: ambari
Updated Branches:
  refs/heads/branch-2.1 c33e7d722 -> 2580916a6


http://git-wip-us.apache.org/repos/asf/ambari/blob/2580916a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js
 
b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js
index b8748cb..366d18c 100644
--- 
a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/settings-test.js
@@ -24,89 +24,113 @@ moduleFor('controller:settings', 'SettingsController', {
     'controller:databases',
     'controller:index',
     'controller:open-queries',
-    'controller:loaded-files',
     'controller:index/history-query/results',
     'controller:index/history-query/explain',
-    'controller:columns',
     'controller:udfs',
     'controller:index/history-query/logs',
     'controller:visual-explain',
     'controller:tez-ui',
-    'controller:tables',
-    'controller:job-progress',
     'adapter:database',
-    'adapter:application'
+    'adapter:application',
+    'service:settings',
+    'service:notify',
+    'service:database',
+    'service:file',
+    'service:session',
+    'service:job',
+    'service:job-progress'
   ]
 });
 
-// test('can add a setting', function() {
-//   var controller = this.subject();
+test('can add a setting', function() {
+  var controller = this.subject();
 
-//   ok(!controller.get('currentSettings.settings.length'), 'No initial 
settings');
+  ok(!controller.get('settings.length'), 'No initial settings');
 
-//   Ember.run(function() {
-//     controller.send('add');
-//   });
+  Ember.run(function() {
+    controller.send('add');
+  });
 
-//   equal(controller.get('currentSettings.settings.length'), 1, 'Can add 
settings');
-// });
-
-// test('hasSettings return true if there are settings', function() {
-//   var controller = this.subject();
-
-//   controller.get('currentSettings');
-//   ok(!controller.hasSettings(null), 'No settings => return false');
-
-//   Ember.run(function() {
-//     controller.send('add');
-//   });
-
-//   ok(controller.hasSettings(null), '1 setting => returns true');
-// });
-
-// test('setSettingForQuery', function() {
-//   var controller = this.subject();
-
-//   var settings = [ Ember.Object.create({key: 'key', value: 'value'}) ];
-
-//   Ember.run(function() {
-//     controller.setSettingForQuery(1, settings);
-//   });
-
-//   equal(controller.get('currentSettings.settings.firstObject.key'), 
settings.get('key'), 'It sets the settings for specified query');
-// });
+  equal(controller.get('settings.length'), 1, 'Can add settings');
+});
 
-// test('validate', function() {
-//   var predefinedSettings = [
-//     {
-//       name: 'some.key',
-//       validate: new RegExp(/^\d+$/) // digits
-//     }
-//   ];
+test('validate', function() {
+  var predefinedSettings = [
+    {
+      name: 'some.key',
+      validate: new RegExp(/^\d+$/) // digits
+    }
+  ];
+
+  var controller = this.subject({
+    predefinedSettings: predefinedSettings
+  });
+
+  controller.set('openQueries.update', function () {
+    var defer = Ember.RSVP.defer();
+    defer.resolve();
+
+    return defer.promise;
+  });
+
+  var settings = [
+    Ember.Object.create({key: { name: 'some.key' }, value: 'value'}),
+    Ember.Object.create({key: { name: 'some.key' }, value: '123'})
+  ];
+
+  Ember.run(function() {
+    controller.set('settings', settings);
+  });
+
+  var currentSettings = controller.get('settings');
+  ok(!currentSettings.get('firstObject.valid'), "First setting doesn\' pass 
validataion");
+  ok(currentSettings.get('lastObject.valid'), 'Second setting passes 
validation');
+});
 
-//   var controller = this.subject({
-//     predefinedSettings: predefinedSettings
-//   });
+test('Actions', function(assert) {
+  assert.expect(5);
+
+  var settingsService = Ember.Object.create({
+    add: function() {
+      assert.ok(true, 'add called');
+    },
+    remove: function(setting) {
+      assert.ok(setting, 'Setting param is sent');
+    },
+    createKey: function(name) {
+      assert.ok(name, 'Name param is sent');
+    },
+    removeAll: function() {
+      assert.ok(true, 'removeAll called');
+    },
+    saveDefaultSettings: function() {
+      assert.ok(true, 'saveDefaultSettings called');
+    }
+  });
+
+  var controller = this.subject();
+  controller.set('settingsService', settingsService);
+
+  Ember.run(function() {
+    controller.send('add');
+    controller.send('remove', {});
+    controller.send('addKey', {});
+    controller.send('removeAll');
+    controller.send('saveDefaultSettings');
+  });
+});
 
-//   controller.set('openQueries.update', function () {
-//     var defer = Ember.RSVP.defer();
-//     defer.resolve();
 
-//     return defer.promise;
-//   });
+test('Excluded settings', function(assert) {
+  var controller = this.subject();
 
-//   var settings = [
-//     Ember.Object.create({key: { name: 'some.key' }, value: 'value'}),
-//     Ember.Object.create({key: { name: 'some.key' }, value: '123'})
-//   ];
+  console.log(controller.get('predefinedSettings'));
+  assert.equal(controller.get('excluded').length, 0, 'Initially there are no 
excluded settings');
 
-//   Ember.run(function() {
-//     controller.set('index.model', Ember.Object.create({ id: 1 }));
-//     controller.get('currentSettings');
-//     controller.setSettingForQuery(1, settings);
-//   });
+  Ember.run(function() {
+    controller.get('settings').pushObject(Ember.Object.create({ key: { name: 
'hive.tez.container.size' }}));
+    controller.get('settings').pushObject(Ember.Object.create({ key: { name: 
'hive.prewarm.enabled' }}));
+  });
 
-//   var currentSettings = controller.get('model.firstObject.settings');
-//   ok(!currentSettings.get('firstObject.valid'), "First setting doesn\' pass 
validataion");
-//   ok(currentSettings.get('lastObject.valid'), 'Second setting passes 
validation');
-// });
+  assert.equal(controller.get('excluded').length, 2, 'Two settings are 
excluded');
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/2580916a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js
 
b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js
index e03b561..fdf4a89 100644
--- 
a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/tez-ui-test.js
@@ -35,10 +35,12 @@ moduleFor('controller:tez-ui', 'TezUIController', {
     'controller:index/history-query/explain',
     'controller:settings',
     'controller:visual-explain',
-    'controller:job-progress',
     'adapter:database',
     'service:database',
-    'service:notify'
+    'service:notify',
+    'service:job-progress',
+    'service:session',
+    'service:settings'
   ],
 
   setup: function() {

http://git-wip-us.apache.org/repos/asf/ambari/blob/2580916a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/udf-test.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/udf-test.js
 
b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/udf-test.js
deleted file mode 100644
index 8fd643e..0000000
--- 
a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/controllers/udf-test.js
+++ /dev/null
@@ -1,92 +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';
-import { moduleFor, test } from 'ember-qunit';
-
-moduleFor('controller:udf', 'UdfController', {});
-
-test('controller is initialized', function() {
-  expect(2);
-
-  var model = Ember.Object.create({
-    id: 1,
-    name: 'udfmodel',
-    classname: 'cls',
-    isNew: true,
-    fileResource: 'fileresource'
-  });
-
-  var component = this.subject({ model: model});
-
-  ok(component.get('isEditing'), 'Model is new, isEditing is set to true');
-  equal(component.get('fileBackup'), model.get('fileResource'), 'fileBackup is 
set to model.fileResource');
-});
-
-test('addFileResource', function() {
-  expect(3);
-
-  var model = Ember.Object.create({
-    id: 1,
-    name: 'udfmodel',
-    classname: 'cls',
-    isNew: true,
-    fileResource: null
-  });
-
-  var store = {
-    createRecord: function() {
-      return 'newfileresource';
-    }
-  };
-
-  var component = this.subject({model: model, store: store });
-
-  equal(component.get('model.fileResource'), null, 'fileResource is set to 
null');
-
-  Ember.run(function () {
-    component.send('addFileResource');
-  });
-
-  ok(component.get('isEditingResource'), 'isEditingResource is set to true');
-  equal(component.get('model.fileResource'), store.createRecord(), 'New file 
resource is set on the model');
-});
-
-test('editFileResource', function() {
-  expect(3);
-
-  var model = Ember.Object.create({
-    id: 1,
-    name: 'udfmodel',
-    classname: 'cls',
-    isNew: true,
-    fileResource: null
-  });
-
-  var file = 'fileresource';
-  var component = this.subject({model: model });
-
-  equal(component.get('model.fileResource'), null, 'fileResource is set to 
null');
-
-  Ember.run(function () {
-    component.send('editFileResource', file);
-  });
-
-  ok(component.get('isEditingResource'), 'isEditingResource is set to true');
-  equal(component.get('model.fileResource'), file, 'New file resource is set 
on the model');
-});

http://git-wip-us.apache.org/repos/asf/ambari/blob/2580916a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/services/settings-test.js
----------------------------------------------------------------------
diff --git 
a/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/services/settings-test.js
 
b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/services/settings-test.js
new file mode 100644
index 0000000..cb99882
--- /dev/null
+++ 
b/contrib/views/hive/src/main/resources/ui/hive-web/tests/unit/services/settings-test.js
@@ -0,0 +1,155 @@
+/**
+ * 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 { moduleFor, test } from 'ember-qunit';
+
+moduleFor('service:settings', 'SettingsService');
+
+test('Init', function(assert) {
+  var service = this.subject();
+  assert.ok(service);
+});
+
+test('Can create a setting object', function(assert) {
+  assert.expect(2);
+
+  var service = this.subject();
+
+  var setting = service._createSetting('sName', 'sValue');
+
+  assert.equal(setting.get('key.name'), 'sName', 'Settign has the correct 
name');
+  assert.equal(setting.get('value'), 'sValue', 'Settign has the correct 
value');
+
+  service.removeAll();
+});
+
+test('Can create default settings', function(assert) {
+  assert.expect(2);
+
+  var service = this.subject();
+
+  var settings = {
+    'sName1': 'sValue1',
+    'sName2': 'sValue2',
+    'sName3': 'sValue3'
+  };
+
+  service._createDefaultSettings();
+
+  assert.equal(service.get('settings.length'), 0, '0 settings created');
+
+  service._createDefaultSettings(settings);
+
+  assert.equal(service.get('settings.length'), 3, '3 settings created');
+
+  service.removeAll();
+});
+
+test('Can add a setting', function(assert) {
+  assert.expect(2);
+
+  var service = this.subject();
+  assert.equal(service.get('settings.length'), 0, 'No settings');
+  service.add();
+  service.add();
+  assert.equal(service.get('settings.length'), 2, '2 settings added');
+
+  service.removeAll();
+});
+
+test('Can remove a setting', function(assert) {
+  assert.expect(2);
+
+  var service = this.subject();
+
+  service.add();
+  service.add();
+
+  assert.equal(service.get('settings.length'), 2, '2 settings added');
+  var firstSetting = service.get('settings.firstObject');
+  service.remove(firstSetting);
+  assert.equal(service.get('settings.length'), 1, 'Setting removed');
+
+  service.removeAll();
+});
+
+test('Can create key', function(assert) {
+  assert.expect(2);
+  var service = this.subject();
+
+  assert.ok(!service.get('predefinedSettings').findBy('name', 'new.key.name'), 
'Key doesn\'t exist');
+
+  var setting = service._createSetting();
+  setting.set('key', null);
+  service.get('settings').pushObject(setting);
+  service.createKey('new.key.name');
+
+  assert.ok(service.get('predefinedSettings').findBy('name', 'new.key.name'), 
'Key created');
+
+  service.removeAll();
+});
+
+test('Can get settings string', function(assert) {
+  var service = this.subject();
+
+  var noSettings = service.getSettings();
+  assert.equal(noSettings, "", 'An empty string is returned if there are no 
settings');
+
+  var settings = {
+    'sName1': 'sValue1',
+    'sName2': 'sValue2'
+  };
+
+  service._createDefaultSettings(settings);
+
+  var expectedWithSettings = "set sName1=sValue1;\nset 
sName2=sValue2;\n--Global Settings--\n\n";
+  var withSettings = service.getSettings();
+
+  assert.equal(withSettings, expectedWithSettings, 'Returns correct string');
+});
+
+test('It can parse global settings', function(assert) {
+  var service = this.subject();
+
+  assert.ok(!service.parseGlobalSettings(), 'It returns if query or model is 
not passed');
+
+  var settings = {
+    'sName1': 'sValue1',
+    'sName2': 'sValue2'
+  };
+
+
+  var globalSettingsString = "set sName1=sValue1;\nset 
sName2=sValue2;\n--Global Settings--\n\n";
+
+  var model = Ember.Object.create({
+    globalSettings: globalSettingsString
+  });
+
+  var query = Ember.Object.create({
+    fileContent: globalSettingsString + "{{match}}"
+  });
+
+  assert.ok(!service.parseGlobalSettings(query, model), 'It returns if current 
settings don\'t match models global settings');
+
+  service._createDefaultSettings(settings);
+
+  service.parseGlobalSettings(query, model);
+
+  assert.equal(query.get('fileContent'), "{{match}}", 'It parsed global 
settings');
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/2580916a/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/AmbariApi.java
----------------------------------------------------------------------
diff --git 
a/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/AmbariApi.java
 
b/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/AmbariApi.java
index fcf070d..f18448c 100644
--- 
a/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/AmbariApi.java
+++ 
b/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/AmbariApi.java
@@ -118,6 +118,21 @@ public class AmbariApi {
   }
 
   /**
+   * Returns first host with requested component installed
+   * @param requestComponent name of component
+   * @return any hostname of node that contains the component
+   * @throws AmbariApiException
+   */
+  public String getAnyHostWithComponent(String requestComponent) throws 
AmbariApiException {
+    List<String> foundHosts = getHostsWithComponent(requestComponent);
+
+    if (foundHosts.size() == 0) {
+      throw new AmbariApiException("RA100 Host with component " + 
requestComponent + " not found");
+    }
+    return foundHosts.get(0);
+  }
+
+  /**
    * Shortcut for GET method
    * @param path REST API path
    * @return response

http://git-wip-us.apache.org/repos/asf/ambari/blob/2580916a/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/Services.java
----------------------------------------------------------------------
diff --git 
a/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/Services.java
 
b/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/Services.java
index 9ee6628..0b49076 100644
--- 
a/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/Services.java
+++ 
b/contrib/views/utils/src/main/java/org/apache/ambari/view/utils/ambari/Services.java
@@ -22,7 +22,13 @@ import org.apache.ambari.view.ViewContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Utilities for specific Hadoop services and util functions for them
@@ -32,6 +38,7 @@ public class Services {
   public static final String HTTP_ONLY = "HTTP_ONLY";
   public static final String YARN_SITE = "yarn-site";
   public static final String YARN_HTTP_POLICY = "yarn.http.policy";
+  public static final String YARN_RESOURCEMANAGER_HA_ENABLED = 
"yarn.resourcemanager.ha.enabled";
 
   private final AmbariApi ambariApi;
   private ViewContext context;
@@ -55,6 +62,7 @@ public class Services {
     if (ambariApi.isClusterAssociated()) {
       String protocol;
 
+      String haEnabled = 
ambariApi.getCluster().getConfigurationValue(YARN_SITE, 
YARN_RESOURCEMANAGER_HA_ENABLED);
       String httpPolicy = 
ambariApi.getCluster().getConfigurationValue(YARN_SITE, YARN_HTTP_POLICY);
       if (httpPolicy.equals(HTTPS_ONLY)) {
         protocol = "https";
@@ -68,6 +76,10 @@ public class Services {
       }
 
       url = addProtocolIfMissing(url, protocol);
+
+      if (haEnabled != null && haEnabled.equals("true")) {
+        url = getActiveRMUrl(url);
+      }
     } else {
       url = context.getProperties().get("yarn.resourcemanager.url");
       if (!hasProtocol(url)) {
@@ -75,9 +87,42 @@ public class Services {
             "RA070 View is not cluster associated. Resource Manager URL should 
contain protocol.");
       }
     }
+    return removeTrailingSlash(url);
+  }
+
+  private String removeTrailingSlash(String url) {
+    if (url.endsWith("/")) {
+      url = url.substring(0, url.length() - 1);
+    }
     return url;
   }
 
+  public final Pattern refreshHeaderUrlPattern = 
Pattern.compile("^\\d+;\\s*url=(.*)$");
+
+  /**
+   * Returns active RM URL. Makes a request to RM passed as argument.
+   * If response contains Refresh header then passed url was standby RM.
+   * @param url url of random RM
+   * @return url of active RM
+   */
+  private String getActiveRMUrl(String url) {
+    String activeRMUrl = url;
+    try {
+      HttpURLConnection httpURLConnection = context.getURLConnectionProvider().
+          getConnection(url, "GET", (String) null, new HashMap<String, 
String>());
+      String refreshHeader = httpURLConnection.getHeaderField("Refresh");
+      if (refreshHeader != null) { // we hit standby RM
+        Matcher matcher = refreshHeaderUrlPattern.matcher(refreshHeader);
+        if (matcher.find()) {
+          activeRMUrl = matcher.group(1);
+        }
+      }
+    } catch (IOException e) {
+      throw new AmbariApiException("RA110 ResourceManager is not accessible");
+    }
+    return activeRMUrl;
+  }
+
   /**
    * Returns URL to WebHCat in format like 
http://<hostname>:<port>/templeton/v1
    * @return url to WebHCat

Reply via email to