Skip to content

Commit

Permalink
YARN-7091. Rename application to service in yarn-native-services. Con…
Browse files Browse the repository at this point in the history
…tributed by Jian He
  • Loading branch information
billierinaldi authored and jian-he committed Nov 6, 2017
1 parent 2ba38ce commit 40ab068
Show file tree
Hide file tree
Showing 198 changed files with 1,246 additions and 2,150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@
</includes>
</fileSet>
<fileSet>
<directory>hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/target</directory>
<directory>hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/target</directory>
<outputDirectory>/share/hadoop/${hadoop.component}/sources</outputDirectory>
<includes>
<include>*-sources.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/conf</directory>
<directory>hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/conf</directory>
<outputDirectory>etc/hadoop</outputDirectory>
</fileSet>
<fileSet>
<directory>hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-slider/hadoop-yarn-slider-core/target/hadoop-yarn-slider-core-${project.version}</directory>
<outputDirectory>/share/hadoop/${hadoop.component}/lib/slider</outputDirectory>
<directory>hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/target/hadoop-yarn-services-core-${project.version}</directory>
<outputDirectory>/share/hadoop/${hadoop.component}/lib/services</outputDirectory>
</fileSet>
<fileSet>
<directory>hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/target</directory>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>hadoop-yarn-slider-dist</id>
<id>hadoop-yarn-services-dist</id>
<formats>
<format>dir</format>
</formats>
Expand Down
2 changes: 1 addition & 1 deletion hadoop-project/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@

<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-slider-core</artifactId>
<artifactId>hadoop-yarn-services-core</artifactId>
<version>${project.version}</version>
</dependency>

Expand Down
14 changes: 7 additions & 7 deletions hadoop-yarn-project/hadoop-yarn/bin/yarn
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function hadoop_usage
hadoop_add_subcommand "router" daemon "run the Router daemon"
hadoop_add_subcommand "schedulerconf" client "Updates scheduler configuration"
hadoop_add_subcommand "scmadmin" admin "SharedCacheManager admin tools"
hadoop_add_subcommand "servicesapi" "run yarn-native-service rest server"
hadoop_add_subcommand "apiserver" "run yarn-native-service rest server"
hadoop_add_subcommand "sharedcachemanager" daemon "run the SharedCacheManager daemon"
hadoop_add_subcommand "service" "run a service"
hadoop_add_subcommand "timelinereader" client "run the timeline reader server"
Expand Down Expand Up @@ -151,14 +151,14 @@ function yarncmd_case
scmadmin)
HADOOP_CLASSNAME='org.apache.hadoop.yarn.client.SCMAdmin'
;;
servicesapi)
apiserver)
HADOOP_SUBCMD_SUPPORTDAEMONIZATION="true"
hadoop_add_classpath "${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/slider"'/*'
hadoop_add_classpath "${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/services"'/*'
hadoop_add_classpath "${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/services-api"'/*'
HADOOP_CLASSNAME='org.apache.hadoop.yarn.service.webapp.ApplicationApiWebApp'
HADOOP_CLASSNAME='org.apache.hadoop.yarn.service.webapp.ApiServerWebApp'
local sld="${HADOOP_YARN_HOME}/${YARN_DIR},\
${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR},\
${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/slider,\
${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/services,\
${HADOOP_HDFS_HOME}/${HDFS_DIR},\
${HADOOP_HDFS_HOME}/${HDFS_LIB_JARS_DIR},\
${HADOOP_COMMON_HOME}/${HADOOP_COMMON_DIR},\
Expand All @@ -171,11 +171,11 @@ ${HADOOP_COMMON_HOME}/${HADOOP_COMMON_LIB_JARS_DIR}"
HADOOP_CLASSNAME='org.apache.hadoop.yarn.server.sharedcachemanager.SharedCacheManager'
;;
service)
hadoop_add_classpath "${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/slider"'/*'
hadoop_add_classpath "${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/services"'/*'
HADOOP_CLASSNAME='org.apache.hadoop.yarn.service.client.ServiceCLI'
local sld="${HADOOP_YARN_HOME}/${YARN_DIR},\
${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR},\
${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/slider,\
${HADOOP_YARN_HOME}/${YARN_LIB_JARS_DIR}/services,\
${HADOOP_HDFS_HOME}/${HDFS_DIR},\
${HADOOP_HDFS_HOME}/${HDFS_LIB_JARS_DIR},\
${HADOOP_COMMON_HOME}/${HADOOP_COMMON_DIR},\
Expand Down
2 changes: 1 addition & 1 deletion hadoop-yarn-project/hadoop-yarn/conf/yarn-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,4 @@
#
# See ResourceManager for some examples
#
#export YARN_SERVICESAPI_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:${HADOOP_LOG_DIR}/gc-servicesapi.log-$(date +'%Y%m%d%H%M')"
#export YARN_APISERVER_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:${HADOOP_LOG_DIR}/gc-apiserver.log-$(date +'%Y%m%d%H%M')"
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-slider-core</artifactId>
<artifactId>hadoop-yarn-services-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
import org.apache.hadoop.yarn.conf.YarnConfiguration;
import org.apache.hadoop.yarn.exceptions.ApplicationNotFoundException;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.service.api.records.Service;
import org.apache.hadoop.yarn.service.api.records.ServiceState;
import org.apache.hadoop.yarn.service.api.records.ServiceStatus;
import org.apache.hadoop.yarn.service.client.ServiceClient;
import org.apache.hadoop.yarn.service.api.records.Application;
import org.apache.hadoop.yarn.service.api.records.ApplicationState;
import org.apache.hadoop.yarn.service.api.records.ApplicationStatus;
import org.apache.hadoop.yarn.service.api.records.Component;
import org.apache.hadoop.yarn.service.utils.SliderUtils;
import org.apache.hadoop.yarn.service.utils.ServiceApiUtil;
Expand All @@ -51,11 +51,14 @@

import static org.apache.hadoop.yarn.service.conf.RestApiConstants.*;

/**
* The rest API endpoints for users to manage services on YARN.
*/
@Singleton
@Path(CONTEXT_ROOT)
public class ApplicationApiService {
public class ApiServer {
private static final Logger LOG =
LoggerFactory.getLogger(ApplicationApiService.class);
LoggerFactory.getLogger(ApiServer.class);
private static Configuration YARN_CONFIG = new YarnConfiguration();
private static ServiceClient SERVICE_CLIENT;

Expand All @@ -81,105 +84,101 @@ public Response getVersion() {
}

@POST
@Path(APP_ROOT_PATH)
@Path(SERVICE_ROOT_PATH)
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response createApplication(Application application) {
LOG.info("POST: createApplication = {}", application);
ApplicationStatus applicationStatus = new ApplicationStatus();
public Response createService(Service service) {
LOG.info("POST: createService = {}", service);
ServiceStatus serviceStatus = new ServiceStatus();
try {
ApplicationId applicationId = SERVICE_CLIENT.actionCreate(application);
LOG.info("Successfully created application " + application.getName()
ApplicationId applicationId = SERVICE_CLIENT.actionCreate(service);
LOG.info("Successfully created service " + service.getName()
+ " applicationId = " + applicationId);
applicationStatus.setState(ApplicationState.ACCEPTED);
applicationStatus.setUri(
CONTEXT_ROOT + APP_ROOT_PATH + "/" + application
serviceStatus.setState(ServiceState.ACCEPTED);
serviceStatus.setUri(
CONTEXT_ROOT + SERVICE_ROOT_PATH + "/" + service
.getName());
return Response.status(Status.CREATED).entity(applicationStatus).build();
return Response.status(Status.CREATED).entity(serviceStatus).build();
} catch (IllegalArgumentException e) {
applicationStatus.setDiagnostics(e.getMessage());
return Response.status(Status.BAD_REQUEST).entity(applicationStatus)
serviceStatus.setDiagnostics(e.getMessage());
return Response.status(Status.BAD_REQUEST).entity(serviceStatus)
.build();
} catch (Exception e) {
String message = "Failed to create application " + application.getName();
String message = "Failed to create service " + service.getName();
LOG.error(message, e);
applicationStatus.setDiagnostics(message + ": " + e.getMessage());
serviceStatus.setDiagnostics(message + ": " + e.getMessage());
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(applicationStatus).build();
.entity(serviceStatus).build();
}
}

@GET
@Path(APP_PATH)
@Path(SERVICE_PATH)
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response getApplication(@PathParam(APP_NAME) String appName) {
LOG.info("GET: getApplication for appName = {}", appName);
ApplicationStatus applicationStatus = new ApplicationStatus();

// app name validation
if (!SliderUtils.isClusternameValid(appName)) {
applicationStatus.setDiagnostics("Invalid application name: " + appName);
applicationStatus.setCode(ERROR_CODE_APP_NAME_INVALID);
return Response.status(Status.NOT_FOUND).entity(applicationStatus)
.build();
}

public Response getService(@PathParam(SERVICE_NAME) String appName) {
LOG.info("GET: getService for appName = {}", appName);
ServiceStatus serviceStatus = new ServiceStatus();
try {
Application app = SERVICE_CLIENT.getStatus(appName);
Service app = SERVICE_CLIENT.getStatus(appName);
return Response.ok(app).build();
} catch (IllegalArgumentException e) {
serviceStatus.setDiagnostics(e.getMessage());
serviceStatus.setCode(ERROR_CODE_APP_NAME_INVALID);
return Response.status(Status.NOT_FOUND).entity(serviceStatus)
.build();
} catch (Exception e) {
LOG.error("Get application failed", e);
applicationStatus
.setDiagnostics("Failed to retrieve application: " + e.getMessage());
LOG.error("Get service failed", e);
serviceStatus
.setDiagnostics("Failed to retrieve service: " + e.getMessage());
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(applicationStatus).build();
.entity(serviceStatus).build();
}
}

@DELETE
@Path(APP_PATH)
@Path(SERVICE_PATH)
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response deleteApplication(@PathParam(APP_NAME) String appName) {
LOG.info("DELETE: deleteApplication for appName = {}", appName);
return stopApplication(appName, true);
public Response deleteService(@PathParam(SERVICE_NAME) String appName) {
LOG.info("DELETE: deleteService for appName = {}", appName);
return stopService(appName, true);
}

private Response stopApplication(String appName, boolean destroy) {
private Response stopService(String appName, boolean destroy) {
try {
SERVICE_CLIENT.actionStop(appName, destroy);
if (destroy) {
SERVICE_CLIENT.actionDestroy(appName);
LOG.info("Successfully deleted application {}", appName);
LOG.info("Successfully deleted service {}", appName);
} else {
LOG.info("Successfully stopped application {}", appName);
LOG.info("Successfully stopped service {}", appName);
}
return Response.status(Status.NO_CONTENT).build();
} catch (ApplicationNotFoundException e) {
ApplicationStatus applicationStatus = new ApplicationStatus();
applicationStatus.setDiagnostics(
"Application " + appName + " not found " + e.getMessage());
return Response.status(Status.NOT_FOUND).entity(applicationStatus)
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.setDiagnostics(
"Service " + appName + " not found " + e.getMessage());
return Response.status(Status.NOT_FOUND).entity(serviceStatus)
.build();
} catch (Exception e) {
ApplicationStatus applicationStatus = new ApplicationStatus();
applicationStatus.setDiagnostics(e.getMessage());
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.setDiagnostics(e.getMessage());
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(applicationStatus).build();
.entity(serviceStatus).build();
}
}

@PUT
@Path(COMPONENT_PATH)
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN })
public Response updateComponent(@PathParam(APP_NAME) String appName,
public Response updateComponent(@PathParam(SERVICE_NAME) String appName,
@PathParam(COMPONENT_NAME) String componentName, Component component) {

if (component.getNumberOfContainers() < 0) {
return Response.status(Status.BAD_REQUEST).entity(
"Application = " + appName + ", Component = " + component.getName()
"Service = " + appName + ", Component = " + component.getName()
+ ": Invalid number of containers specified " + component
.getNumberOfContainers()).build();
}
Expand All @@ -192,81 +191,81 @@ public Response updateComponent(@PathParam(APP_NAME) String appName,
.get(componentName) + " to " + component.getNumberOfContainers())
.build();
} catch (YarnException | IOException e) {
ApplicationStatus status = new ApplicationStatus();
ServiceStatus status = new ServiceStatus();
status.setDiagnostics(e.getMessage());
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(status)
.build();
}
}

@PUT
@Path(APP_PATH)
@Path(SERVICE_PATH)
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public Response updateApplication(@PathParam(APP_NAME) String appName,
Application updateAppData) {
LOG.info("PUT: updateApplication for app = {} with data = {}", appName,
updateAppData);
public Response updateService(@PathParam(SERVICE_NAME) String appName,
Service updateServiceData) {
LOG.info("PUT: updateService for app = {} with data = {}", appName,
updateServiceData);

// Ignore the app name provided in updateAppData and always use appName
// Ignore the app name provided in updateServiceData and always use appName
// path param
updateAppData.setName(appName);
updateServiceData.setName(appName);

// For STOP the app should be running. If already stopped then this
// operation will be a no-op. For START it should be in stopped state.
// If already running then this operation will be a no-op.
if (updateAppData.getState() != null
&& updateAppData.getState() == ApplicationState.STOPPED) {
return stopApplication(appName, false);
if (updateServiceData.getState() != null
&& updateServiceData.getState() == ServiceState.STOPPED) {
return stopService(appName, false);
}

// If a START is requested
if (updateAppData.getState() != null
&& updateAppData.getState() == ApplicationState.STARTED) {
return startApplication(appName);
if (updateServiceData.getState() != null
&& updateServiceData.getState() == ServiceState.STARTED) {
return startService(appName);
}

// If new lifetime value specified then update it
if (updateAppData.getLifetime() != null
&& updateAppData.getLifetime() > 0) {
return updateLifetime(appName, updateAppData);
if (updateServiceData.getLifetime() != null
&& updateServiceData.getLifetime() > 0) {
return updateLifetime(appName, updateServiceData);
}

// flex a single component app
if (updateAppData.getNumberOfContainers() != null && !ServiceApiUtil
.hasComponent(updateAppData)) {
Component defaultComp = ServiceApiUtil.createDefaultComponent(updateAppData);
return updateComponent(updateAppData.getName(), defaultComp.getName(),
if (updateServiceData.getNumberOfContainers() != null && !ServiceApiUtil
.hasComponent(updateServiceData)) {
Component defaultComp = ServiceApiUtil.createDefaultComponent(updateServiceData);
return updateComponent(updateServiceData.getName(), defaultComp.getName(),
defaultComp);
}

// If nothing happens consider it a no-op
return Response.status(Status.NO_CONTENT).build();
}

private Response updateLifetime(String appName, Application updateAppData) {
private Response updateLifetime(String appName, Service updateAppData) {
try {
String newLifeTime =
SERVICE_CLIENT.updateLifetime(appName, updateAppData.getLifetime());
return Response.ok("Application " + appName + " lifeTime is successfully updated to "
return Response.ok("Service " + appName + " lifeTime is successfully updated to "
+ updateAppData.getLifetime() + " seconds from now: " + newLifeTime).build();
} catch (Exception e) {
String message =
"Failed to update application (" + appName + ") lifetime ("
"Failed to update service (" + appName + ") lifetime ("
+ updateAppData.getLifetime() + ")";
LOG.error(message, e);
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(message + " : " + e.getMessage()).build();
}
}

private Response startApplication(String appName) {
private Response startService(String appName) {
try {
SERVICE_CLIENT.actionStart(appName);
LOG.info("Successfully started application " + appName);
return Response.ok("Application " + appName + " is successfully started").build();
LOG.info("Successfully started service " + appName);
return Response.ok("Service " + appName + " is successfully started").build();
} catch (Exception e) {
String message = "Failed to start application " + appName;
String message = "Failed to start service " + appName;
LOG.info(message, e);
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity(message + ": " + e.getMessage()).build();
Expand Down
Loading

0 comments on commit 40ab068

Please sign in to comment.