You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by ar...@apache.org on 2018/05/22 20:14:54 UTC

[26/50] [abbrv] hadoop git commit: YARN-7530. Refactored YARN service API project location. Contributed by Chandni Singh

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/TestApiServer.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/TestApiServer.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/TestApiServer.java
deleted file mode 100644
index 733b9bc..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/TestApiServer.java
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hadoop.yarn.service;
-
-import static org.junit.Assert.*;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Path;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-
-import com.google.common.collect.Sets;
-import org.apache.commons.io.FileUtils;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.yarn.service.api.records.Artifact;
-import org.apache.hadoop.yarn.service.api.records.Artifact.TypeEnum;
-import org.apache.hadoop.yarn.service.api.records.Component;
-import org.apache.hadoop.yarn.service.api.records.ComponentState;
-import org.apache.hadoop.yarn.service.api.records.Container;
-import org.apache.hadoop.yarn.service.api.records.ContainerState;
-import org.apache.hadoop.yarn.service.api.records.Resource;
-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.conf.RestApiConstants;
-import org.apache.hadoop.yarn.service.webapp.ApiServer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-/**
- * Test case for ApiServer REST API.
- *
- */
-public class TestApiServer {
-  private ApiServer apiServer;
-  private HttpServletRequest request;
-  private ServiceClientTest mockServerClient;
-
-  @Before
-  public void setup() throws Exception {
-    request = Mockito.mock(HttpServletRequest.class);
-    Mockito.when(request.getRemoteUser())
-        .thenReturn(System.getProperty("user.name"));
-    mockServerClient = new ServiceClientTest();
-    Configuration conf = new Configuration();
-    conf.set("yarn.api-service.service.client.class",
-        ServiceClientTest.class.getName());
-    apiServer = new ApiServer(conf);
-    apiServer.setServiceClient(mockServerClient);
-  }
-
-  @After
-  public void teardown() {
-    mockServerClient.forceStop();
-  }
-
-  @Test
-  public void testPathAnnotation() {
-    assertNotNull(this.apiServer.getClass().getAnnotation(Path.class));
-    assertTrue("The controller has the annotation Path",
-        this.apiServer.getClass().isAnnotationPresent(Path.class));
-    final Path path = this.apiServer.getClass()
-        .getAnnotation(Path.class);
-    assertEquals("The path has /v1 annotation", "/v1", path.value());
-  }
-
-  @Test
-  public void testGetVersion() {
-    final Response actual = apiServer.getVersion();
-    assertEquals("Version number is", Response.ok().build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testBadCreateService() {
-    Service service = new Service();
-    // Test for invalid argument
-    final Response actual = apiServer.createService(request, service);
-    assertEquals("Create service is ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testGoodCreateService() throws Exception {
-    String json = "{\"auths\": "
-        + "{\"https://index.docker.io/v1/\": "
-        + "{\"auth\": \"foobarbaz\"},"
-        + "\"registry.example.com\": "
-        + "{\"auth\": \"bazbarfoo\"}}}";
-    File dockerTmpDir = new File("target", "docker-tmp");
-    FileUtils.deleteQuietly(dockerTmpDir);
-    dockerTmpDir.mkdirs();
-    String dockerConfig = dockerTmpDir + "/config.json";
-    BufferedWriter bw = new BufferedWriter(new FileWriter(dockerConfig));
-    bw.write(json);
-    bw.close();
-    Service service = ServiceClientTest.buildGoodService();
-    final Response actual = apiServer.createService(request, service);
-    assertEquals("Create service is ",
-        Response.status(Status.ACCEPTED).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testInternalServerErrorDockerClientConfigMissingCreateService() {
-    Service service = new Service();
-    service.setName("jenkins");
-    service.setVersion("v1");
-    service.setDockerClientConfig("/does/not/exist/config.json");
-    Artifact artifact = new Artifact();
-    artifact.setType(TypeEnum.DOCKER);
-    artifact.setId("jenkins:latest");
-    Resource resource = new Resource();
-    resource.setCpus(1);
-    resource.setMemory("2048");
-    List<Component> components = new ArrayList<>();
-    Component c = new Component();
-    c.setName("jenkins");
-    c.setNumberOfContainers(1L);
-    c.setArtifact(artifact);
-    c.setLaunchCommand("");
-    c.setResource(resource);
-    components.add(c);
-    service.setComponents(components);
-    final Response actual = apiServer.createService(request, service);
-    assertEquals("Create service is ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testBadGetService() {
-    final String serviceName = "nonexistent-jenkins";
-    final Response actual = apiServer.getService(request, serviceName);
-    assertEquals("Get service is ",
-        Response.status(Status.NOT_FOUND).build().getStatus(),
-        actual.getStatus());
-    ServiceStatus serviceStatus = (ServiceStatus) actual.getEntity();
-    assertEquals("Response code don't match",
-        RestApiConstants.ERROR_CODE_APP_NAME_INVALID, serviceStatus.getCode());
-    assertEquals("Response diagnostics don't match",
-        "Service " + serviceName + " not found",
-        serviceStatus.getDiagnostics());
-  }
-
-  @Test
-  public void testBadGetService2() {
-    final Response actual = apiServer.getService(request, null);
-    assertEquals("Get service is ",
-        Response.status(Status.NOT_FOUND).build().getStatus(),
-        actual.getStatus());
-    ServiceStatus serviceStatus = (ServiceStatus) actual.getEntity();
-    assertEquals("Response code don't match",
-        RestApiConstants.ERROR_CODE_APP_NAME_INVALID, serviceStatus.getCode());
-    assertEquals("Response diagnostics don't match",
-        "Service name cannot be null.", serviceStatus.getDiagnostics());
-  }
-
-  @Test
-  public void testGoodGetService() {
-    final Response actual = apiServer.getService(request, "jenkins");
-    assertEquals("Get service is ",
-        Response.status(Status.OK).build().getStatus(), actual.getStatus());
-  }
-
-  @Test
-  public void testBadDeleteService() {
-    final Response actual = apiServer.deleteService(request, "no-jenkins");
-    assertEquals("Delete service is ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testBadDeleteService2() {
-    final Response actual = apiServer.deleteService(request, null);
-    assertEquals("Delete service is ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testBadDeleteService3() {
-    final Response actual = apiServer.deleteService(request,
-        "jenkins-doesn't-exist");
-    assertEquals("Delete service is ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testBadDeleteService4() {
-    final Response actual = apiServer.deleteService(request,
-        "jenkins-error-cleaning-registry");
-    assertEquals("Delete service is ",
-        Response.status(Status.INTERNAL_SERVER_ERROR).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testGoodDeleteService() {
-    final Response actual = apiServer.deleteService(request, "jenkins");
-    assertEquals("Delete service is ",
-        Response.status(Status.OK).build().getStatus(), actual.getStatus());
-  }
-
-  @Test
-  public void testDeleteStoppedService() {
-    final Response actual = apiServer.deleteService(request,
-        "jenkins-already-stopped");
-    assertEquals("Delete service is ",
-        Response.status(Status.OK).build().getStatus(), actual.getStatus());
-  }
-
-  @Test
-  public void testDecreaseContainerAndStop() {
-    Service service = new Service();
-    service.setState(ServiceState.STOPPED);
-    service.setName("jenkins");
-    Artifact artifact = new Artifact();
-    artifact.setType(TypeEnum.DOCKER);
-    artifact.setId("jenkins:latest");
-    Resource resource = new Resource();
-    resource.setCpus(1);
-    resource.setMemory("2048");
-    List<Component> components = new ArrayList<Component>();
-    Component c = new Component();
-    c.setName("jenkins");
-    c.setNumberOfContainers(0L);
-    c.setArtifact(artifact);
-    c.setLaunchCommand("");
-    c.setResource(resource);
-    components.add(c);
-    service.setComponents(components);
-    final Response actual = apiServer.updateService(request, "jenkins",
-        service);
-    assertEquals("update service is ",
-        Response.status(Status.OK).build().getStatus(), actual.getStatus());
-  }
-
-  @Test
-  public void testBadDecreaseContainerAndStop() {
-    Service service = new Service();
-    service.setState(ServiceState.STOPPED);
-    service.setName("no-jenkins");
-    Artifact artifact = new Artifact();
-    artifact.setType(TypeEnum.DOCKER);
-    artifact.setId("jenkins:latest");
-    Resource resource = new Resource();
-    resource.setCpus(1);
-    resource.setMemory("2048");
-    List<Component> components = new ArrayList<Component>();
-    Component c = new Component();
-    c.setName("no-jenkins");
-    c.setNumberOfContainers(-1L);
-    c.setArtifact(artifact);
-    c.setLaunchCommand("");
-    c.setResource(resource);
-    components.add(c);
-    service.setComponents(components);
-    System.out.println("before stop");
-    final Response actual = apiServer.updateService(request, "no-jenkins",
-        service);
-    assertEquals("flex service is ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testIncreaseContainersAndStart() {
-    Service service = new Service();
-    service.setState(ServiceState.STARTED);
-    service.setName("jenkins");
-    Artifact artifact = new Artifact();
-    artifact.setType(TypeEnum.DOCKER);
-    artifact.setId("jenkins:latest");
-    Resource resource = new Resource();
-    resource.setCpus(1);
-    resource.setMemory("2048");
-    List<Component> components = new ArrayList<Component>();
-    Component c = new Component();
-    c.setName("jenkins");
-    c.setNumberOfContainers(2L);
-    c.setArtifact(artifact);
-    c.setLaunchCommand("");
-    c.setResource(resource);
-    components.add(c);
-    service.setComponents(components);
-    final Response actual = apiServer.updateService(request, "jenkins",
-        service);
-    assertEquals("flex service is ",
-        Response.status(Status.OK).build().getStatus(), actual.getStatus());
-  }
-
-  @Test
-  public void testBadStartServices() {
-    Service service = new Service();
-    service.setState(ServiceState.STARTED);
-    service.setName("no-jenkins");
-    Artifact artifact = new Artifact();
-    artifact.setType(TypeEnum.DOCKER);
-    artifact.setId("jenkins:latest");
-    Resource resource = new Resource();
-    resource.setCpus(1);
-    resource.setMemory("2048");
-    List<Component> components = new ArrayList<Component>();
-    Component c = new Component();
-    c.setName("jenkins");
-    c.setNumberOfContainers(2L);
-    c.setArtifact(artifact);
-    c.setLaunchCommand("");
-    c.setResource(resource);
-    components.add(c);
-    service.setComponents(components);
-    final Response actual = apiServer.updateService(request, "no-jenkins",
-        service);
-    assertEquals("start service is ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testGoodStartServices() {
-    Service service = new Service();
-    service.setState(ServiceState.STARTED);
-    service.setName("jenkins");
-    Artifact artifact = new Artifact();
-    artifact.setType(TypeEnum.DOCKER);
-    artifact.setId("jenkins:latest");
-    Resource resource = new Resource();
-    resource.setCpus(1);
-    resource.setMemory("2048");
-    List<Component> components = new ArrayList<Component>();
-    Component c = new Component();
-    c.setName("jenkins");
-    c.setNumberOfContainers(2L);
-    c.setArtifact(artifact);
-    c.setLaunchCommand("");
-    c.setResource(resource);
-    components.add(c);
-    service.setComponents(components);
-    final Response actual = apiServer.updateService(request, "jenkins",
-        service);
-    assertEquals("start service is ",
-        Response.status(Status.OK).build().getStatus(), actual.getStatus());
-  }
-
-  @Test
-  public void testBadStopServices() {
-    Service service = new Service();
-    service.setState(ServiceState.STOPPED);
-    service.setName("no-jenkins");
-    Artifact artifact = new Artifact();
-    artifact.setType(TypeEnum.DOCKER);
-    artifact.setId("jenkins:latest");
-    Resource resource = new Resource();
-    resource.setCpus(1);
-    resource.setMemory("2048");
-    List<Component> components = new ArrayList<Component>();
-    Component c = new Component();
-    c.setName("no-jenkins");
-    c.setNumberOfContainers(-1L);
-    c.setArtifact(artifact);
-    c.setLaunchCommand("");
-    c.setResource(resource);
-    components.add(c);
-    service.setComponents(components);
-    System.out.println("before stop");
-    final Response actual = apiServer.updateService(request, "no-jenkins",
-        service);
-    assertEquals("stop service is ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testGoodStopServices() {
-    Service service = new Service();
-    service.setState(ServiceState.STOPPED);
-    service.setName("jenkins");
-    System.out.println("before stop");
-    final Response actual = apiServer.updateService(request, "jenkins",
-        service);
-    assertEquals("stop service is ",
-        Response.status(Status.OK).build().getStatus(), actual.getStatus());
-  }
-
-  @Test
-  public void testBadSecondStopServices() throws Exception {
-    Service service = new Service();
-    service.setState(ServiceState.STOPPED);
-    service.setName("jenkins-second-stop");
-    // simulates stop on an already stopped service
-    System.out.println("before second stop");
-    final Response actual = apiServer.updateService(request,
-        "jenkins-second-stop", service);
-    assertEquals("stop service should have thrown 400 Bad Request: ",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-    ServiceStatus serviceStatus = (ServiceStatus) actual.getEntity();
-    assertEquals("Stop service should have failed with service already stopped",
-        "Service jenkins-second-stop is already stopped",
-        serviceStatus.getDiagnostics());
-  }
-
-  @Test
-  public void testUpdateService() {
-    Service service = new Service();
-    service.setState(ServiceState.STARTED);
-    service.setName("no-jenkins");
-    Artifact artifact = new Artifact();
-    artifact.setType(TypeEnum.DOCKER);
-    artifact.setId("jenkins:latest");
-    Resource resource = new Resource();
-    resource.setCpus(1);
-    resource.setMemory("2048");
-    List<Component> components = new ArrayList<Component>();
-    Component c = new Component();
-    c.setName("no-jenkins");
-    c.setNumberOfContainers(-1L);
-    c.setArtifact(artifact);
-    c.setLaunchCommand("");
-    c.setResource(resource);
-    components.add(c);
-    service.setComponents(components);
-    System.out.println("before stop");
-    final Response actual = apiServer.updateService(request, "no-jenkins",
-        service);
-    assertEquals("update service is ",
-        Response.status(Status.BAD_REQUEST)
-            .build().getStatus(), actual.getStatus());
-  }
-
-  @Test
-  public void testUpdateComponent() {
-    Response actual = apiServer.updateComponent(request, "jenkins",
-        "jenkins-master", null);
-    ServiceStatus serviceStatus = (ServiceStatus) actual.getEntity();
-    assertEquals("Update component should have failed with 400 bad request",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-    assertEquals("Update component should have failed with no data error",
-        "No component data provided", serviceStatus.getDiagnostics());
-
-    Component comp = new Component();
-    actual = apiServer.updateComponent(request, "jenkins", "jenkins-master",
-        comp);
-    serviceStatus = (ServiceStatus) actual.getEntity();
-    assertEquals("Update component should have failed with 400 bad request",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-    assertEquals("Update component should have failed with no count error",
-        "No container count provided", serviceStatus.getDiagnostics());
-
-    comp.setNumberOfContainers(-1L);
-    actual = apiServer.updateComponent(request, "jenkins", "jenkins-master",
-        comp);
-    serviceStatus = (ServiceStatus) actual.getEntity();
-    assertEquals("Update component should have failed with 400 bad request",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-    assertEquals("Update component should have failed with no count error",
-        "Invalid number of containers specified -1", serviceStatus.getDiagnostics());
-
-    comp.setName("jenkins-slave");
-    comp.setNumberOfContainers(1L);
-    actual = apiServer.updateComponent(request, "jenkins", "jenkins-master",
-        comp);
-    serviceStatus = (ServiceStatus) actual.getEntity();
-    assertEquals("Update component should have failed with 400 bad request",
-        Response.status(Status.BAD_REQUEST).build().getStatus(),
-        actual.getStatus());
-    assertEquals(
-        "Update component should have failed with component name mismatch "
-            + "error",
-        "Component name in the request object (jenkins-slave) does not match "
-            + "that in the URI path (jenkins-master)",
-        serviceStatus.getDiagnostics());
-  }
-
-  @Test
-  public void testInitiateUpgrade() {
-    Service goodService = ServiceClientTest.buildLiveGoodService();
-    goodService.setVersion("v2");
-    goodService.setState(ServiceState.UPGRADING);
-    final Response actual = apiServer.updateService(request,
-        goodService.getName(), goodService);
-    assertEquals("Initiate upgrade is ",
-        Response.status(Status.ACCEPTED).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testUpgradeSingleInstance() {
-    Service goodService = ServiceClientTest.buildLiveGoodService();
-    Component comp = goodService.getComponents().iterator().next();
-    Container container = comp.getContainers().iterator().next();
-    container.setState(ContainerState.UPGRADING);
-
-    // To be able to upgrade, the service needs to be in UPGRADING
-    // and container state needs to be in NEEDS_UPGRADE.
-    Service serviceStatus = mockServerClient.getGoodServiceStatus();
-    serviceStatus.setState(ServiceState.UPGRADING);
-    Container liveContainer = serviceStatus.getComponents().iterator().next()
-        .getContainers().iterator().next();
-    liveContainer.setState(ContainerState.NEEDS_UPGRADE);
-    mockServerClient.setExpectedInstances(Sets.newHashSet(
-        liveContainer.getComponentInstanceName()));
-
-    final Response actual = apiServer.updateComponentInstance(request,
-        goodService.getName(), comp.getName(),
-        container.getComponentInstanceName(), container);
-    assertEquals("Instance upgrade is ",
-        Response.status(Status.ACCEPTED).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testUpgradeMultipleInstances() {
-    Service goodService = ServiceClientTest.buildLiveGoodService();
-    Component comp = goodService.getComponents().iterator().next();
-    comp.getContainers().forEach(container ->
-        container.setState(ContainerState.UPGRADING));
-
-    // To be able to upgrade, the service needs to be in UPGRADING
-    // and container state needs to be in NEEDS_UPGRADE.
-    Service serviceStatus = mockServerClient.getGoodServiceStatus();
-    serviceStatus.setState(ServiceState.UPGRADING);
-    Set<String> expectedInstances = new HashSet<>();
-    serviceStatus.getComponents().iterator().next().getContainers().forEach(
-        container -> {
-          container.setState(ContainerState.NEEDS_UPGRADE);
-          expectedInstances.add(container.getComponentInstanceName());
-        }
-    );
-    mockServerClient.setExpectedInstances(expectedInstances);
-
-    final Response actual = apiServer.updateComponentInstances(request,
-        goodService.getName(), comp.getContainers());
-    assertEquals("Instance upgrade is ",
-        Response.status(Status.ACCEPTED).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testUpgradeComponent() {
-    Service goodService = ServiceClientTest.buildLiveGoodService();
-    Component comp = goodService.getComponents().iterator().next();
-    comp.setState(ComponentState.UPGRADING);
-
-    // To be able to upgrade, the service needs to be in UPGRADING
-    // and component state needs to be in NEEDS_UPGRADE.
-    Service serviceStatus = mockServerClient.getGoodServiceStatus();
-    serviceStatus.setState(ServiceState.UPGRADING);
-    Component liveComp = serviceStatus.getComponent(comp.getName());
-    liveComp.setState(ComponentState.NEEDS_UPGRADE);
-    Set<String> expectedInstances = new HashSet<>();
-    liveComp.getContainers().forEach(container -> {
-      expectedInstances.add(container.getComponentInstanceName());
-      container.setState(ContainerState.NEEDS_UPGRADE);
-    });
-    mockServerClient.setExpectedInstances(expectedInstances);
-
-    final Response actual = apiServer.updateComponent(request,
-        goodService.getName(), comp.getName(), comp);
-    assertEquals("Component upgrade is ",
-        Response.status(Status.ACCEPTED).build().getStatus(),
-        actual.getStatus());
-  }
-
-  @Test
-  public void testUpgradeMultipleComps() {
-    Service goodService = ServiceClientTest.buildLiveGoodService();
-    goodService.getComponents().forEach(comp ->
-        comp.setState(ComponentState.UPGRADING));
-
-    // To be able to upgrade, the live service needs to be in UPGRADING
-    // and component states needs to be in NEEDS_UPGRADE.
-    Service serviceStatus = mockServerClient.getGoodServiceStatus();
-    serviceStatus.setState(ServiceState.UPGRADING);
-    Set<String> expectedInstances = new HashSet<>();
-    serviceStatus.getComponents().forEach(liveComp -> {
-      liveComp.setState(ComponentState.NEEDS_UPGRADE);
-      liveComp.getContainers().forEach(liveContainer -> {
-        expectedInstances.add(liveContainer.getComponentInstanceName());
-        liveContainer.setState(ContainerState.NEEDS_UPGRADE);
-      });
-    });
-    mockServerClient.setExpectedInstances(expectedInstances);
-
-    final Response actual = apiServer.updateComponents(request,
-        goodService.getName(), goodService.getComponents());
-    assertEquals("Component upgrade is ",
-        Response.status(Status.ACCEPTED).build().getStatus(),
-        actual.getStatus());
-  }
-}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestApiServiceClient.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestApiServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestApiServiceClient.java
deleted file mode 100644
index 6cf0880..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestApiServiceClient.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hadoop.yarn.service.client;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import com.google.common.collect.Lists;
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.yarn.exceptions.YarnException;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.ServerConnector;
-import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlet.ServletHolder;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import static org.apache.hadoop.yarn.service.exceptions.LauncherExitCodes.*;
-
-/**
- * Test case for CLI to API Service.
- *
- */
-public class TestApiServiceClient {
-  private static ApiServiceClient asc;
-  private static ApiServiceClient badAsc;
-  private static Server server;
-
-  /**
-   * A mocked version of API Service for testing purpose.
-   *
-   */
-  @SuppressWarnings("serial")
-  public static class TestServlet extends HttpServlet {
-
-    @Override
-    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
-        throws ServletException, IOException {
-      System.out.println("Get was called");
-      if (req.getPathInfo() != null
-          && req.getPathInfo().contains("nonexistent-app")) {
-        resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
-      } else {
-        resp.setStatus(HttpServletResponse.SC_OK);
-      }
-    }
-
-    @Override
-    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
-        throws ServletException, IOException {
-      resp.setStatus(HttpServletResponse.SC_OK);
-    }
-
-    @Override
-    protected void doPut(HttpServletRequest req, HttpServletResponse resp)
-        throws ServletException, IOException {
-      resp.setStatus(HttpServletResponse.SC_OK);
-    }
-
-    @Override
-    protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
-        throws ServletException, IOException {
-      resp.setStatus(HttpServletResponse.SC_OK);
-    }
-
-  }
-
-  @BeforeClass
-  public static void setup() throws Exception {
-    server = new Server(8088);
-    ((QueuedThreadPool)server.getThreadPool()).setMaxThreads(10);
-    ServletContextHandler context = new ServletContextHandler();
-    context.setContextPath("/app");
-    server.setHandler(context);
-    context.addServlet(new ServletHolder(TestServlet.class), "/*");
-    ((ServerConnector)server.getConnectors()[0]).setHost("localhost");
-    server.start();
-
-    Configuration conf = new Configuration();
-    conf.set("yarn.resourcemanager.webapp.address",
-        "localhost:8088");
-    asc = new ApiServiceClient();
-    asc.serviceInit(conf);
-
-    Configuration conf2 = new Configuration();
-    conf2.set("yarn.resourcemanager.webapp.address",
-        "localhost:8089");
-    badAsc = new ApiServiceClient();
-    badAsc.serviceInit(conf2);
-  }
-
-  @AfterClass
-  public static void tearDown() throws Exception {
-    server.stop();
-  }
-
-  @Test
-  public void testLaunch() {
-    String fileName = "target/test-classes/example-app.json";
-    String appName = "example-app";
-    long lifetime = 3600L;
-    String queue = "default";
-    try {
-      int result = asc.actionLaunch(fileName, appName, lifetime, queue);
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testBadLaunch() {
-    String fileName = "unknown_file";
-    String appName = "unknown_app";
-    long lifetime = 3600L;
-    String queue = "default";
-    try {
-      int result = badAsc.actionLaunch(fileName, appName, lifetime, queue);
-      assertEquals(EXIT_EXCEPTION_THROWN, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testStatus() {
-    String appName = "nonexistent-app";
-    try {
-      String result = asc.getStatusString(appName);
-      assertEquals("Status reponse don't match",
-          " Service " + appName + " not found", result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testStop() {
-    String appName = "example-app";
-    try {
-      int result = asc.actionStop(appName);
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testBadStop() {
-    String appName = "unknown_app";
-    try {
-      int result = badAsc.actionStop(appName);
-      assertEquals(EXIT_EXCEPTION_THROWN, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testStart() {
-    String appName = "example-app";
-    try {
-      int result = asc.actionStart(appName);
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testBadStart() {
-    String appName = "unknown_app";
-    try {
-      int result = badAsc.actionStart(appName);
-      assertEquals(EXIT_EXCEPTION_THROWN, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testSave() {
-    String fileName = "target/test-classes/example-app.json";
-    String appName = "example-app";
-    long lifetime = 3600L;
-    String queue = "default";
-    try {
-      int result = asc.actionSave(fileName, appName, lifetime, queue);
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testBadSave() {
-    String fileName = "unknown_file";
-    String appName = "unknown_app";
-    long lifetime = 3600L;
-    String queue = "default";
-    try {
-      int result = badAsc.actionSave(fileName, appName, lifetime, queue);
-      assertEquals(EXIT_EXCEPTION_THROWN, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testFlex() {
-    String appName = "example-app";
-    HashMap<String, String> componentCounts = new HashMap<String, String>();
-    try {
-      int result = asc.actionFlex(appName, componentCounts);
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testBadFlex() {
-    String appName = "unknown_app";
-    HashMap<String, String> componentCounts = new HashMap<String, String>();
-    try {
-      int result = badAsc.actionFlex(appName, componentCounts);
-      assertEquals(EXIT_EXCEPTION_THROWN, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testDestroy() {
-    String appName = "example-app";
-    try {
-      int result = asc.actionDestroy(appName);
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testBadDestroy() {
-    String appName = "unknown_app";
-    try {
-      int result = badAsc.actionDestroy(appName);
-      assertEquals(EXIT_EXCEPTION_THROWN, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testInitiateServiceUpgrade() {
-    String appName = "example-app";
-    String upgradeFileName = "target/test-classes/example-app.json";
-    try {
-      int result = asc.initiateUpgrade(appName, upgradeFileName, false);
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testInstancesUpgrade() {
-    String appName = "example-app";
-    try {
-      int result = asc.actionUpgradeInstances(appName, Lists.newArrayList(
-          "comp-1", "comp-2"));
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-  @Test
-  public void testComponentsUpgrade() {
-    String appName = "example-app";
-    try {
-      int result = asc.actionUpgradeComponents(appName, Lists.newArrayList(
-          "comp"));
-      assertEquals(EXIT_SUCCESS, result);
-    } catch (IOException | YarnException e) {
-      fail();
-    }
-  }
-
-
-}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestSystemServiceManagerImpl.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestSystemServiceManagerImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestSystemServiceManagerImpl.java
deleted file mode 100644
index d39083d..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/java/org/apache/hadoop/yarn/service/client/TestSystemServiceManagerImpl.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hadoop.yarn.service.client;
-
-import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.hadoop.yarn.api.records.ApplicationId;
-import org.apache.hadoop.yarn.exceptions.YarnException;
-import org.apache.hadoop.yarn.service.api.records.Service;
-import org.apache.hadoop.yarn.service.conf.YarnServiceConf;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Test class for system service manager.
- */
-public class TestSystemServiceManagerImpl {
-
-  private static final Logger LOG =
-      LoggerFactory.getLogger(TestSystemServiceManagerImpl.class);
-  private SystemServiceManagerImpl systemService;
-  private Configuration conf;
-  private String resourcePath = "system-services";
-
-  private String[] users = new String[] {"user1", "user2"};
-  private static Map<String, Set<String>> loadedServices = new HashMap<>();
-  private static Map<String, Set<String>> submittedServices = new HashMap<>();
-
-  @Before
-  public void setup() {
-    File file = new File(
-        getClass().getClassLoader().getResource(resourcePath).getFile());
-    conf = new Configuration();
-    conf.set(YarnServiceConf.YARN_SERVICES_SYSTEM_SERVICE_DIRECTORY,
-        file.getAbsolutePath());
-    systemService = new SystemServiceManagerImpl() {
-      @Override ServiceClient getServiceClient() {
-        return new TestServiceClient();
-      }
-    };
-    systemService.init(conf); // do not call explicit start
-
-    constructUserService(users[0], "example-app1");
-    constructUserService(users[1], "example-app1", "example-app2");
-  }
-
-  @After
-  public void teadDown() {
-    systemService.stop();
-  }
-
-  @Test
-  public void testSystemServiceSubmission() throws Exception {
-    systemService.start();
-
-    /* verify for ignored sevices count */
-    Map<String, Integer> ignoredUserServices =
-        systemService.getIgnoredUserServices();
-    Assert.assertEquals(1, ignoredUserServices.size());
-    Assert.assertTrue("User user1 doesn't exist.",
-        ignoredUserServices.containsKey(users[0]));
-    int count = ignoredUserServices.get(users[0]);
-    Assert.assertEquals(1, count);
-    Assert.assertEquals(1,
-        systemService.getBadFileNameExtensionSkipCounter());
-    Assert.assertEquals(1, systemService.getBadDirSkipCounter());
-
-    Map<String, Set<Service>> userServices =
-        systemService.getSyncUserServices();
-    Assert.assertEquals(loadedServices.size(), userServices.size());
-    verifyForScannedUserServices(userServices);
-
-    verifyForLaunchedUserServices();
-
-    // 2nd time launch service to handle if service exist scenario
-    systemService.launchUserService(userServices);
-    verifyForLaunchedUserServices();
-  }
-
-  private void verifyForScannedUserServices(
-      Map<String, Set<Service>> userServices) {
-    for (String user : users) {
-      Set<Service> services = userServices.get(user);
-      Set<String> serviceNames = loadedServices.get(user);
-      Assert.assertEquals(serviceNames.size(), services.size());
-      Iterator<Service> iterator = services.iterator();
-      while (iterator.hasNext()) {
-        Service next = iterator.next();
-        Assert.assertTrue(
-            "Service name doesn't exist in expected userService "
-                + serviceNames, serviceNames.contains(next.getName()));
-      }
-    }
-  }
-
-  public void constructUserService(String user, String... serviceNames) {
-    Set<String> service = loadedServices.get(user);
-    if (service == null) {
-      service = new HashSet<>();
-      for (String serviceName : serviceNames) {
-        service.add(serviceName);
-      }
-      loadedServices.put(user, service);
-    }
-  }
-
-  class TestServiceClient extends ServiceClient {
-    @Override
-    protected void serviceStart() throws Exception {
-      // do nothing
-    }
-
-    @Override
-    protected void serviceStop() throws Exception {
-      // do nothing
-    }
-
-    @Override
-    protected void serviceInit(Configuration configuration)
-        throws Exception {
-      // do nothing
-    }
-
-    @Override
-    public ApplicationId actionCreate(Service service)
-        throws YarnException, IOException {
-      String userName =
-          UserGroupInformation.getCurrentUser().getShortUserName();
-      Set<String> services = submittedServices.get(userName);
-      if (services == null) {
-        services = new HashSet<>();
-        submittedServices.put(userName, services);
-      }
-      if (services.contains(service.getName())) {
-        String message = "Failed to create service " + service.getName()
-            + ", because it already exists.";
-        throw new YarnException(message);
-      }
-      services.add(service.getName());
-      return ApplicationId.newInstance(System.currentTimeMillis(), 1);
-    }
-  }
-
-  private void verifyForLaunchedUserServices() {
-    Assert.assertEquals(loadedServices.size(), submittedServices.size());
-    for (Map.Entry<String, Set<String>> entry : submittedServices.entrySet()) {
-      String user = entry.getKey();
-      Set<String> serviceSet = entry.getValue();
-      Assert.assertTrue(loadedServices.containsKey(user));
-      Set<String> services = loadedServices.get(user);
-      Assert.assertEquals(services.size(), serviceSet.size());
-      Assert.assertTrue(services.containsAll(serviceSet));
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/example-app.json
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/example-app.json b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/example-app.json
deleted file mode 100644
index a2f41cf..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/example-app.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "example-app",
-  "version": "1.0.0",
-  "components" :
-  [
-    {
-      "name": "simple",
-      "number_of_containers": 1,
-      "launch_command": "sleep 2",
-      "resource": {
-        "cpus": 1,
-        "memory": "128"
-      }
-    }
-  ]
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/log4j.properties b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/log4j.properties
deleted file mode 100644
index 81a3f6a..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-#   Licensed 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.
-
-# log4j configuration used during build and unit tests
-
-log4j.rootLogger=info,stdout
-log4j.threshold=ALL
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2} (%F:%M(%L)) - %m%n

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/bad/bad.yarnfile
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/bad/bad.yarnfile b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/bad/bad.yarnfile
deleted file mode 100644
index 1d514d6..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/bad/bad.yarnfile
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "bad",
-  "version": "1.0.0",
-  "components" :
-  [
-    {
-      "name": "simple",
-      "number_of_containers": 1,
-      "launch_command": "sleep 2",
-      "resource": {
-        "cpus": 1,
-        "memory": "128"
-      }
-    }
-  ]
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app1.yarnfile
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app1.yarnfile b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app1.yarnfile
deleted file mode 100644
index 823561d..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app1.yarnfile
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "example-app1",
-  "version": "1.0.0",
-  "components" :
-  [
-    {
-      "name": "simple",
-      "number_of_containers": 1,
-      "launch_command": "sleep 2",
-      "resource": {
-        "cpus": 1,
-        "memory": "128"
-      }
-    }
-  ]
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app2.yarnfile
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app2.yarnfile b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app2.yarnfile
deleted file mode 100644
index 823561d..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app2.yarnfile
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "example-app1",
-  "version": "1.0.0",
-  "components" :
-  [
-    {
-      "name": "simple",
-      "number_of_containers": 1,
-      "launch_command": "sleep 2",
-      "resource": {
-        "cpus": 1,
-        "memory": "128"
-      }
-    }
-  ]
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app3.json
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app3.json b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app3.json
deleted file mode 100644
index 8a3a561..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user1/example-app3.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "example-app3",
-  "version": "1.0.0",
-  "components" :
-  [
-    {
-      "name": "simple",
-      "number_of_containers": 1,
-      "launch_command": "sleep 2",
-      "resource": {
-        "cpus": 1,
-        "memory": "128"
-      }
-    }
-  ]
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user2/example-app1.yarnfile
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user2/example-app1.yarnfile b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user2/example-app1.yarnfile
deleted file mode 100644
index 823561d..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user2/example-app1.yarnfile
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "example-app1",
-  "version": "1.0.0",
-  "components" :
-  [
-    {
-      "name": "simple",
-      "number_of_containers": 1,
-      "launch_command": "sleep 2",
-      "resource": {
-        "cpus": 1,
-        "memory": "128"
-      }
-    }
-  ]
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user2/example-app2.yarnfile
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user2/example-app2.yarnfile b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user2/example-app2.yarnfile
deleted file mode 100644
index d8fd1d1..0000000
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/test/resources/system-services/sync/user2/example-app2.yarnfile
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "example-app2",
-  "version": "1.0.0",
-  "components" :
-  [
-    {
-      "name": "simple",
-      "number_of_containers": 1,
-      "launch_command": "sleep 2",
-      "resource": {
-        "cpus": 1,
-        "memory": "128"
-      }
-    }
-  ]
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/dev-support/findbugs-exclude.xml
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/dev-support/findbugs-exclude.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/dev-support/findbugs-exclude.xml
new file mode 100644
index 0000000..b89146a
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/dev-support/findbugs-exclude.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   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.
+-->
+<FindBugsFilter>
+
+</FindBugsFilter>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/pom.xml
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/pom.xml b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/pom.xml
new file mode 100644
index 0000000..45168a9
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/pom.xml
@@ -0,0 +1,144 @@
+<!--
+   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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.hadoop</groupId>
+    <artifactId>hadoop-yarn-services</artifactId>
+    <version>3.2.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>hadoop-yarn-services-api</artifactId>
+  <name>Apache Hadoop YARN Services API</name>
+  <packaging>jar</packaging>
+  <description>Hadoop YARN REST APIs for services</description>
+
+  <build>
+
+    <!-- resources are filtered for dynamic updates. This gets build info in-->
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+      <resource>
+        <directory>src/main/scripts/</directory>
+        <filtering>true</filtering>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <!-- The configuration of the plugin -->
+        <configuration>
+          <!-- Configuration of the archiver -->
+          <archive>
+            <manifestEntries>
+              <mode>development</mode>
+              <url>${project.url}</url>
+            </manifestEntries>
+            <!-- Manifest specific configuration -->
+            <manifest>
+            </manifest>
+          </archive>
+        </configuration>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <exclude>**/*.json</exclude>
+            <exclude>**/*.yarnfile</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <reporting>
+  </reporting>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-services-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-yarn-server-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-webapp</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.inject</groupId>
+      <artifactId>guice</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>javax.ws.rs</groupId>
+      <artifactId>jsr311-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- ======================================================== -->
+    <!-- Test dependencies -->
+    <!-- ======================================================== -->
+
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <type>test-jar</type>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/hadoop/blob/a23ff8d8/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java
new file mode 100644
index 0000000..a8e2f51
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java
@@ -0,0 +1,598 @@
+/*
+ * 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.hadoop.yarn.service.client;
+
+import static org.apache.hadoop.yarn.service.utils.ServiceApiUtil.jsonSerDeser;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+
+import com.google.common.base.Preconditions;
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.client.AuthenticatedURL;
+import org.apache.hadoop.yarn.api.ApplicationConstants;
+import org.apache.hadoop.yarn.api.records.ApplicationId;
+import org.apache.hadoop.yarn.api.records.ApplicationReport;
+import org.apache.hadoop.yarn.client.api.AppAdminClient;
+import org.apache.hadoop.yarn.client.api.YarnClient;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.exceptions.YarnException;
+import org.apache.hadoop.yarn.service.api.records.Component;
+import org.apache.hadoop.yarn.service.api.records.ComponentState;
+import org.apache.hadoop.yarn.service.api.records.Container;
+import org.apache.hadoop.yarn.service.api.records.ContainerState;
+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.conf.RestApiConstants;
+import org.apache.hadoop.yarn.service.utils.JsonSerDeser;
+import org.apache.hadoop.yarn.service.utils.ServiceApiUtil;
+import org.apache.hadoop.yarn.util.RMHAUtils;
+import org.codehaus.jackson.map.PropertyNamingStrategy;
+import org.eclipse.jetty.util.UrlEncoded;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.WebResource.Builder;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+
+import static org.apache.hadoop.yarn.service.exceptions.LauncherExitCodes.*;
+
+/**
+ * The rest API client for users to manage services on YARN.
+ */
+public class ApiServiceClient extends AppAdminClient {
+  private static final Logger LOG =
+      LoggerFactory.getLogger(ApiServiceClient.class);
+  protected YarnClient yarnClient;
+
+  @Override protected void serviceInit(Configuration configuration)
+      throws Exception {
+    yarnClient = YarnClient.createYarnClient();
+    addService(yarnClient);
+    super.serviceInit(configuration);
+  }
+
+  /**
+   * Calculate Resource Manager address base on working REST API.
+   */
+  private String getRMWebAddress() {
+    Configuration conf = getConfig();
+    String scheme = "http://";
+    String path = "/app/v1/services/version";
+    String rmAddress = conf
+        .get("yarn.resourcemanager.webapp.address");
+    if (YarnConfiguration.useHttps(conf)) {
+      scheme = "https://";
+      rmAddress = conf
+          .get("yarn.resourcemanager.webapp.https.address");
+    }
+    boolean useKerberos = UserGroupInformation.isSecurityEnabled();
+    List<String> rmServers = RMHAUtils
+        .getRMHAWebappAddresses(new YarnConfiguration(conf));
+    for (String host : rmServers) {
+      try {
+        Client client = Client.create();
+        StringBuilder sb = new StringBuilder();
+        sb.append(scheme);
+        sb.append(host);
+        sb.append(path);
+        if (!useKerberos) {
+          try {
+            String username = UserGroupInformation.getCurrentUser().getShortUserName();
+            sb.append("?user.name=");
+            sb.append(username);
+          } catch (IOException e) {
+            LOG.debug("Fail to resolve username: {}", e);
+          }
+        }
+        WebResource webResource = client
+            .resource(sb.toString());
+        if (useKerberos) {
+          AuthenticatedURL.Token token = new AuthenticatedURL.Token();
+          webResource.header("WWW-Authenticate", token);
+        }
+        ClientResponse test = webResource.get(ClientResponse.class);
+        if (test.getStatus() == 200) {
+          rmAddress = host;
+          break;
+        }
+      } catch (Exception e) {
+        LOG.debug("Fail to connect to: "+host, e);
+      }
+    }
+    return scheme+rmAddress;
+  }
+
+  /**
+   * Compute active resource manager API service location.
+   *
+   * @param appName - YARN service name
+   * @return URI to API Service
+   * @throws IOException
+   */
+  private String getServicePath(String appName) throws IOException {
+    String url = getRMWebAddress();
+    StringBuilder api = new StringBuilder();
+    api.append(url);
+    api.append("/app/v1/services");
+    if (appName != null) {
+      api.append("/");
+      api.append(appName);
+    }
+    Configuration conf = getConfig();
+    if (conf.get("hadoop.http.authentication.type").equalsIgnoreCase("simple")) {
+      api.append("?user.name=" + UrlEncoded
+          .encodeString(System.getProperty("user.name")));
+    }
+    return api.toString();
+  }
+
+  private String getInstancesPath(String appName) throws IOException {
+    Preconditions.checkNotNull(appName);
+    String url = getRMWebAddress();
+    StringBuilder api = new StringBuilder();
+    api.append(url);
+    api.append("/app/v1/services/").append(appName).append("/")
+        .append(RestApiConstants.COMP_INSTANCES);
+    Configuration conf = getConfig();
+    if (conf.get("hadoop.http.authentication.type").equalsIgnoreCase(
+        "simple")) {
+      api.append("?user.name=" + UrlEncoded
+          .encodeString(System.getProperty("user.name")));
+    }
+    return api.toString();
+  }
+
+  private String getComponentsPath(String appName) throws IOException {
+    Preconditions.checkNotNull(appName);
+    String url = getRMWebAddress();
+    StringBuilder api = new StringBuilder();
+    api.append(url);
+    api.append("/app/v1/services/").append(appName).append("/")
+        .append(RestApiConstants.COMPONENTS);
+    Configuration conf = getConfig();
+    if (conf.get("hadoop.http.authentication.type").equalsIgnoreCase(
+        "simple")) {
+      api.append("?user.name=" + UrlEncoded
+          .encodeString(System.getProperty("user.name")));
+    }
+    return api.toString();
+  }
+
+  private Builder getApiClient() throws IOException {
+    return getApiClient(getServicePath(null));
+  }
+
+  /**
+   * Setup API service web request.
+   *
+   * @param requestPath
+   * @return
+   * @throws IOException
+   */
+  private Builder getApiClient(String requestPath)
+      throws IOException {
+    Client client = Client.create(getClientConfig());
+    Configuration conf = getConfig();
+    client.setChunkedEncodingSize(null);
+    Builder builder = client
+        .resource(requestPath).type(MediaType.APPLICATION_JSON);
+    if (conf.get("hadoop.http.authentication.type").equals("kerberos")) {
+      AuthenticatedURL.Token token = new AuthenticatedURL.Token();
+      builder.header("WWW-Authenticate", token);
+    }
+    return builder
+        .accept("application/json;charset=utf-8");
+  }
+
+  private ClientConfig getClientConfig() {
+    ClientConfig config = new DefaultClientConfig();
+    config.getProperties().put(
+        ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE, 0);
+    config.getProperties().put(
+        ClientConfig.PROPERTY_BUFFER_RESPONSE_ENTITY_ON_EXCEPTION, true);
+    return config;
+  }
+
+  private int processResponse(ClientResponse response) {
+    response.bufferEntity();
+    String output;
+    if (response.getStatus() == 401) {
+      LOG.error("Authentication required");
+      return EXIT_EXCEPTION_THROWN;
+    }
+    if (response.getStatus() == 503) {
+      LOG.error("YARN Service is unavailable or disabled.");
+      return EXIT_EXCEPTION_THROWN;
+    }
+    try {
+      ServiceStatus ss = response.getEntity(ServiceStatus.class);
+      output = ss.getDiagnostics();
+    } catch (Throwable t) {
+      output = response.getEntity(String.class);
+    }
+    if (output==null) {
+      output = response.getEntity(String.class);
+    }
+    if (response.getStatus() <= 299) {
+      LOG.info(output);
+      return EXIT_SUCCESS;
+    } else {
+      LOG.error(output);
+      return EXIT_EXCEPTION_THROWN;
+    }
+  }
+
+  /**
+   * Utility method to load Service json from disk or from
+   * YARN examples.
+   *
+   * @param fileName - path to yarnfile
+   * @param serviceName - YARN Service Name
+   * @param lifetime - application lifetime
+   * @param queue - Queue to submit application
+   * @return
+   * @throws IOException
+   * @throws YarnException
+   */
+  public Service loadAppJsonFromLocalFS(String fileName, String serviceName,
+      Long lifetime, String queue) throws IOException, YarnException {
+    File file = new File(fileName);
+    if (!file.exists() && fileName.equals(file.getName())) {
+      String examplesDirStr = System.getenv("YARN_SERVICE_EXAMPLES_DIR");
+      String[] examplesDirs;
+      if (examplesDirStr == null) {
+        String yarnHome = System
+            .getenv(ApplicationConstants.Environment.HADOOP_YARN_HOME.key());
+        examplesDirs = new String[]{
+            yarnHome + "/share/hadoop/yarn/yarn-service-examples",
+            yarnHome + "/yarn-service-examples"
+        };
+      } else {
+        examplesDirs = StringUtils.split(examplesDirStr, ":");
+      }
+      for (String dir : examplesDirs) {
+        file = new File(MessageFormat.format("{0}/{1}/{2}.json",
+            dir, fileName, fileName));
+        if (file.exists()) {
+          break;
+        }
+        // Then look for secondary location.
+        file = new File(MessageFormat.format("{0}/{1}.json",
+            dir, fileName));
+        if (file.exists()) {
+          break;
+        }
+      }
+    }
+    if (!file.exists()) {
+      throw new YarnException("File or example could not be found: " +
+          fileName);
+    }
+    Path filePath = new Path(file.getAbsolutePath());
+    LOG.info("Loading service definition from local FS: " + filePath);
+    Service service = jsonSerDeser
+        .load(FileSystem.getLocal(getConfig()), filePath);
+    if (!StringUtils.isEmpty(serviceName)) {
+      service.setName(serviceName);
+    }
+    if (lifetime != null && lifetime > 0) {
+      service.setLifetime(lifetime);
+    }
+    if (!StringUtils.isEmpty(queue)) {
+      service.setQueue(queue);
+    }
+    return service;
+  }
+
+  /**
+   * Launch YARN service application.
+   *
+   * @param fileName - path to yarnfile
+   * @param appName - YARN Service Name
+   * @param lifetime - application lifetime
+   * @param queue - Queue to submit application
+   */
+  @Override
+  public int actionLaunch(String fileName, String appName, Long lifetime,
+      String queue) throws IOException, YarnException {
+    int result = EXIT_SUCCESS;
+    try {
+      Service service =
+          loadAppJsonFromLocalFS(fileName, appName, lifetime, queue);
+      String buffer = jsonSerDeser.toJson(service);
+      ClientResponse response = getApiClient()
+          .post(ClientResponse.class, buffer);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Fail to launch application: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  /**
+   * Stop YARN service application.
+   *
+   * @param appName - YARN Service Name
+   */
+  @Override
+  public int actionStop(String appName) throws IOException, YarnException {
+    int result = EXIT_SUCCESS;
+    try {
+      Service service = new Service();
+      service.setName(appName);
+      service.setState(ServiceState.STOPPED);
+      String buffer = jsonSerDeser.toJson(service);
+      ClientResponse response = getApiClient(getServicePath(appName))
+          .put(ClientResponse.class, buffer);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Fail to stop application: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  /**
+   * Start YARN service application.
+   *
+   * @param appName - YARN Service Name
+   */
+  @Override
+  public int actionStart(String appName) throws IOException, YarnException {
+    int result = EXIT_SUCCESS;
+    try {
+      Service service = new Service();
+      service.setName(appName);
+      service.setState(ServiceState.STARTED);
+      String buffer = jsonSerDeser.toJson(service);
+      ClientResponse response = getApiClient(getServicePath(appName))
+          .put(ClientResponse.class, buffer);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Fail to start application: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  /**
+   * Save Service configuration.
+   *
+   * @param fileName - path to Yarnfile
+   * @param appName - YARN Service Name
+   * @param lifetime - container life time
+   * @param queue - Queue to submit the application
+   */
+  @Override
+  public int actionSave(String fileName, String appName, Long lifetime,
+      String queue) throws IOException, YarnException {
+    int result = EXIT_SUCCESS;
+    try {
+      Service service =
+          loadAppJsonFromLocalFS(fileName, appName, lifetime, queue);
+      service.setState(ServiceState.STOPPED);
+      String buffer = jsonSerDeser.toJson(service);
+      ClientResponse response = getApiClient()
+          .post(ClientResponse.class, buffer);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Fail to save application: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  /**
+   * Decommission a YARN service.
+   *
+   * @param appName - YARN Service Name
+   */
+  @Override
+  public int actionDestroy(String appName) throws IOException, YarnException {
+    int result = EXIT_SUCCESS;
+    try {
+      ClientResponse response = getApiClient(getServicePath(appName))
+          .delete(ClientResponse.class);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Fail to destroy application: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  /**
+   * Change number of containers associated with a service.
+   *
+   * @param appName - YARN Service Name
+   * @param componentCounts - list of components and desired container count
+   */
+  @Override
+  public int actionFlex(String appName, Map<String, String> componentCounts)
+      throws IOException, YarnException {
+    int result = EXIT_SUCCESS;
+    try {
+      Service service = new Service();
+      service.setName(appName);
+      service.setState(ServiceState.FLEX);
+      for (Map.Entry<String, String> entry : componentCounts.entrySet()) {
+        Component component = new Component();
+        component.setName(entry.getKey());
+        Long numberOfContainers = Long.parseLong(entry.getValue());
+        component.setNumberOfContainers(numberOfContainers);
+        service.addComponent(component);
+      }
+      String buffer = jsonSerDeser.toJson(service);
+      ClientResponse response = getApiClient(getServicePath(appName))
+          .put(ClientResponse.class, buffer);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Fail to flex application: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  @Override
+  public int enableFastLaunch(String destinationFolder) throws IOException, YarnException {
+    ServiceClient sc = new ServiceClient();
+    sc.init(getConfig());
+    sc.start();
+    int result = sc.enableFastLaunch(destinationFolder);
+    sc.close();
+    return result;
+  }
+
+  /**
+   * Retrieve Service Status through REST API.
+   *
+   * @param appIdOrName - YARN application ID or application name
+   * @return Status output
+   */
+  @Override
+  public String getStatusString(String appIdOrName) throws IOException,
+      YarnException {
+    String output = "";
+    String appName;
+    try {
+      ApplicationId appId = ApplicationId.fromString(appIdOrName);
+      ApplicationReport appReport = yarnClient.getApplicationReport(appId);
+      appName = appReport.getName();
+    } catch (IllegalArgumentException e) {
+      // not app Id format, may be app name
+      appName = appIdOrName;
+      ServiceApiUtil.validateNameFormat(appName, getConfig());
+    }
+    try {
+      ClientResponse response = getApiClient(getServicePath(appName))
+          .get(ClientResponse.class);
+      if (response.getStatus() == 404) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(" Service ");
+        sb.append(appName);
+        sb.append(" not found");
+        return sb.toString();
+      }
+      if (response.getStatus() != 200) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(appName);
+        sb.append(" Failed : HTTP error code : ");
+        sb.append(response.getStatus());
+        return sb.toString();
+      }
+      output = response.getEntity(String.class);
+    } catch (Exception e) {
+      LOG.error("Fail to check application status: ", e);
+    }
+    return output;
+  }
+
+  @Override
+  public int initiateUpgrade(String appName,
+      String fileName, boolean autoFinalize) throws IOException, YarnException {
+    int result;
+    try {
+      Service service =
+          loadAppJsonFromLocalFS(fileName, appName, null, null);
+      if (autoFinalize) {
+        service.setState(ServiceState.UPGRADING_AUTO_FINALIZE);
+      } else {
+        service.setState(ServiceState.UPGRADING);
+      }
+      String buffer = jsonSerDeser.toJson(service);
+      ClientResponse response = getApiClient(getServicePath(appName))
+          .put(ClientResponse.class, buffer);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Failed to upgrade application: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  @Override
+  public int actionUpgradeInstances(String appName, List<String> compInstances)
+      throws IOException, YarnException {
+    int result;
+    Container[] toUpgrade = new Container[compInstances.size()];
+    try {
+      int idx = 0;
+      for (String instanceName : compInstances) {
+        Container container = new Container();
+        container.setComponentInstanceName(instanceName);
+        container.setState(ContainerState.UPGRADING);
+        toUpgrade[idx++] = container;
+      }
+      String buffer = CONTAINER_JSON_SERDE.toJson(toUpgrade);
+      ClientResponse response = getApiClient(getInstancesPath(appName))
+          .put(ClientResponse.class, buffer);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Failed to upgrade component instance: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  @Override
+  public int actionUpgradeComponents(String appName, List<String> components)
+      throws IOException, YarnException {
+    int result;
+    Component[] toUpgrade = new Component[components.size()];
+    try {
+      int idx = 0;
+      for (String compName : components) {
+        Component component = new Component();
+        component.setName(compName);
+        component.setState(ComponentState.UPGRADING);
+        toUpgrade[idx++] = component;
+      }
+      String buffer = COMP_JSON_SERDE.toJson(toUpgrade);
+      ClientResponse response = getApiClient(getComponentsPath(appName))
+          .put(ClientResponse.class, buffer);
+      result = processResponse(response);
+    } catch (Exception e) {
+      LOG.error("Failed to upgrade components: ", e);
+      result = EXIT_EXCEPTION_THROWN;
+    }
+    return result;
+  }
+
+  private static final JsonSerDeser<Container[]> CONTAINER_JSON_SERDE =
+      new JsonSerDeser<>(Container[].class,
+          PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
+
+  private static final JsonSerDeser<Component[]> COMP_JSON_SERDE =
+      new JsonSerDeser<>(Component[].class,
+          PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscribe@hadoop.apache.org
For additional commands, e-mail: common-commits-help@hadoop.apache.org