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/27 22:38:52 UTC
git commit: AMBARI-5903. Implement POST method on the apps endpoint -
to create new apps. (srimanth)
Repository: ambari
Updated Branches:
refs/heads/trunk 66d8d5bf7 -> c7736445d
AMBARI-5903. Implement POST method on the apps endpoint - to create new apps. (srimanth)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c7736445
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c7736445
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c7736445
Branch: refs/heads/trunk
Commit: c7736445d5feb6a19eb31c7692cfdab4e60e1941
Parents: 66d8d5b
Author: Srimanth Gunturi <sg...@hortonworks.com>
Authored: Tue May 27 13:13:24 2014 -0700
Committer: Srimanth Gunturi <sg...@hortonworks.com>
Committed: Tue May 27 13:13:24 2014 -0700
----------------------------------------------------------------------
contrib/views/slider/pom.xml | 79 +++--
.../view/slider/SliderAppsViewController.java | 79 ++---
.../slider/SliderAppsViewControllerImpl.java | 316 ++++++++++++++-----
.../view/slider/rest/SliderAppsResource.java | 69 ++--
pom.xml | 3 +
5 files changed, 384 insertions(+), 162 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7736445/contrib/views/slider/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/slider/pom.xml b/contrib/views/slider/pom.xml
index 13a4d9d..1bcd294 100644
--- a/contrib/views/slider/pom.xml
+++ b/contrib/views/slider/pom.xml
@@ -111,6 +111,37 @@
<!-- Slider Dependencies (to be removed when Slider has Maven repository) -->
<!-- ==================================================================== -->
<dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-client</artifactId>
+ <version>${curator.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-framework</artifactId>
+ <version>${curator.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-x-discovery</artifactId>
+ <version>${curator.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.curator</groupId>
+ <artifactId>curator-x-discovery-server</artifactId>
+ <version>${curator.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.zookeeper</groupId>
+ <artifactId>zookeeper</artifactId>
+ <version>${zookeeper.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
@@ -341,6 +372,8 @@
<commons-lang.version>2.6</commons-lang.version>
<httpclient.version>4.2.5</httpclient.version>
<jcommander.version>1.30</jcommander.version>
+ <curator.version>2.4.1</curator.version>
+ <zookeeper.version>3.4.5</zookeeper.version>
</properties>
<build>
@@ -446,29 +479,29 @@
</plugin>
</plugins>
<resources>
- <resource>
- <directory>src/main/resources</directory>
- <filtering>true</filtering>
- <includes>
- <include>slider.properties</include>
- </includes>
- </resource>
- <resource>
- <directory>src/main/resources/</directory>
- <filtering>false</filtering>
- <includes>
- <include>view.xml</include>
- </includes>
- </resource>
- <resource>
- <directory>src/main/resources/ui/public</directory>
- <filtering>false</filtering>
- </resource>
- <resource>
- <targetPath>WEB-INF/lib</targetPath>
- <filtering>false</filtering>
- <directory>target/lib</directory>
- </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <includes>
+ <include>slider.properties</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources/</directory>
+ <filtering>false</filtering>
+ <includes>
+ <include>view.xml</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources/ui/public</directory>
+ <filtering>false</filtering>
+ </resource>
+ <resource>
+ <targetPath>WEB-INF/lib</targetPath>
+ <filtering>false</filtering>
+ <directory>target/lib</directory>
+ </resource>
</resources>
<pluginManagement>
<plugins>
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7736445/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 da66a3b..83b641e 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
@@ -24,52 +24,55 @@ import java.util.Set;
import org.apache.hadoop.yarn.exceptions.YarnException;
+import com.google.gson.JsonObject;
import com.google.inject.ImplementedBy;
@ImplementedBy(SliderAppsViewControllerImpl.class)
public interface SliderAppsViewController {
- public ViewStatus getViewStatus();
+ public ViewStatus getViewStatus();
- /**
- * Provides information about requested Slider App.
- *
- * @param applicationId
- * @param properties
- * Identifies specific properties to show up. Provide
- * <code>null</code> for default properties.
- * @return
- * @throws YarnException
- * @throws IOException
- */
- public SliderApp getSliderApp(String applicationId, Set<String> properties)
- throws YarnException, IOException;
+ /**
+ * Provides information about requested Slider App.
+ *
+ * @param applicationId
+ * @param properties
+ * Identifies specific properties to show up. Provide
+ * <code>null</code> for default properties.
+ * @return
+ * @throws YarnException
+ * @throws IOException
+ */
+ public SliderApp getSliderApp(String applicationId, Set<String> properties)
+ throws YarnException, IOException;
- /**
- * Provides list of Slider apps with requested properties populated.
- *
- * @param properties
- * Identifies specific properties to show up. Provide
- * <code>null</code> for default properties.
- * @return
- * @throws YarnException
- * @throws IOException
- */
- public List<SliderApp> getSliderApps(Set<String> properties)
- throws YarnException, IOException;
+ /**
+ * Provides list of Slider apps with requested properties populated.
+ *
+ * @param properties
+ * Identifies specific properties to show up. Provide
+ * <code>null</code> for default properties.
+ * @return
+ * @throws YarnException
+ * @throws IOException
+ */
+ public List<SliderApp> getSliderApps(Set<String> properties)
+ throws YarnException, IOException;
- /**
- * Attempts to delete a Slider app. An unsuccessful attempt will result in
- * exception.
- *
- * @param applicationId
- * @throws YarnException
- * @throws IOException
- */
- public void deleteSliderApp(String applicationId) throws YarnException,
- IOException;
+ /**
+ * Attempts to delete a Slider app. An unsuccessful attempt will result in
+ * exception.
+ *
+ * @param applicationId
+ * @throws YarnException
+ * @throws IOException
+ */
+ public void deleteSliderApp(String applicationId) throws YarnException,
+ IOException;
- public SliderAppType getSliderAppType(String appTypeId, Set<String> properties);
+ public SliderAppType getSliderAppType(String appTypeId, Set<String> properties);
- public List<SliderAppType> getSliderAppTypes(Set<String> properties);
+ public List<SliderAppType> getSliderAppTypes(Set<String> properties);
+
+ public String createSliderApp(JsonObject requestJson) throws IOException, YarnException, InterruptedException;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7736445/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 c67e9ce..1947e1d 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
@@ -18,11 +18,22 @@
package org.apache.ambari.view.slider;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.zip.ZipException;
+
import org.apache.ambari.view.ViewContext;
import org.apache.ambari.view.slider.clients.AmbariClient;
import org.apache.ambari.view.slider.clients.AmbariCluster;
@@ -37,7 +48,9 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.RegexFileFilter;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.HdfsConfiguration;
+import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.api.records.ApplicationId;
import org.apache.hadoop.yarn.api.records.ApplicationReport;
import org.apache.hadoop.yarn.api.records.YarnApplicationState;
@@ -48,6 +61,7 @@ import org.apache.log4j.Logger;
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.tools.SliderFileSystem;
import org.apache.slider.core.exceptions.UnknownApplicationInstanceException;
import org.apache.slider.core.main.LauncherExitCodes;
@@ -59,19 +73,13 @@ import org.apache.tools.zip.ZipFile;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.zip.ZipException;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
@Singleton
public class SliderAppsViewControllerImpl implements SliderAppsViewController {
@@ -84,10 +92,16 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
private AmbariClient ambariClient;
private List<SliderAppType> appTypes;
+ private Integer createAppCounter = -1;
+
private String getAppsFolderPath() {
return viewContext
- .getAmbariProperty(org.apache.ambari.server.configuration.Configuration.RESOURCES_DIR_KEY)
- + "/apps";
+ .getAmbariProperty(org.apache.ambari.server.configuration.Configuration.RESOURCES_DIR_KEY)
+ + "/apps";
+ }
+
+ private String getAppsCreateFolderPath() {
+ return getAppsFolderPath() + "/create";
}
@Override
@@ -175,33 +189,45 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
return null;
}
+ private String getApplicationIdString(ApplicationId appId) {
+ return Long.toString(appId.getClusterTimestamp()) + "_"
+ + Integer.toString(appId.getId());
+ }
+
+ private ApplicationId getApplicationId(String appIdString) {
+ if (appIdString != null) {
+ int index = appIdString.indexOf('_');
+ if (index > -1 && index < appIdString.length() - 1) {
+ ApplicationId appId = ApplicationId.newInstance(
+ Long.parseLong(appIdString.substring(0, index)),
+ Integer.parseInt(appIdString.substring(index + 1)));
+ return appId;
+ }
+ }
+ return null;
+ }
+
@Override
public SliderApp getSliderApp(String applicationId, Set<String> properties)
throws YarnException, IOException {
- if (applicationId != null) {
- int index = applicationId.indexOf('_');
- if (index > -1 && index < applicationId.length() - 1) {
- ApplicationId appId = ApplicationId.newInstance(
- Long.parseLong(applicationId.substring(0, index)),
- Integer.parseInt(applicationId.substring(index + 1)));
- ClassLoader currentClassLoader = Thread.currentThread()
- .getContextClassLoader();
- Thread.currentThread().setContextClassLoader(
- getClass().getClassLoader());
- try {
- SliderClient sliderClient = getSliderClient();
- ApplicationReport yarnApp = sliderClient.getApplicationReport(appId);
- return createSliderAppObject(yarnApp, properties, sliderClient);
- } finally {
- Thread.currentThread().setContextClassLoader(currentClassLoader);
- }
+ ApplicationId appId = getApplicationId(applicationId);
+ if (appId != null) {
+ ClassLoader currentClassLoader = Thread.currentThread()
+ .getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ SliderClient sliderClient = getSliderClient();
+ ApplicationReport yarnApp = sliderClient.getApplicationReport(appId);
+ return createSliderAppObject(yarnApp, properties, sliderClient);
+ } finally {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
}
}
return null;
}
private SliderApp createSliderAppObject(ApplicationReport yarnApp,
- Set<String> properties, SliderClient sliderClient) {
+ Set<String> properties, SliderClient sliderClient) {
if (yarnApp == null) {
return null;
}
@@ -229,8 +255,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
}
}
- app.setId(Long.toString(yarnApp.getApplicationId().getClusterTimestamp())
- + "_" + Integer.toString(yarnApp.getApplicationId().getId()));
+ app.setId(getApplicationIdString(yarnApp.getApplicationId()));
app.setName(yarnApp.getName());
app.setUser(yarnApp.getUser());
app.setDiagnostics(yarnApp.getDiagnostics());
@@ -267,10 +292,11 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
if (quickLinks != null && quickLinks.containsKey("JMX")) {
String jmxUrl = quickLinks.get("JMX");
List<SliderAppType> appTypes = getSliderAppTypes(null);
- if(appTypes != null && appTypes.size() > 0) {
+ if (appTypes != null && appTypes.size() > 0) {
// TODO: Get the correct app type based on name and version
SliderAppType appType = appTypes.get(0);
- app.setJmx(sliderAppClient.getJmx(jmxUrl, viewContext, appType));
+ app.setJmx(sliderAppClient.getJmx(jmxUrl, viewContext,
+ appType));
}
}
Map<String, Map<String, String>> configs = sliderAppClient
@@ -286,10 +312,8 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
Map<String, SliderAppComponent> componentTypeMap = new HashMap<String, SliderAppComponent>();
for (Entry<String, Object> e : description.status.entrySet()) {
@SuppressWarnings("unchecked")
- Map<String, Map<String, Map<String, Object>>>
- componentsObj =
- (Map<String, Map<String, Map<String, Object>>>) e
- .getValue();
+ Map<String, Map<String, Map<String, Object>>> componentsObj = (Map<String, Map<String, Map<String, Object>>>) e
+ .getValue();
boolean isLive = "live".equals(e.getKey());
for (Entry<String, Map<String, Map<String, Object>>> componentEntry : componentsObj
.entrySet()) {
@@ -303,7 +327,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
appComponent
.setCompletedContainers(new HashMap<String, Map<String, String>>());
componentTypeMap.put(componentEntry.getKey(),
- appComponent);
+ appComponent);
}
for (Entry<String, Map<String, Object>> containerEntry : componentEntry
.getValue().entrySet()) {
@@ -316,19 +340,19 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
Object containerPropertyValue = containerValues
.get(containerProperty);
containerDataMap.put(containerProperty,
- containerPropertyValue.toString());
+ containerPropertyValue.toString());
}
if (isLive) {
appComponent.getActiveContainers().put(containerId,
- containerDataMap);
+ containerDataMap);
} else {
appComponent.getCompletedContainers().put(
containerId, containerDataMap);
}
}
appComponent.setInstanceCount(appComponent
- .getActiveContainers().size()
- + appComponent.getCompletedContainers().size());
+ .getActiveContainers().size()
+ + appComponent.getCompletedContainers().size());
}
}
app.setComponents(componentTypeMap);
@@ -336,16 +360,16 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
} catch (UnknownApplicationInstanceException e) {
logger.warn(
"Unable to determine app components for "
- + yarnApp.getName(), e);
+ + yarnApp.getName(), e);
} catch (YarnException e) {
logger.warn(
"Unable to determine app components for "
- + yarnApp.getName(), e);
+ + yarnApp.getName(), e);
throw new RuntimeException(e.getMessage(), e);
} catch (IOException e) {
logger.warn(
"Unable to determine app components for "
- + yarnApp.getName(), e);
+ + yarnApp.getName(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
@@ -357,9 +381,10 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
}
/**
- * Creates a new {@link SliderClient} initialized with appropriate configuration. If configuration was not determined,
- * <code>null</code> is returned.
- *
+ * Creates a new {@link SliderClient} initialized with appropriate
+ * configuration. If configuration was not determined, <code>null</code> is
+ * returned.
+ *
* @return
*/
protected SliderClient getSliderClient() {
@@ -368,7 +393,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
SliderClient client = new SliderClient() {
@Override
public String getUsername() throws IOException {
- return null;
+ return "yarn";
}
@Override
@@ -376,7 +401,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
super.serviceInit(conf);
// Override the default FS client to set the super user.
FileSystem fs = FileSystem.get(FileSystem.getDefaultUri(getConfig()),
- getConfig(), "yarn");
+ getConfig(), "yarn");
SliderFileSystem fileSystem = new SliderFileSystem(fs, getConfig());
Field fsField = SliderClient.class
.getDeclaredField("sliderFileSystem");
@@ -386,7 +411,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
};
try {
sliderClientConfiguration = client.bindArgs(sliderClientConfiguration,
- new String[]{"usage"});
+ new String[] { "usage" });
} catch (Exception e) {
logger.warn("Unable to set SliderClient configs", e);
throw new RuntimeException(e.getMessage(), e);
@@ -399,15 +424,16 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
}
/**
- * Dynamically determines Slider client configuration. If unable to determine, <code>null</code> is returned.
- *
+ * Dynamically determines Slider client configuration. If unable to determine,
+ * <code>null</code> is returned.
+ *
* @return
*/
private Configuration getSliderClientConfiguration() {
AmbariCluster ambariCluster = getAmbariCluster();
if (ambariCluster != null) {
AmbariService zkService = ambariClient.getService(ambariCluster,
- "ZOOKEEPER");
+ "ZOOKEEPER");
if (zkService != null && ambariCluster.getDesiredConfigs() != null
&& ambariCluster.getDesiredConfigs().containsKey("global")
&& ambariCluster.getDesiredConfigs().containsKey("yarn-site")
@@ -442,7 +468,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
yarnConfig.set("yarn.log-aggregation-enable", "true");
yarnConfig.set("yarn.resourcemanager.address", rmAddress);
yarnConfig.set("yarn.resourcemanager.scheduler.address",
- rmSchedulerAddress);
+ rmSchedulerAddress);
yarnConfig.set("fs.defaultFS", hdfsPath);
yarnConfig.set("slider.zookeeper.quorum", zkQuorum.toString());
return yarnConfig;
@@ -463,7 +489,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
List<ApplicationReport> yarnApps = sliderClient.listSliderInstances(null);
for (ApplicationReport yarnApp : yarnApps) {
SliderApp sliderAppObject = createSliderAppObject(yarnApp, properties,
- sliderClient);
+ sliderClient);
if (sliderAppObject != null) {
sliderApps.add(sliderAppObject);
}
@@ -530,7 +556,7 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
try {
ZipFile zipFile = new ZipFile(appZip);
Metainfo metainfo = new MetainfoParser().parse(zipFile
- .getInputStream(zipFile.getEntry("metainfo.xml")));
+ .getInputStream(zipFile.getEntry("metainfo.xml")));
// Create app type object
if (metainfo.getServices() != null
&& metainfo.getServices().size() > 0) {
@@ -571,11 +597,11 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
// appTypeComponent.setPriority(component.);
if (component.getMinInstanceCount() != null) {
appTypeComponent.setInstanceCount(Integer.parseInt(component
- .getMinInstanceCount()));
+ .getMinInstanceCount()));
}
if (component.getMaxInstanceCount() != null) {
appTypeComponent.setMaxInstanceCount(Integer
- .parseInt(component.getMaxInstanceCount()));
+ .parseInt(component.getMaxInstanceCount()));
}
if (resourcesJson != null) {
JsonElement componentJson = resourcesJson.getAsJsonObject()
@@ -583,10 +609,10 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
.get(component.getName());
if (componentJson != null
&& componentJson.getAsJsonObject().has(
- "yarn.role.priority")) {
+ "yarn.role.priority")) {
appTypeComponent.setPriority(Integer.parseInt(componentJson
- .getAsJsonObject().get("yarn.role.priority")
- .getAsString()));
+ .getAsJsonObject().get("yarn.role.priority")
+ .getAsString()));
}
}
appTypeComponent.setCategory(component.getCategory());
@@ -594,7 +620,8 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
}
appType.setJmxMetrics(readMetrics(zipFile, "jmx_metrics.json"));
- appType.setGangliaMetrics(readMetrics(zipFile, "ganglia_metrics.json"));
+ appType.setGangliaMetrics(readMetrics(zipFile,
+ "ganglia_metrics.json"));
appType.setTypeComponents(appTypeComponentList);
appTypes.add(appType);
@@ -610,21 +637,152 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
return appTypes;
}
- Map<String, Map<String, Map<String, Metric>>> readMetrics(ZipFile zipFile, String fileName) {
+ Map<String, Map<String, Map<String, Metric>>> readMetrics(ZipFile zipFile,
+ String fileName) {
Map<String, Map<String, Map<String, Metric>>> metrics = null;
try {
- InputStream inputStream =
- zipFile.getInputStream(zipFile.getEntry("jmx_metrics.json"));
+ InputStream inputStream = zipFile.getInputStream(zipFile
+ .getEntry("jmx_metrics.json"));
ObjectMapper mapper = new ObjectMapper();
- metrics =
- mapper.readValue(inputStream,
- new TypeReference<Map<String, Map<String, Map<String, Metric>>>>() {
- });
+ metrics = mapper.readValue(inputStream,
+ new TypeReference<Map<String, Map<String, Map<String, Metric>>>>() {
+ });
} catch (IOException e) {
logger.info("Error reading metrics. " + e.getMessage());
}
return metrics;
}
+
+ @Override
+ public String createSliderApp(JsonObject json) throws IOException,
+ YarnException, InterruptedException {
+ if (json.has("name") && json.has("typeConfigs")
+ && json.has("typeComponents")) {
+ final String appName = json.get("name").getAsString();
+ JsonObject configs = json.get("typeConfigs").getAsJsonObject();
+ JsonArray componentsArray = json.get("typeComponents").getAsJsonArray();
+ String appsCreateFolderPath = getAppsCreateFolderPath();
+ File appsCreateFolder = new File(appsCreateFolderPath);
+ if (!appsCreateFolder.exists())
+ appsCreateFolder.mkdirs();
+ int appCount;
+ synchronized (createAppCounter) {
+ if (createAppCounter < 0) {
+ // Not initialized
+ createAppCounter = 0;
+ String[] apps = appsCreateFolder.list();
+ for (String app : apps) {
+ try {
+ int count = Integer.parseInt(app);
+ if (count > createAppCounter)
+ createAppCounter = count;
+ } catch (NumberFormatException e) {
+ }
+ }
+ }
+ appCount = ++createAppCounter;
+ }
+ File appCreateFolder = new File(appsCreateFolder,
+ Integer.toString(appCount));
+ appCreateFolder.mkdirs();
+ File appConfigJsonFile = new File(appCreateFolder, "appConfig.json");
+ File resourcesJsonFile = new File(appCreateFolder, "resources.json");
+ saveAppConfigs(configs, componentsArray, appConfigJsonFile);
+ saveAppResources(componentsArray, resourcesJsonFile);
+
+ AmbariClusterInfo clusterInfo = ambariClient.getClusterInfo();
+ AmbariCluster cluster = ambariClient.getCluster(clusterInfo);
+ Map<String, String> coreSiteConfigs = ambariClient.getConfiguration(
+ clusterInfo, "core-site", cluster.getDesiredConfigs()
+ .get("core-site"));
+ String hdfsLocation = coreSiteConfigs.get("fs.defaultFS");
+ final ActionCreateArgs createArgs = new ActionCreateArgs();
+ createArgs.template = appConfigJsonFile;
+ createArgs.resources = resourcesJsonFile;
+ createArgs.image = new Path(hdfsLocation
+ + "/slider/agent/slider-agent.tar.gz");
+
+ ClassLoader currentClassLoader = Thread.currentThread()
+ .getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ ApplicationId applicationId = UserGroupInformation.getBestUGI(null,
+ "yarn").doAs(new PrivilegedExceptionAction<ApplicationId>() {
+ public ApplicationId run() throws IOException, YarnException {
+ SliderClient sliderClient = getSliderClient();
+ sliderClient.actionCreate(appName, createArgs);
+ return sliderClient.applicationId;
+ }
+ });
+ if (applicationId != null)
+ return getApplicationIdString(applicationId);
+ } finally {
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+ return null;
+ }
+
+ private void saveAppResources(JsonArray componentsArray,
+ File resourcesJsonFile) throws IOException {
+ JsonObject resourcesObj = new JsonObject();
+ resourcesObj.addProperty("schema",
+ "http://example.org/specification/v2.0.0");
+ resourcesObj.add("metadata", new JsonObject());
+ resourcesObj.add("global", new JsonObject());
+ JsonObject componentsObj = new JsonObject();
+ if (componentsArray != null) {
+ for (int i = 0; i < componentsArray.size(); i++) {
+ JsonObject inputComponent = componentsArray.get(i).getAsJsonObject();
+ if (inputComponent.has("id")) {
+ JsonObject componentValue = new JsonObject();
+ componentValue.addProperty("yarn.role.priority",
+ inputComponent.get("priority").getAsString());
+ componentValue.addProperty("yarn.component.instances", inputComponent
+ .get("instanceCount").getAsString());
+ componentsObj.add(inputComponent.get("id").getAsString(),
+ componentValue);
+ }
+ }
+ }
+ resourcesObj.add("components", componentsObj);
+ String jsonString = new Gson().toJson(resourcesObj);
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(resourcesJsonFile);
+ IOUtils.write(jsonString, fos);
+ } finally {
+ if (fos != null)
+ fos.close();
+ }
+ }
+
+ private void saveAppConfigs(JsonObject configs, JsonArray componentsArray,
+ File appConfigJsonFile) throws IOException {
+ JsonObject appConfigs = new JsonObject();
+ appConfigs.addProperty("schema", "http://example.org/specification/v2.0.0");
+ appConfigs.add("metadata", new JsonObject());
+ appConfigs.add("global", configs);
+ JsonObject componentsObj = new JsonObject();
+ if (componentsArray != null) {
+ for (int i = 0; i < componentsArray.size(); i++) {
+ JsonObject inputComponent = componentsArray.get(i).getAsJsonObject();
+ if (inputComponent.has("id"))
+ componentsObj.add(inputComponent.get("id").getAsString(),
+ new JsonObject());
+ }
+ }
+ appConfigs.add("components", componentsObj);
+ String jsonString = new Gson().toJson(appConfigs);
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(appConfigJsonFile);
+ IOUtils.write(jsonString, fos);
+ } finally {
+ if (fos != null)
+ fos.close();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7736445/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 a221610..30b9f3b 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
@@ -19,9 +19,13 @@
package org.apache.ambari.view.slider.rest;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -34,35 +38,56 @@ import javax.ws.rs.core.UriInfo;
import org.apache.ambari.view.ViewResourceHandler;
import org.apache.ambari.view.slider.SliderAppsViewController;
import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.log4j.Logger;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
import com.google.inject.Inject;
public class SliderAppsResource {
- @Inject
- ViewResourceHandler resourceHandler;
- @Inject
- SliderAppsViewController sliderAppsViewController;
+ private static final Logger logger = Logger
+ .getLogger(SliderAppsResource.class);
+ @Inject
+ ViewResourceHandler resourceHandler;
+ @Inject
+ SliderAppsViewController sliderAppsViewController;
- @GET
- @Produces({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
- public Response getApps(@Context HttpHeaders headers, @Context UriInfo uri) {
- return resourceHandler.handleRequest(headers, uri, null);
- }
+ @GET
+ @Produces({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
+ public Response getApps(@Context HttpHeaders headers, @Context UriInfo uri) {
+ return resourceHandler.handleRequest(headers, uri, null);
+ }
- @GET
- @Path("{appId}")
- @Produces({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
- public Response getApp(@Context HttpHeaders headers, @Context UriInfo uri,
- @PathParam("appId") String appId) {
- return resourceHandler.handleRequest(headers, uri, appId);
- }
+ @GET
+ @Path("{appId}")
+ @Produces({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
+ public Response getApp(@Context HttpHeaders headers, @Context UriInfo uri,
+ @PathParam("appId") String appId) {
+ return resourceHandler.handleRequest(headers, uri, appId);
+ }
- @DELETE
- @Path("{appId}")
- public void deleteApp(@Context HttpHeaders headers, @Context UriInfo uri,
- @PathParam("appId") String appId) throws YarnException, IOException {
- sliderAppsViewController.deleteSliderApp(appId);
- }
+ @DELETE
+ @Path("{appId}")
+ public void deleteApp(@Context HttpHeaders headers, @Context UriInfo uri,
+ @PathParam("appId") String appId) throws YarnException, IOException {
+ sliderAppsViewController.deleteSliderApp(appId);
+ }
+ @POST
+ @Consumes({ MediaType.TEXT_PLAIN })
+ public Response createApp(@Context UriInfo uri, String jsonString)
+ throws IOException, YarnException, InterruptedException,
+ URISyntaxException {
+ if (jsonString != null) {
+ JsonElement requestContent = new JsonParser().parse(jsonString);
+ 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();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c7736445/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 214e0b3..2d47548 100644
--- a/pom.xml
+++ b/pom.xml
@@ -213,6 +213,9 @@
<exclude>contrib/views/slider/src/main/resources/ui/app/assets/javascripts/modernizr-2.6.2.min.js</exclude>
<exclude>contrib/addons/package/deb/nagios_addon_deb_control</exclude>
<exclude>contrib/addons/src/addOns/nagios/conf.d/hdp_mon_nagios_addons.conf</exclude>
+ <exclude>contrib/views/*/.classpath</exclude>
+ <exclude>contrib/views/*/.project</exclude>
+ <exclude>contrib/views/*/.settings/**</exclude>
</excludes>
</configuration>
<executions>