瀏覽代碼

AMBARI-5853. Implement apps and app GET endpoint in Slider Apps view. (srimanth)

Srimanth Gunturi 11 年之前
父節點
當前提交
3eec911026

二進制
contrib/views/slider/lib/org/apache/slider/slider/0.30.0/slider-0.30.0.jar


+ 220 - 0
contrib/views/slider/pom.xml

@@ -106,6 +106,218 @@
 			<version>${ambari.version}</version>
 			<version>${ambari.version}</version>
 			<scope>provided</scope>
 			<scope>provided</scope>
 		</dependency>
 		</dependency>
+
+		<!-- ==================================================================== -->
+		<!-- Slider Dependencies (to be removed when Slider has Maven repository) -->
+		<!-- ==================================================================== -->
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-common</artifactId>
+			<version>${hadoop.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>org.codehaus.jackson</groupId>
+					<artifactId>jackson-core-asl</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>net.java.dev.jets3t</groupId>
+					<artifactId>jets3t</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>commons-codec</groupId>
+					<artifactId>commons-codec</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>com.google.guava</groupId>
+					<artifactId>guava</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>commons-net</groupId>
+					<artifactId>commons-net</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>tomcat</groupId>
+					<artifactId>jasper-runtime</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>net.java.dev.jets3t</groupId>
+					<artifactId>jets3t</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.apache.httpcomponents</groupId>
+					<artifactId>httpclient</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.apache.httpcomponents</groupId>
+					<artifactId>httpcore</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-client</artifactId>
+			<version>${hadoop.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-client</artifactId>
+			<version>${hadoop.version}</version>
+			<type>pom</type>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-minicluster</artifactId>
+			<version>${hadoop.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>com.sun.jersey.jersey-test-framework</groupId>
+					<artifactId>jersey-test-framework-grizzly2</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-hdfs</artifactId>
+			<version>${hadoop.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>tomcat</groupId>
+					<artifactId>jasper-runtime</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-common</artifactId>
+			<version>${hadoop.version}</version>
+			<type>test-jar</type>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-yarn-server-common</artifactId>
+			<version>${hadoop.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>com.sun.jersey.jersey-test-framework</groupId>
+					<artifactId>jersey-test-framework-grizzly2</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-yarn-client</artifactId>
+			<version>${hadoop.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>com.sun.jersey.jersey-test-framework</groupId>
+					<artifactId>jersey-test-framework-grizzly2</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-yarn-common</artifactId>
+			<version>${hadoop.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-yarn-server-web-proxy</artifactId>
+			<version>${hadoop.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.hadoop</groupId>
+			<artifactId>hadoop-mapreduce-client</artifactId>
+			<version>${hadoop.version}</version>
+			<type>pom</type>
+			<exclusions>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.avro</groupId>
+			<artifactId>avro</artifactId>
+			<version>${avro.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>org.mortbay.jetty</groupId>
+					<artifactId>jetty</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.apache.ant</groupId>
+					<artifactId>ant</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.jboss.netty</groupId>
+					<artifactId>netty</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.apache.velocity</groupId>
+					<artifactId>velocity</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>slf4j-api</artifactId>
+				</exclusion>
+				<exclusion>
+					<artifactId>paranamer-ant</artifactId>
+					<groupId>com.thoughtworks.paranamer</groupId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.bigtop.itest</groupId>
+			<artifactId>itest-common</artifactId>
+			<version>${bigtop.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>commons-logging</groupId>
+					<artifactId>commons-logging</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>commons-configuration</groupId>
+			<artifactId>commons-configuration</artifactId>
+			<version>${commons-configuration.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>commons-logging</groupId>
+					<artifactId>commons-logging</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>commons-lang</groupId>
+					<artifactId>commons-lang</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>commons-logging</groupId>
+					<artifactId>commons-logging</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+			<version>${commons-lang.version}</version>
+			<exclusions>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpclient</artifactId>
+			<version>${httpclient.version}</version>
+			<exclusions>
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>com.beust</groupId>
+			<artifactId>jcommander</artifactId>
+			<version>${jcommander.version}</version>
+			<exclusions>
+				<exclusion>
+					<groupId>org.testng</groupId>
+					<artifactId>testng</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
 	</dependencies>
 	</dependencies>
 
 
 	<repositories>
 	<repositories>
@@ -122,7 +334,15 @@
 		<npm.version>1.4.3</npm.version>
 		<npm.version>1.4.3</npm.version>
 		<ui.directory>${basedir}/src/main/resources/ui</ui.directory>
 		<ui.directory>${basedir}/src/main/resources/ui</ui.directory>
 		<ambari.version>1.3.0-SNAPSHOT</ambari.version>
 		<ambari.version>1.3.0-SNAPSHOT</ambari.version>
+		<hadoop.version>2.4.0</hadoop.version>
+		<avro.version>1.7.4</avro.version>
+		<bigtop.version>0.7.0</bigtop.version>
+		<commons-configuration.version>1.6</commons-configuration.version>
+		<commons-lang.version>2.6</commons-lang.version>
+		<httpclient.version>4.2.5</httpclient.version>
+		<jcommander.version>1.30</jcommander.version>
 	</properties>
 	</properties>
+
 	<build>
 	<build>
 		<plugins>
 		<plugins>
 			<plugin>
 			<plugin>

+ 101 - 0
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderApp.java

@@ -18,9 +18,22 @@
 
 
 package org.apache.ambari.view.slider;
 package org.apache.ambari.view.slider;
 
 
+import java.util.Map;
+
 public class SliderApp {
 public class SliderApp {
 	private String id;
 	private String id;
+	private String yarnId;
 	private String name;
 	private String name;
+	private String type;
+	private String user;
+	private String state;
+	private String diagnostics;
+	private long startTime;
+	private long endTime;
+	private Map<String, String> jmx;
+	private Map<String, String> urls;
+	private Map<String, Map<String, String>> configs;
+	private Map<String, SliderAppComponent> components;
 
 
 	public String getName() {
 	public String getName() {
 		return name;
 		return name;
@@ -37,4 +50,92 @@ public class SliderApp {
 	public void setId(String id) {
 	public void setId(String id) {
 		this.id = id;
 		this.id = id;
 	}
 	}
+
+	public String getYarnId() {
+		return yarnId;
+	}
+
+	public void setYarnId(String yarnId) {
+		this.yarnId = yarnId;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getUser() {
+		return user;
+	}
+
+	public void setUser(String user) {
+		this.user = user;
+	}
+
+	public String getState() {
+		return state;
+	}
+
+	public void setState(String state) {
+		this.state = state;
+	}
+
+	public String getDiagnostics() {
+		return diagnostics;
+	}
+
+	public void setDiagnostics(String diagnostics) {
+		this.diagnostics = diagnostics;
+	}
+
+	public Map<String, String> getJmx() {
+		return jmx;
+	}
+
+	public void setJmx(Map<String, String> jmx) {
+		this.jmx = jmx;
+	}
+
+	public Map<String, String> getUrls() {
+		return urls;
+	}
+
+	public void setUrls(Map<String, String> urls) {
+		this.urls = urls;
+	}
+
+	public Map<String, Map<String, String>> getConfigs() {
+		return configs;
+	}
+
+	public void setConfigs(Map<String, Map<String, String>> configs) {
+		this.configs = configs;
+	}
+
+	public Map<String, SliderAppComponent> getComponents() {
+		return components;
+	}
+
+	public void setComponents(Map<String, SliderAppComponent> components) {
+		this.components = components;
+	}
+
+	public long getStartTime() {
+		return startTime;
+	}
+
+	public void setStartTime(long startTime) {
+		this.startTime = startTime;
+	}
+
+	public long getEndTime() {
+		return endTime;
+	}
+
+	public void setEndTime(long endTime) {
+		this.endTime = endTime;
+	}
 }
 }

+ 62 - 0
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppComponent.java

@@ -0,0 +1,62 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.slider;
+
+import java.util.Map;
+
+public class SliderAppComponent {
+	private String componentName;
+	private int instanceCount;
+	private Map<String, Map<String, String>> activeContainers;
+	private Map<String, Map<String, String>> completedContainers;
+
+	public String getComponentName() {
+		return componentName;
+	}
+
+	public void setComponentName(String componentName) {
+		this.componentName = componentName;
+	}
+
+	public int getInstanceCount() {
+		return instanceCount;
+	}
+
+	public void setInstanceCount(int instanceCount) {
+		this.instanceCount = instanceCount;
+	}
+
+	public Map<String, Map<String, String>> getActiveContainers() {
+		return activeContainers;
+	}
+
+	public void setActiveContainers(
+	    Map<String, Map<String, String>> activeContainers) {
+		this.activeContainers = activeContainers;
+	}
+
+	public Map<String, Map<String, String>> getCompletedContainers() {
+		return completedContainers;
+	}
+
+	public void setCompletedContainers(
+	    Map<String, Map<String, String>> completedContainers) {
+		this.completedContainers = completedContainers;
+	}
+}

+ 58 - 28
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsResourceProvider.java

@@ -18,6 +18,10 @@
 
 
 package org.apache.ambari.view.slider;
 package org.apache.ambari.view.slider;
 
 
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
 
 
@@ -27,49 +31,75 @@ import org.apache.ambari.view.ResourceAlreadyExistsException;
 import org.apache.ambari.view.ResourceProvider;
 import org.apache.ambari.view.ResourceProvider;
 import org.apache.ambari.view.SystemException;
 import org.apache.ambari.view.SystemException;
 import org.apache.ambari.view.UnsupportedPropertyException;
 import org.apache.ambari.view.UnsupportedPropertyException;
+import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.log4j.Logger;
 
 
 import com.google.inject.Inject;
 import com.google.inject.Inject;
 
 
 public class SliderAppsResourceProvider implements ResourceProvider<SliderApp> {
 public class SliderAppsResourceProvider implements ResourceProvider<SliderApp> {
 
 
+	private static final Logger logger = Logger
+	    .getLogger(SliderAppsResourceProvider.class);
 	@Inject
 	@Inject
-	SliderAppsViewController sliderController;
+	private SliderAppsViewController sliderController;
 
 
 	@Override
 	@Override
-  public void createResource(String resourceId, Map<String, Object> properties)
-      throws SystemException, ResourceAlreadyExistsException,
-      NoSuchResourceException, UnsupportedPropertyException {
-	  // TODO Auto-generated method stub
-  }
+	public void createResource(String resourceId, Map<String, Object> properties)
+	    throws SystemException, ResourceAlreadyExistsException,
+	    NoSuchResourceException, UnsupportedPropertyException {
+		// TODO Auto-generated method stub
+	}
 
 
 	@Override
 	@Override
-  public boolean deleteResource(String resourceId) throws SystemException,
-      NoSuchResourceException, UnsupportedPropertyException {
-	  // TODO Auto-generated method stub
-	  return false;
-  }
+	public boolean deleteResource(String resourceId) throws SystemException,
+	    NoSuchResourceException, UnsupportedPropertyException {
+		// TODO Auto-generated method stub
+		return false;
+	}
 
 
 	@Override
 	@Override
-  public SliderApp getResource(String resourceId, Set<String> properties)
-      throws SystemException, NoSuchResourceException,
-      UnsupportedPropertyException {
-	  // TODO Auto-generated method stub
-	  return null;
-  }
+	public SliderApp getResource(String resourceId, Set<String> properties)
+	    throws SystemException, NoSuchResourceException,
+	    UnsupportedPropertyException {
+		try {
+			SliderApp sliderApp = sliderController.getSliderApp(resourceId);
+			if (sliderApp == null)
+				throw new NoSuchResourceException(resourceId);
+			return sliderApp;
+		} catch (YarnException e) {
+			logger.warn("Unable to determine Slider app with id " + resourceId, e);
+			throw new SystemException(e.getMessage(), e);
+		} catch (IOException e) {
+			logger.warn("Unable to determine Slider app with id " + resourceId, e);
+			throw new SystemException(e.getMessage(), e);
+		}
+	}
 
 
 	@Override
 	@Override
-  public Set<SliderApp> getResources(ReadRequest request) throws SystemException,
-      NoSuchResourceException, UnsupportedPropertyException {
-	  // TODO Auto-generated method stub
-	  return null;
-  }
+	public Set<SliderApp> getResources(ReadRequest request)
+	    throws SystemException, NoSuchResourceException,
+	    UnsupportedPropertyException {
+		Set<SliderApp> appSet = new HashSet<SliderApp>();
+		try {
+			List<SliderApp> sliderApps = sliderController.getSliderApps();
+			for (SliderApp app : sliderApps)
+				appSet.add(app);
+		} catch (YarnException e) {
+			logger.warn("Unable to determine Slider apps", e);
+			throw new SystemException(e.getMessage(), e);
+		} catch (IOException e) {
+			logger.warn("Unable to determine Slider apps", e);
+			throw new SystemException(e.getMessage(), e);
+		}
+		return appSet;
+	}
 
 
 	@Override
 	@Override
-  public boolean updateResource(String resourceId, Map<String, Object> properties)
-      throws SystemException, NoSuchResourceException,
-      UnsupportedPropertyException {
-	  // TODO Auto-generated method stub
-	  return false;
-  }
+	public boolean updateResource(String resourceId,
+	    Map<String, Object> properties) throws SystemException,
+	    NoSuchResourceException, UnsupportedPropertyException {
+		// TODO Auto-generated method stub
+		return false;
+	}
 
 
 }
 }

+ 5 - 2
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewController.java

@@ -18,8 +18,11 @@
 
 
 package org.apache.ambari.view.slider;
 package org.apache.ambari.view.slider;
 
 
+import java.io.IOException;
 import java.util.List;
 import java.util.List;
 
 
+import org.apache.hadoop.yarn.exceptions.YarnException;
+
 import com.google.inject.ImplementedBy;
 import com.google.inject.ImplementedBy;
 
 
 @ImplementedBy(SliderAppsViewControllerImpl.class)
 @ImplementedBy(SliderAppsViewControllerImpl.class)
@@ -27,7 +30,7 @@ public interface SliderAppsViewController {
 
 
 	public ViewStatus getViewStatus();
 	public ViewStatus getViewStatus();
 
 
-	public SliderApp getSliderApp(String applicationId);
+	public SliderApp getSliderApp(String applicationId) throws YarnException, IOException;
 
 
-	public List<SliderApp> getSliderApps();
+	public List<SliderApp> getSliderApps() throws YarnException, IOException;
 }
 }

+ 146 - 5
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/SliderAppsViewControllerImpl.java

@@ -18,6 +18,7 @@
 
 
 package org.apache.ambari.view.slider;
 package org.apache.ambari.view.slider;
 
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
@@ -26,8 +27,17 @@ import org.apache.ambari.view.ViewContext;
 import org.apache.ambari.view.slider.clients.AmbariClient;
 import org.apache.ambari.view.slider.clients.AmbariClient;
 import org.apache.ambari.view.slider.clients.AmbariCluster;
 import org.apache.ambari.view.slider.clients.AmbariCluster;
 import org.apache.ambari.view.slider.clients.AmbariClusterInfo;
 import org.apache.ambari.view.slider.clients.AmbariClusterInfo;
+import org.apache.ambari.view.slider.clients.AmbariHostComponent;
+import org.apache.ambari.view.slider.clients.AmbariService;
 import org.apache.ambari.view.slider.clients.AmbariServiceInfo;
 import org.apache.ambari.view.slider.clients.AmbariServiceInfo;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hdfs.HdfsConfiguration;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ApplicationReport;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.exceptions.YarnException;
 import org.apache.log4j.Logger;
 import org.apache.log4j.Logger;
+import org.apache.slider.client.SliderClient;
 
 
 import com.google.inject.Inject;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.google.inject.Singleton;
@@ -119,16 +129,147 @@ public class SliderAppsViewControllerImpl implements SliderAppsViewController {
 		return status;
 		return status;
 	}
 	}
 
 
-	@Override
-	public SliderApp getSliderApp(String applicationId) {
-		// TODO Auto-generated method stub
+	private AmbariCluster getAmbariCluster() {
+		AmbariClusterInfo clusterInfo = ambariClient.getClusterInfo();
+		if (clusterInfo != null)
+			return ambariClient.getCluster(clusterInfo);
 		return null;
 		return null;
 	}
 	}
 
 
 	@Override
 	@Override
-	public List<SliderApp> getSliderApps() {
-		// TODO Auto-generated method stub
+	public SliderApp getSliderApp(String applicationId) 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 {
+					ApplicationReport yarnApp = getSliderClient().getApplicationReport(
+					    appId);
+					return mapToSliderApp(yarnApp);
+				} finally {
+					Thread.currentThread().setContextClassLoader(currentClassLoader);
+				}
+			}
+		}
+		return null;
+	}
+
+	private SliderApp mapToSliderApp(ApplicationReport yarnApp) {
+		if (yarnApp == null)
+			return null;
+		SliderApp app = new SliderApp();
+		app.setId(Long.toString(yarnApp.getApplicationId().getClusterTimestamp())
+		    + "_" + Integer.toString(yarnApp.getApplicationId().getId()));
+		app.setName(yarnApp.getName());
+		app.setUser(yarnApp.getUser());
+		app.setState(yarnApp.getYarnApplicationState().name());
+		app.setDiagnostics(yarnApp.getDiagnostics());
+		app.setYarnId(yarnApp.getApplicationId().toString());
+		app.setType(yarnApp.getApplicationType());
+		app.setStartTime(yarnApp.getStartTime());
+		app.setEndTime(yarnApp.getFinishTime());
+		return app;
+	}
+
+	/**
+	 * Creates a new {@link SliderClient} initialized with appropriate
+	 * configuration. If configuration was not determined, <code>null</code> is
+	 * returned.
+	 * 
+	 * @return
+	 */
+	protected SliderClient getSliderClient() {
+		Configuration sliderClientConfiguration = getSliderClientConfiguration();
+		if (sliderClientConfiguration != null) {
+			SliderClient client = new SliderClient();
+			try {
+				sliderClientConfiguration = client.bindArgs(sliderClientConfiguration,
+				    new String[] { "usage" });
+			} catch (Exception e) {
+				logger.warn("Unable to set SliderClient configs", e);
+				throw new RuntimeException(e.getMessage(), e);
+			}
+			client.init(sliderClientConfiguration);
+			client.start();
+			return client;
+		}
 		return null;
 		return null;
 	}
 	}
 
 
+	/**
+	 * 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");
+			if (zkService != null && ambariCluster.getDesiredConfigs() != null
+			    && ambariCluster.getDesiredConfigs().containsKey("global")
+			    && ambariCluster.getDesiredConfigs().containsKey("yarn-site")
+			    && ambariCluster.getDesiredConfigs().containsKey("core-site")) {
+				Map<String, String> globalConfigs = ambariClient.getConfiguration(
+				    ambariCluster, "global",
+				    ambariCluster.getDesiredConfigs().get("yarn-site"));
+				Map<String, String> yarnSiteConfigs = ambariClient.getConfiguration(
+				    ambariCluster, "yarn-site",
+				    ambariCluster.getDesiredConfigs().get("yarn-site"));
+				Map<String, String> coreSiteConfigs = ambariClient.getConfiguration(
+				    ambariCluster, "core-site",
+				    ambariCluster.getDesiredConfigs().get("core-site"));
+				String zkPort = globalConfigs.get("clientPort");
+				String hdfsPath = coreSiteConfigs.get("fs.defaultFS");
+				String rmAddress = yarnSiteConfigs.get("yarn.resourcemanager.address");
+				String rmSchedulerAddress = yarnSiteConfigs
+				    .get("yarn.resourcemanager.scheduler.address");
+				StringBuilder zkQuorum = new StringBuilder();
+				List<AmbariHostComponent> zkHosts = zkService
+				    .getComponentsToHostComponentsMap().get("ZOOKEEPER_SERVER");
+				for (AmbariHostComponent zkHost : zkHosts) {
+					if (zkQuorum.length() > 0)
+						zkQuorum.append(',');
+					zkQuorum.append(zkHost.getHostName() + ":" + zkPort);
+				}
+				HdfsConfiguration hdfsConfig = new HdfsConfiguration();
+				YarnConfiguration yarnConfig = new YarnConfiguration(hdfsConfig);
+
+				yarnConfig.set("slider.yarn.queue", "default");
+				yarnConfig.set("yarn.log-aggregation-enable", "true");
+				yarnConfig.set("yarn.resourcemanager.address", rmAddress);
+				yarnConfig.set("yarn.resourcemanager.scheduler.address",
+				    rmSchedulerAddress);
+				yarnConfig.set("fs.defaultFS", hdfsPath);
+				yarnConfig.set("slider.zookeeper.quorum", zkQuorum.toString());
+				return yarnConfig;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public List<SliderApp> getSliderApps() throws YarnException, IOException {
+		List<SliderApp> sliderApps = new ArrayList<SliderApp>();
+		ClassLoader currentClassLoader = Thread.currentThread()
+		    .getContextClassLoader();
+		Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+		try {
+			List<ApplicationReport> yarnApps = getSliderClient().getApplications();
+			for (ApplicationReport yarnApp : yarnApps) {
+				sliderApps.add(mapToSliderApp(yarnApp));
+			}
+		} finally {
+			Thread.currentThread().setContextClassLoader(currentClassLoader);
+		}
+		return sliderApps;
+	}
 }
 }

+ 25 - 3
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/clients/AmbariClient.java

@@ -24,9 +24,6 @@ import com.google.inject.ImplementedBy;
 
 
 @ImplementedBy(AmbariInternalClient.class)
 @ImplementedBy(AmbariInternalClient.class)
 public interface AmbariClient {
 public interface AmbariClient {
-
-	public AmbariCluster getCluster(AmbariClusterInfo clusterInfo);
-
 	/**
 	/**
 	 * Provides the first cluster defined on this Ambari server.
 	 * Provides the first cluster defined on this Ambari server.
 	 * 
 	 * 
@@ -34,6 +31,31 @@ public interface AmbariClient {
 	 */
 	 */
 	public AmbariClusterInfo getClusterInfo();
 	public AmbariClusterInfo getClusterInfo();
 
 
+	/**
+	 * Provides detailed information about the given cluster.
+	 * 
+	 * @param clusterInfo
+	 * @return
+	 */
+	public AmbariCluster getCluster(AmbariClusterInfo clusterInfo);
+
+	/**
+	 * Provides configs identified by type and tag on given cluster.
+	 * 
+	 * @param cluster
+	 * @param configType
+	 * @param configTag
+	 * @return
+	 */
 	public Map<String, String> getConfiguration(AmbariClusterInfo cluster,
 	public Map<String, String> getConfiguration(AmbariClusterInfo cluster,
 	    String configType, String configTag);
 	    String configType, String configTag);
+
+	/**
+	 * Provides detailed information about the given service.
+	 * 
+	 * @param cluster
+	 * @param serviceId
+	 * @return
+	 */
+	public AmbariService getService(AmbariClusterInfo cluster, String serviceId);
 }
 }

+ 49 - 0
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/clients/AmbariHostComponent.java

@@ -0,0 +1,49 @@
+/**
+ * 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.
+ */
+
+package org.apache.ambari.view.slider.clients;
+
+public class AmbariHostComponent {
+	private String name;
+	private boolean started;
+	private String hostName;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getHostName() {
+		return hostName;
+	}
+
+	public void setHostName(String hostName) {
+		this.hostName = hostName;
+	}
+
+	public boolean isStarted() {
+		return started;
+	}
+
+	public void setStarted(boolean started) {
+		this.started = started;
+	}
+}

+ 83 - 0
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/clients/AmbariInternalClient.java

@@ -91,6 +91,8 @@ public class AmbariInternalClient implements AmbariClient {
 					    "ServiceInfo/service_name").toString());
 					    "ServiceInfo/service_name").toString());
 					service.setStarted(State.STARTED.toString().equals(
 					service.setStarted(State.STARTED.toString().equals(
 					    serviceResource.getPropertyValue("ServiceInfo/state")));
 					    serviceResource.getPropertyValue("ServiceInfo/state")));
+					service.setMaintenanceMode("ON".equals(serviceResource
+					    .getPropertyValue("ServiceInfo/maintenance_state")));
 					servicesList.add(service);
 					servicesList.add(service);
 				}
 				}
 				for (Resource hostResource : hostResources) {
 				for (Resource hostResource : hostResources) {
@@ -206,4 +208,85 @@ public class AmbariInternalClient implements AmbariClient {
 		return null;
 		return null;
 	}
 	}
 
 
+	@Override
+	public AmbariService getService(AmbariClusterInfo clusterInfo,
+	    String serviceId) {
+		ClusterController clusterController = ClusterControllerHelper
+		    .getClusterController();
+		try {
+			EqualsPredicate<String> clusterPredicate = new EqualsPredicate<String>(
+			    "ServiceInfo/cluster_name", clusterInfo.getName());
+			EqualsPredicate<String> servicePredicate = new EqualsPredicate<String>(
+			    "ServiceInfo/service_name", serviceId);
+			AndPredicate andPredicate = new AndPredicate(clusterPredicate,
+			    servicePredicate);
+			Set<Resource> serviceResources = clusterController.getResources(
+			    Resource.Type.Service, PropertyHelper.getReadRequest(), andPredicate);
+			if (!serviceResources.isEmpty()) {
+				Resource serviceResource = serviceResources.iterator().next();
+				AmbariService service = new AmbariService();
+				service.setId(serviceResource.getPropertyValue(
+				    "ServiceInfo/service_name").toString());
+				service.setStarted(State.STARTED.toString().equals(
+				    serviceResource.getPropertyValue("ServiceInfo/state")));
+				service.setMaintenanceMode("ON".equals(serviceResource
+				    .getPropertyValue("ServiceInfo/maintenance_state")));
+				// Components
+				Map<String, List<AmbariHostComponent>> componentsMap = new HashMap<String, List<AmbariHostComponent>>();
+				service.setComponentsToHostComponentsMap(componentsMap);
+				clusterPredicate = new EqualsPredicate<String>(
+				    "ServiceComponentInfo/cluster_name", clusterInfo.getName());
+				servicePredicate = new EqualsPredicate<String>(
+				    "ServiceComponentInfo/service_name", serviceId);
+				andPredicate = new AndPredicate(clusterPredicate, servicePredicate);
+				Set<Resource> componentResources = clusterController.getResources(
+				    Resource.Type.Component, PropertyHelper.getReadRequest(),
+				    andPredicate);
+				if (!componentResources.isEmpty()) {
+					for (Resource componentResouce : componentResources) {
+						List<AmbariHostComponent> hostComponents = new ArrayList<AmbariHostComponent>();
+						String componentName = componentResouce.getPropertyValue(
+						    "ServiceComponentInfo/component_name").toString();
+						componentsMap.put(componentName, hostComponents);
+						clusterPredicate = new EqualsPredicate<String>(
+						    "HostRoles/cluster_name", clusterInfo.getName());
+						EqualsPredicate<String> componentPredicate = new EqualsPredicate<String>(
+						    "HostRoles/component_name", componentName);
+						andPredicate = new AndPredicate(clusterPredicate,
+						    componentPredicate);
+						Set<Resource> hostComponentResources = clusterController
+						    .getResources(Resource.Type.HostComponent,
+						        PropertyHelper.getReadRequest(), andPredicate);
+						if (!hostComponentResources.isEmpty()) {
+							for (Resource hostComponentResource : hostComponentResources) {
+								AmbariHostComponent hc = new AmbariHostComponent();
+								hc.setHostName(hostComponentResource.getPropertyValue(
+								    "HostRoles/host_name").toString());
+								hc.setName(hostComponentResource.getPropertyValue(
+								    "HostRoles/component_name").toString());
+								hc.setStarted(State.STARTED.toString().equals(
+								    hostComponentResource.getPropertyValue("HostRoles/state")
+								        .toString()));
+								hostComponents.add(hc);
+							}
+						}
+					}
+				}
+				return service;
+			}
+		} catch (UnsupportedPropertyException e) {
+			logger.warn("Unable to determine service details - " + serviceId, e);
+			throw new RuntimeException(e.getMessage(), e);
+		} catch (NoSuchResourceException e) {
+			logger.warn("Unable to determine service details - " + serviceId, e);
+			throw new RuntimeException(e.getMessage(), e);
+		} catch (NoSuchParentResourceException e) {
+			logger.warn("Unable to determine service details - " + serviceId, e);
+			throw new RuntimeException(e.getMessage(), e);
+		} catch (SystemException e) {
+			logger.warn("Unable to determine service details - " + serviceId, e);
+			throw new RuntimeException(e.getMessage(), e);
+		}
+		return null;
+	}
 }
 }

+ 36 - 0
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/clients/AmbariService.java

@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.slider.clients;
+
+import java.util.List;
+import java.util.Map;
+
+public class AmbariService extends AmbariServiceInfo {
+
+	private Map<String, List<AmbariHostComponent>> componentsToHostComponentsMap;
+
+	public Map<String, List<AmbariHostComponent>> getComponentsToHostComponentsMap() {
+		return componentsToHostComponentsMap;
+	}
+
+	public void setComponentsToHostComponentsMap(
+	    Map<String, List<AmbariHostComponent>> componentsToHostComponentsMap) {
+		this.componentsToHostComponentsMap = componentsToHostComponentsMap;
+	}
+}

+ 9 - 0
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/clients/AmbariServiceInfo.java

@@ -22,6 +22,7 @@ public class AmbariServiceInfo {
 
 
 	private String id;
 	private String id;
 	private boolean started;
 	private boolean started;
+	private boolean maintenanceMode;
 
 
 	public String getId() {
 	public String getId() {
 		return id;
 		return id;
@@ -39,4 +40,12 @@ public class AmbariServiceInfo {
 	  this.started = started;
 	  this.started = started;
   }
   }
 
 
+	public boolean isMaintenanceMode() {
+	  return maintenanceMode;
+  }
+
+	public void setMaintenanceMode(boolean maintenanceMode) {
+	  this.maintenanceMode = maintenanceMode;
+  }
+
 }
 }

+ 26 - 2
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/SliderAppsResource.java

@@ -18,13 +18,37 @@
 
 
 package org.apache.ambari.view.slider.rest;
 package org.apache.ambari.view.slider.rest;
 
 
-import org.apache.ambari.view.slider.SliderAppsResourceProvider;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.view.ViewResourceHandler;
 
 
 import com.google.inject.Inject;
 import com.google.inject.Inject;
 
 
 public class SliderAppsResource {
 public class SliderAppsResource {
 
 
 	@Inject
 	@Inject
-	SliderAppsResourceProvider resourceHandler;
+	ViewResourceHandler resourceHandler;
+
+	@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);
+	}
 
 
 }
 }

+ 8 - 1
contrib/views/slider/src/main/java/org/apache/ambari/view/slider/rest/client/AmbariHttpClient.java

@@ -28,6 +28,7 @@ import org.apache.ambari.view.slider.clients.AmbariClient;
 import org.apache.ambari.view.slider.clients.AmbariCluster;
 import org.apache.ambari.view.slider.clients.AmbariCluster;
 import org.apache.ambari.view.slider.clients.AmbariClusterInfo;
 import org.apache.ambari.view.slider.clients.AmbariClusterInfo;
 import org.apache.ambari.view.slider.clients.AmbariHostInfo;
 import org.apache.ambari.view.slider.clients.AmbariHostInfo;
+import org.apache.ambari.view.slider.clients.AmbariService;
 import org.apache.ambari.view.slider.clients.AmbariServiceInfo;
 import org.apache.ambari.view.slider.clients.AmbariServiceInfo;
 import org.apache.commons.httpclient.HttpException;
 import org.apache.commons.httpclient.HttpException;
 import org.apache.log4j.Logger;
 import org.apache.log4j.Logger;
@@ -46,7 +47,7 @@ public class AmbariHttpClient extends BaseHttpClient implements AmbariClient {
 
 
 	/**
 	/**
 	 * Provides the first cluster defined on this Ambari server.
 	 * Provides the first cluster defined on this Ambari server.
-	 *
+	 * 
 	 * @return
 	 * @return
 	 */
 	 */
 	public AmbariClusterInfo getClusterInfo() {
 	public AmbariClusterInfo getClusterInfo() {
@@ -140,4 +141,10 @@ public class AmbariHttpClient extends BaseHttpClient implements AmbariClient {
 		return null;
 		return null;
 	}
 	}
 
 
+	@Override
+	public AmbariService getService(AmbariClusterInfo cluster, String serviceId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
 }
 }