You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sr...@apache.org on 2014/05/29 01:43:47 UTC
git commit: AMBARI-5918. Implement Slider app api to freeze and thaw
an application. (onechiporenko, srimanth)
Repository: ambari
Updated Branches:
refs/heads/trunk 1064ade01 -> 53e3d8dd0
AMBARI-5918. Implement Slider app api to freeze and thaw an application. (onechiporenko, srimanth)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/53e3d8dd
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/53e3d8dd
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/53e3d8dd
Branch: refs/heads/trunk
Commit: 53e3d8dd018e694a79982179f9f5fabffd275369
Parents: 1064ade
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Wed May 28 15:18:47 2014 -0700
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Wed May 28 16:37:59 2014 -0700
----------------------------------------------------------------------
.../view/slider/SliderAppsViewController.java | 9 +-
.../slider/SliderAppsViewControllerImpl.java | 63 +++++++++++++
.../view/slider/rest/SliderAppsResource.java | 37 +++++++-
.../ui/app/controllers/slider_app_controller.js | 93 +++++++++++++++++++-
.../src/main/resources/ui/app/helpers/ajax.js | 32 ++++++-
.../src/main/resources/ui/app/initialize.js | 7 ++
.../src/main/resources/ui/app/routes/main.js | 6 +-
7 files changed, 234 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/53e3d8dd/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java
index 83b641e..823fea6 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java
@@ -74,5 +74,12 @@ public interface SliderAppsViewController {
public List<SliderAppType> getSliderAppTypes(Set<String> properties);
- public String createSliderApp(JsonObject requestJson) throws IOException, YarnException, InterruptedException;
+ public String createSliderApp(JsonObject requestJson) throws IOException,
+ YarnException, InterruptedException;
+
+ public void freezeApp(String appId) throws YarnException, IOException,
+ InterruptedException;
+
+ public void thawApp(String appId) throws YarnException, IOException,
+ InterruptedException;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/53e3d8dd/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
index 679fa3a..4ccc51b 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java
@@ -62,6 +62,8 @@ import org.apache.slider.api.ClusterDescription;
import org.apache.slider.client.SliderClient;
import org.apache.slider.common.SliderKeys;
import org.apache.slider.common.params.ActionCreateArgs;
+import org.apache.slider.common.params.ActionFreezeArgs;
+import org.apache.slider.common.params.ActionThawArgs;
import org.apache.slider.common.tools.SliderFileSystem;
import org.apache.slider.core.exceptions.UnknownApplicationInstanceException;
import org.apache.slider.core.main.LauncherExitCodes;
@@ -486,6 +488,10 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
rmSchedulerAddress);
yarnConfig.set("fs.defaultFS", hdfsPath);
yarnConfig.set("slider.zookeeper.quorum", zkQuorum.toString());
+ yarnConfig
+ .set(
+ "yarn.application.classpath",
+ "/etc/hadoop/conf,/usr/lib/hadoop/*,/usr/lib/hadoop/lib/*,/usr/lib/hadoop-hdfs/*,/usr/lib/hadoop-hdfs/lib/*,/usr/lib/hadoop-yarn/*,/usr/lib/hadoop-yarn/lib/*,/usr/lib/hadoop-mapreduce/*,/usr/lib/hadoop-mapreduce/lib/*");
return yarnConfig;
}
}
@@ -802,4 +808,61 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
fos.close();
}
}
+
+ @Override
+ public void freezeApp(String appId) throws YarnException, IOException,
+ InterruptedException {
+ ClassLoader currentClassLoader = Thread.currentThread()
+ .getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ Set<String> properties = new HashSet<String>();
+ properties.add("id");
+ properties.add("name");
+ final SliderApp sliderApp = getSliderApp(appId, properties);
+ if (sliderApp == null)
+ throw new ApplicationNotFoundException(appId);
+
+ ApplicationId applicationId = UserGroupInformation.getBestUGI(null,
+ "yarn").doAs(new PrivilegedExceptionAction<ApplicationId>() {
+ public ApplicationId run() throws IOException, YarnException {
+ SliderClient sliderClient = getSliderClient();
+ ActionFreezeArgs freezeArgs = new ActionFreezeArgs();
+ sliderClient.actionFreeze(sliderApp.getName(), freezeArgs);
+ return sliderClient.applicationId;
+ }
+ });
+ logger.debug("Slider app has been frozen - " + applicationId.toString());
+ } finally {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+
+ @Override
+ public void thawApp(String appId) throws YarnException, IOException,
+ InterruptedException {
+ ClassLoader currentClassLoader = Thread.currentThread()
+ .getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ Set<String> properties = new HashSet<String>();
+ properties.add("id");
+ properties.add("name");
+ final SliderApp sliderApp = getSliderApp(appId, properties);
+ if (sliderApp == null)
+ throw new ApplicationNotFoundException(appId);
+ ApplicationId applicationId = UserGroupInformation.getBestUGI(null,
+ "yarn").doAs(new PrivilegedExceptionAction<ApplicationId>() {
+ public ApplicationId run() throws IOException, YarnException {
+ SliderClient sliderClient = getSliderClient();
+ ActionThawArgs thawArgs = new ActionThawArgs();
+ sliderClient.actionThaw(sliderApp.getName(), thawArgs);
+ return sliderClient.applicationId;
+ }
+ });
+ logger.debug("Slider app has been thawed - " + applicationId.toString());
+ } finally {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/53e3d8dd/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java
index 30b9f3b..4459db2 100644
--- a/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java
+++ b/contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java
@@ -26,6 +26,7 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -41,6 +42,7 @@ import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.log4j.Logger;
import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.inject.Inject;
@@ -74,8 +76,37 @@ public class SliderAppsResource {
sliderAppsViewController.deleteSliderApp(appId);
}
+ @PUT
+ @Path("{appId}")
+ @Consumes({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
+ public Response updateApp(@Context UriInfo uri, String jsonString,
+ @PathParam("appId") String appId) throws IOException, YarnException,
+ InterruptedException, URISyntaxException {
+ if (jsonString != null) {
+ JsonElement requestContent = new JsonParser().parse(jsonString);
+ if (requestContent != null && appId != null) {
+ JsonObject requestJson = requestContent.getAsJsonObject();
+ if (requestJson.has("state")) {
+ String newState = requestJson.get("state").getAsString();
+ if ("FROZEN".equals(newState))
+ sliderAppsViewController.freezeApp(appId);
+ else if ("RUNNING".equals(newState))
+ sliderAppsViewController.thawApp(appId);
+ } else if (requestJson.has("components")) {
+ }
+ }
+ String sliderApp = sliderAppsViewController
+ .createSliderApp(requestContent.getAsJsonObject());
+ if (sliderApp != null)
+ return Response.created(new URI(uri.getAbsolutePath() + sliderApp))
+ .build();
+ }
+ logger.warn("No request content sent to create app");
+ return Response.status(Response.Status.BAD_REQUEST).build();
+ }
+
@POST
- @Consumes({ MediaType.TEXT_PLAIN })
+ @Consumes({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
public Response createApp(@Context UriInfo uri, String jsonString)
throws IOException, YarnException, InterruptedException,
URISyntaxException {
@@ -84,8 +115,8 @@ public class SliderAppsResource {
String sliderApp = sliderAppsViewController
.createSliderApp(requestContent.getAsJsonObject());
if (sliderApp != null)
- return Response.created(
- new URI(uri.getAbsolutePath() + "/" + sliderApp)).build();
+ return Response.created(new URI(uri.getAbsolutePath() + sliderApp))
+ .build();
}
logger.warn("No request content sent to create app");
return Response.status(Response.Status.BAD_REQUEST).build();
http://git-wip-us.apache.org/repos/asf/ambari/blob/53e3d8dd/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
index 6a383c5..06af9f3 100644
--- a/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
+++ b/contrib/views/slider/src/main/resources/ui/app/controllers/slider_app_controller.js
@@ -83,12 +83,99 @@ App.SliderAppController = Ember.ObjectController.extend({
this[currentAction]();
},
- thaw: Ember.K,
- freeze: Ember.K,
- flex: Ember.K,
+ /**
+ * Do request to <strong>thaw</strong> current slider's app
+ * @returns {$.ajax}
+ * @method freeze
+ */
+ thaw: function() {
+ var model = this.get('model');
+ return App.ajax.send({
+ name: 'changeAppState',
+ sender: this,
+ data: {
+ id: model.get('id'),
+ data: {
+ id: model.get('id'),
+ name: model.get('name'),
+ state: "RUNNING"
+ }
+ }
+ });
+ },
/**
* Do request to delete current slider's app
+ * Do request to <strong>freeze</strong> current slider's app
+ * @returns {$.ajax}
+ * @method freeze
+ */
+ freeze: function() {
+ var model = this.get('model');
+ return App.ajax.send({
+ name: 'changeAppState',
+ sender: this,
+ data: {
+ id: model.get('id'),
+ data: {
+ id: model.get('id'),
+ name: model.get('name'),
+ state: "FROZEN"
+ }
+ }
+ });
+ },
+
+ /**
+ * Do request to <strong>flex</strong> current slider's app
+ * @returns {$.ajax}
+ * @method flex
+ */
+ flex: function() {
+ var model = this.get('model');
+ return App.ajax.send({
+ name: 'flexApp',
+ sender: this,
+ data: {
+ id: model.get('id'),
+ data: {
+ id: model.get('id'),
+ name: model.get('name'),
+ components: this.mapComponentsForFlexRequest()
+ }
+ }
+ });
+ },
+
+ /**
+ * Map <code>model.components</code> for Flex request
+ * Output format:
+ * <code>
+ * {
+ * COMPONENT_NAME_1: {
+ * instanceCount: 1
+ * },
+ * COMPONENT_NAME_2: {
+ * instanceCount: 2
+ * },
+ * ....
+ * }
+ * </code>
+ * @returns {object}
+ * @method mapComponentsForFlexRequest
+ */
+ mapComponentsForFlexRequest: function() {
+ var components = {};
+ this.get('model.components').forEach(function(component) {
+ components[component.get('name')] = {
+ instanceCount: component.get('defaultNumInstances')
+ }
+ });
+ return components;
+ },
+
+ /**
+ * Do request to <strong>delete</strong> current slider's app
* @return {$.ajax}
* @method destroy
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/53e3d8dd/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
index 05e78db..66b97bd 100644
--- a/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
+++ b/contrib/views/slider/src/main/resources/ui/app/helpers/ajax.js
@@ -56,6 +56,9 @@ var urls = {
'createNewApp': {
real: 'apps',
mock: '',
+ headers: {
+ "Content-Type": "text/plain; charset=utf-8"
+ },
format: function(data) {
return {
type: 'POST',
@@ -72,6 +75,33 @@ var urls = {
method: 'DELETE'
}
}
+ },
+
+ 'changeAppState': {
+ real: 'apps/{id}',
+ mock: '',
+ headers: {
+ "Content-Type": "text/plain; charset=utf-8"
+ },
+ format: function(data) {
+ return {
+ method: 'PUT',
+ data: JSON.stringify(data.data)
+ }
+ }
+ },
+ 'flexApp': {
+ real: 'apps/{id}',
+ mock: '',
+ headers: {
+ "Content-Type": "text/plain; charset=utf-8"
+ },
+ format: function(data) {
+ return {
+ method: 'PUT',
+ data: JSON.stringify(data.data)
+ }
+ }
}
};
/**
@@ -110,7 +140,7 @@ var formatRequest = function (data) {
type: this.type || 'GET',
dataType: 'json',
async: true,
- headers: this.headers || {accepts: "application/json; charset=utf-8"}
+ headers: this.headers || {Accept: "application/json; charset=utf-8"}
};
if (App.get('testMode')) {
opt.url = formatUrl(this.mock ? this.mock : '', data);
http://git-wip-us.apache.org/repos/asf/ambari/blob/53e3d8dd/contrib/views/slider/src/main/resources/ui/app/initialize.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/initialize.js b/contrib/views/slider/src/main/resources/ui/app/initialize.js
index 73f4c6f..cc22ba2 100755
--- a/contrib/views/slider/src/main/resources/ui/app/initialize.js
+++ b/contrib/views/slider/src/main/resources/ui/app/initialize.js
@@ -102,4 +102,11 @@ folderOrder.forEach(function(folder) {
}).forEach(function(module) {
require(module);
});
+});
+
+$.ajaxSetup({
+ cache : false,
+ headers : {
+ "X-Requested-By" : "X-Requested-By"
+ }
});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/53e3d8dd/contrib/views/slider/src/main/resources/ui/app/routes/main.js
----------------------------------------------------------------------
diff --git a/contrib/views/slider/src/main/resources/ui/app/routes/main.js b/contrib/views/slider/src/main/resources/ui/app/routes/main.js
index 07babda..f875ffa 100644
--- a/contrib/views/slider/src/main/resources/ui/app/routes/main.js
+++ b/contrib/views/slider/src/main/resources/ui/app/routes/main.js
@@ -18,10 +18,6 @@
App.IndexRoute = Ember.Route.extend({
- model: function () {
- return this.modelFor('sliderApps');
- },
-
redirect: function () {
this.transitionTo('slider_apps');
}
@@ -44,7 +40,7 @@ App.SliderAppsRoute = Ember.Route.extend({
App.SliderAppRoute = Ember.Route.extend({
model: function(params) {
- return this.store.all('sliderApp', params.slider_app_id);
+ return this.store.find('sliderApp', params.slider_app_id);
}
});
\ No newline at end of file