diff --git a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/upgrade/FinalizeSubCommand.java b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/upgrade/FinalizeSubCommand.java index 7f36b84b93e7..411955951df6 100644 --- a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/upgrade/FinalizeSubCommand.java +++ b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/upgrade/FinalizeSubCommand.java @@ -20,7 +20,9 @@ import java.util.concurrent.Callable; import org.apache.hadoop.hdds.cli.AbstractSubcommand; import org.apache.hadoop.hdds.cli.HddsVersionProvider; +import org.apache.hadoop.ozone.OzoneManagerVersion; import org.apache.hadoop.ozone.admin.om.OmAddressOptions; +import org.apache.hadoop.ozone.client.rpc.RpcClient; import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol; import picocli.CommandLine; @@ -33,18 +35,24 @@ mixinStandardHelpOptions = true, versionProvider = HddsVersionProvider.class ) -public class FinalizeSubCommand extends AbstractSubcommand implements Callable { +public class FinalizeSubCommand extends AbstractSubcommand implements Callable { @CommandLine.Mixin private OmAddressOptions.OptionalServiceIdOrHostMixin omAddressOptions; @Override - public Void call() throws Exception { + public Integer call() throws Exception { try (OzoneManagerProtocol client = getClient()) { + OzoneManagerVersion omVersion = RpcClient.getOmVersion(client.getServiceInfo()); + if (!OzoneManagerVersion.ZDU.isSupportedBy(omVersion)) { + err().println("OM does not support zero downtime upgrade. The cluster should be finalized with " + + "`ozone admin om finalizeupgrade`"); + return 1; + } client.finalizeUpgrade(); out().println("Cluster finalization has been started. Monitor progress with `ozone admin upgrade status`"); } - return null; + return 0; } protected OzoneManagerProtocol getClient() throws Exception { diff --git a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/ozone/admin/upgrade/TestFinalizeSubCommand.java b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/ozone/admin/upgrade/TestFinalizeSubCommand.java index 0f7e9f2116ad..a21dca441841 100644 --- a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/ozone/admin/upgrade/TestFinalizeSubCommand.java +++ b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/ozone/admin/upgrade/TestFinalizeSubCommand.java @@ -17,17 +17,25 @@ package org.apache.hadoop.ozone.admin.upgrade; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; import java.nio.charset.StandardCharsets; +import java.util.Collections; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos; +import org.apache.hadoop.ozone.OzoneManagerVersion; +import org.apache.hadoop.ozone.om.helpers.ServiceInfo; +import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx; import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -42,16 +50,17 @@ public class TestFinalizeSubCommand { private static final String DEFAULT_ENCODING = StandardCharsets.UTF_8.name(); private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + private final ByteArrayOutputStream errContent = new ByteArrayOutputStream(); private final PrintStream originalOut = System.out; + private final PrintStream originalErr = System.err; private FinalizeSubCommand cmd; private OzoneManagerProtocol omClient; @BeforeEach public void setup() throws IOException { omClient = mock(OzoneManagerProtocol.class); - - // Mock close() to do nothing - needed for try-with-resources doNothing().when(omClient).close(); + when(omClient.getServiceInfo()).thenReturn(serviceInfoWithVersion(OzoneManagerVersion.ZDU)); cmd = new FinalizeSubCommand() { @Override @@ -60,17 +69,19 @@ protected OzoneManagerProtocol getClient() throws Exception { } }; System.setOut(new PrintStream(outContent, false, DEFAULT_ENCODING)); + System.setErr(new PrintStream(errContent, false, DEFAULT_ENCODING)); } @AfterEach public void tearDown() { System.setOut(originalOut); + System.setErr(originalErr); } @Test public void testCommandRunsAndPrintsOutput() throws Exception { new CommandLine(cmd).parseArgs(); - cmd.call(); + assertEquals(0, cmd.call()); String output = outContent.toString(DEFAULT_ENCODING); assertTrue(output.contains("Cluster finalization has been started")); @@ -95,4 +106,25 @@ public void testExceptionFromServerIsPropagated() throws Exception { // Client must still be closed even when finalizeUpgrade() throws. verify(omClient).close(); } + + @Test + public void testNonZduServerPrintsErrorAndReturnsNonZero() throws Exception { + when(omClient.getServiceInfo()).thenReturn(serviceInfoWithVersion(OzoneManagerVersion.DEFAULT_VERSION)); + + new CommandLine(cmd).parseArgs(); + assertEquals(1, cmd.call()); + + String errOutput = errContent.toString(DEFAULT_ENCODING); + assertTrue(errOutput.contains("OM does not support zero downtime upgrade")); + verify(omClient, never()).finalizeUpgrade(); + } + + private ServiceInfoEx serviceInfoWithVersion(OzoneManagerVersion version) { + ServiceInfo serviceInfo = new ServiceInfo.Builder() + .setNodeType(HddsProtos.NodeType.OM) + .setHostname("localhost") + .setOmVersion(version) + .build(); + return new ServiceInfoEx(Collections.singletonList(serviceInfo), "", Collections.emptyList()); + } }