diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/ServiceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/ServiceManager.java index 3c8fed68a12..7d7bbfd035a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/ServiceManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/main/java/org/apache/hadoop/yarn/service/ServiceManager.java @@ -478,6 +478,12 @@ void processUpgradeRequest(String upgradeVersion, return true; } + if (component.getNumberOfContainers() <= 0) { + LOG.info("Upgrade is not needed because the component {} " + + "has no instance", component.getName()); + return true; + } + return false; }); } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/ServiceTestUtils.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/ServiceTestUtils.java index e5c35275c95..fec9386545b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/ServiceTestUtils.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/ServiceTestUtils.java @@ -147,6 +147,15 @@ public static Service createTerminatingDominantComponentJobExample( return exampleApp; } + public static Service createNoInstanceComponentExample() { + Service exampleApp = new Service(); + exampleApp.setName("no-instance-component-app"); + exampleApp.setVersion("v1"); + exampleApp.addComponent(createComponent("compa")); + exampleApp.addComponent(createComponent("compb", 0, "sleep 1000")); + return exampleApp; + } + public static Component createComponent(String name) { return createComponent(name, 2L, "sleep 1000", Component.RestartPolicyEnum.ALWAYS, null); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/TestServiceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/TestServiceManager.java index 1d8ccff4f6f..9f10d37066e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/TestServiceManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services/hadoop-yarn-services-core/src/test/java/org/apache/hadoop/yarn/service/TestServiceManager.java @@ -196,6 +196,28 @@ public void testExpressUpgrade() throws Exception { validateUpgradeFinalization(manager.getName(), "v2"); } + @Test(timeout = TIMEOUT) + public void testExpressUpgradeWithNoInstanceComponent() throws Exception { + ServiceContext context = createServiceContext( + "testExpressUpgradeWithNoInstanceComponent"); + ServiceManager manager = context.getServiceManager(); + manager.getServiceSpec().setState(ServiceState.EXPRESS_UPGRADING); + initUpgrade(context, "v2", true, true, true); + + List comps = ServiceApiUtil.resolveCompsDependency(context.service); + // wait till instances of first component are upgraded and ready + String compA = comps.get(0); + makeInstancesReadyAfterUpgrade(context, compA); + + GenericTestUtils.waitFor(() -> + context.service.getState().equals(ServiceState.STABLE), + CHECK_EVERY_MILLIS, TIMEOUT); + + Assert.assertEquals("service not stable", + ServiceState.STABLE, manager.getServiceSpec().getState()); + validateUpgradeFinalization(manager.getName(), "v2"); + } + @Test(timeout = TIMEOUT) public void testCancelUpgrade() throws Exception { ServiceContext context = createServiceContext("testCancelUpgrade"); @@ -266,6 +288,9 @@ private void initUpgrade(ServiceContext context, String version, InterruptedException { ServiceManager serviceManager = context.getServiceManager(); Service upgradedDef = ServiceTestUtils.createExampleApplication(); + if (serviceManager.getName().equals("testExpressUpgradeWithNoInstanceComponent")) { + upgradedDef = ServiceTestUtils.createNoInstanceComponentExample(); + } upgradedDef.setName(serviceManager.getName()); upgradedDef.setVersion(version); if (upgradeArtifact) { @@ -278,8 +303,9 @@ private void initUpgrade(ServiceContext context, String version, serviceManager.processUpgradeRequest(version, autoFinalize, expressUpgrade); GenericTestUtils.waitFor(() -> { for (Component comp : context.scheduler.getAllComponents().values()) { - if (!comp.getComponentSpec().getState().equals( - ComponentState.NEEDS_UPGRADE)) { + if (comp.getComponentSpec().getNumberOfContainers() > 0 && + !comp.getComponentSpec().getState().equals( + ComponentState.NEEDS_UPGRADE)) { return false; } } @@ -388,7 +414,11 @@ private ServiceContext createServiceContext(String name) } public static Service createBaseDef(String name) { - return createDef(name, ServiceTestUtils.createExampleApplication()); + Service service = ServiceTestUtils.createExampleApplication(); + if (name.equals("testExpressUpgradeWithNoInstanceComponent")) { + service = ServiceTestUtils.createNoInstanceComponentExample(); + } + return createDef(name, service); } public static Service createDef(String name, Service serviceDef) {