HDFS-12407. Journal node fails to shutdown cleanly if JournalNodeHttpServer or JournalNodeRpcServer fails to start. Contributed by Ajay Kumar.

This commit is contained in:
Arpit Agarwal 2017-09-12 16:18:41 -07:00
parent 4e147f7e96
commit e5a65ebc28
2 changed files with 48 additions and 18 deletions

View File

@ -158,26 +158,35 @@ public class JournalNode implements Tool, Configurable, JournalNodeMXBean {
public void start() throws IOException { public void start() throws IOException {
Preconditions.checkState(!isStarted(), "JN already running"); Preconditions.checkState(!isStarted(), "JN already running");
validateAndCreateJournalDir(localDir); try {
DefaultMetricsSystem.initialize("JournalNode"); validateAndCreateJournalDir(localDir);
JvmMetrics.create("JournalNode",
conf.get(DFSConfigKeys.DFS_METRICS_SESSION_ID_KEY),
DefaultMetricsSystem.instance());
InetSocketAddress socAddr = JournalNodeRpcServer.getAddress(conf); DefaultMetricsSystem.initialize("JournalNode");
SecurityUtil.login(conf, DFSConfigKeys.DFS_JOURNALNODE_KEYTAB_FILE_KEY, JvmMetrics.create("JournalNode",
DFSConfigKeys.DFS_JOURNALNODE_KERBEROS_PRINCIPAL_KEY, socAddr.getHostName()); conf.get(DFSConfigKeys.DFS_METRICS_SESSION_ID_KEY),
DefaultMetricsSystem.instance());
registerJNMXBean(); InetSocketAddress socAddr = JournalNodeRpcServer.getAddress(conf);
SecurityUtil.login(conf, DFSConfigKeys.DFS_JOURNALNODE_KEYTAB_FILE_KEY,
DFSConfigKeys.DFS_JOURNALNODE_KERBEROS_PRINCIPAL_KEY,
socAddr.getHostName());
httpServer = new JournalNodeHttpServer(conf, this); registerJNMXBean();
httpServer.start();
httpServerURI = httpServer.getServerURI().toString(); httpServer = new JournalNodeHttpServer(conf, this);
httpServer.start();
rpcServer = new JournalNodeRpcServer(conf, this); httpServerURI = httpServer.getServerURI().toString();
rpcServer.start();
rpcServer = new JournalNodeRpcServer(conf, this);
rpcServer.start();
} catch (IOException ioe) {
//Shutdown JournalNode of JournalNodeRpcServer fails to start
LOG.error("Failed to start JournalNode.", ioe);
this.stop(1);
throw ioe;
}
} }
public boolean isStarted() { public boolean isStarted() {

View File

@ -55,6 +55,7 @@ import org.junit.Test;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.primitives.Bytes; import com.google.common.primitives.Bytes;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import org.mockito.Mockito;
public class TestJournalNode { public class TestJournalNode {
@ -342,4 +343,24 @@ public class TestJournalNode {
System.err.println("Time per batch: " + avgRtt + "ms"); System.err.println("Time per batch: " + avgRtt + "ms");
System.err.println("Throughput: " + throughput + " bytes/sec"); System.err.println("Throughput: " + throughput + " bytes/sec");
} }
/**
* Test case to check if JournalNode exits cleanly when httpserver or rpc
* server fails to start. Call to JournalNode start should fail with bind
* exception as the port is in use by the JN started in @Before routine
*/
@Test
public void testJournalNodeStartupFailsCleanly() {
JournalNode jNode = Mockito.spy(new JournalNode());
try {
jNode.setConf(conf);
jNode.start();
fail("Should throw bind exception");
} catch (Exception e) {
GenericTestUtils
.assertExceptionContains("java.net.BindException: Port in use", e);
}
Mockito.verify(jNode).stop(1);
}
} }