This closes #1038
This commit is contained in:
commit
fbf3a726cc
|
@ -134,7 +134,7 @@ public class Run extends LockAbstract {
|
|||
if (file.exists()) {
|
||||
try {
|
||||
try {
|
||||
server.stop(true);
|
||||
server.exit();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ public class Run extends LockAbstract {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
server.stop(true);
|
||||
server.exit();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -118,15 +118,19 @@ public class FileBroker implements Broker {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void stop(boolean isShutdown) throws Exception {
|
||||
public void exit() throws Exception {
|
||||
stop(true);
|
||||
}
|
||||
|
||||
private void stop(boolean isShutdown) throws Exception {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
ActiveMQComponent[] mqComponents = new ActiveMQComponent[components.size()];
|
||||
components.values().toArray(mqComponents);
|
||||
for (int i = mqComponents.length - 1; i >= 0; i--) {
|
||||
if (mqComponents[i] instanceof ServiceComponent) {
|
||||
((ServiceComponent)mqComponents[i]).stop(isShutdown);
|
||||
if (mqComponents[i] instanceof ServiceComponent && isShutdown) {
|
||||
((ServiceComponent) mqComponents[i]).exit();
|
||||
} else {
|
||||
mqComponents[i].stop();
|
||||
}
|
||||
|
|
|
@ -21,5 +21,6 @@ package org.apache.activemq.artemis.core.server;
|
|||
*/
|
||||
public interface ServiceComponent extends ActiveMQComponent {
|
||||
|
||||
void stop(boolean isShutdown) throws Exception;
|
||||
//called by shutdown hooks before exit the VM
|
||||
void exit() throws Exception;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ import org.apache.activemq.artemis.utils.ExecutorFactory;
|
|||
* <p>
|
||||
* This is not part of our public API.
|
||||
*/
|
||||
public interface ActiveMQServer extends ActiveMQComponent {
|
||||
public interface ActiveMQServer extends ServiceComponent {
|
||||
|
||||
/**
|
||||
* Sets the server identity.
|
||||
|
|
|
@ -130,6 +130,7 @@ import org.apache.activemq.artemis.core.server.QueueQueryResult;
|
|||
import org.apache.activemq.artemis.api.core.RoutingType;
|
||||
import org.apache.activemq.artemis.core.server.SecuritySettingPlugin;
|
||||
import org.apache.activemq.artemis.core.server.ServerSession;
|
||||
import org.apache.activemq.artemis.core.server.ServiceComponent;
|
||||
import org.apache.activemq.artemis.core.server.ServiceRegistry;
|
||||
import org.apache.activemq.artemis.core.server.cluster.BackupManager;
|
||||
import org.apache.activemq.artemis.core.server.cluster.ClusterManager;
|
||||
|
@ -335,7 +336,7 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
internalStop();
|
||||
internalStop(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -667,19 +668,24 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit() throws Exception {
|
||||
internalStop(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void stop() throws Exception {
|
||||
internalStop(false);
|
||||
}
|
||||
|
||||
private void internalStop(boolean isExit) throws Exception {
|
||||
try {
|
||||
internalStop();
|
||||
stop(false, isExit);
|
||||
} finally {
|
||||
networkHealthCheck.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void internalStop() throws Exception {
|
||||
stop(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addActivationParam(String key, Object val) {
|
||||
activationParams.put(key, val);
|
||||
|
@ -810,7 +816,11 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
|
||||
@Override
|
||||
public final void stop(boolean failoverOnServerShutdown) throws Exception {
|
||||
stop(failoverOnServerShutdown, false, false);
|
||||
stop(failoverOnServerShutdown, false, false, false);
|
||||
}
|
||||
|
||||
public final void stop(boolean failoverOnServerShutdown, boolean isExit) throws Exception {
|
||||
stop(failoverOnServerShutdown, false, false, isExit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -830,12 +840,16 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
}
|
||||
}
|
||||
|
||||
void stop(boolean failoverOnServerShutdown, final boolean criticalIOError, boolean restarting) {
|
||||
this.stop(failoverOnServerShutdown, criticalIOError, restarting, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the server
|
||||
*
|
||||
* @param criticalIOError whether we have encountered an IO error with the journal etc
|
||||
*/
|
||||
void stop(boolean failoverOnServerShutdown, final boolean criticalIOError, boolean restarting) {
|
||||
void stop(boolean failoverOnServerShutdown, final boolean criticalIOError, boolean restarting, boolean isExit) {
|
||||
|
||||
synchronized (this) {
|
||||
if (state == SERVER_STATE.STOPPED || state == SERVER_STATE.STOPPING) {
|
||||
|
@ -1024,7 +1038,11 @@ public class ActiveMQServerImpl implements ActiveMQServer {
|
|||
|
||||
for (ActiveMQComponent externalComponent : externalComponents) {
|
||||
try {
|
||||
if (isExit && externalComponent instanceof ServiceComponent) {
|
||||
((ServiceComponent)externalComponent).exit();
|
||||
} else {
|
||||
externalComponent.stop();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ActiveMQServerLogger.LOGGER.errorStoppingComponent(e, externalComponent.getClass().getName());
|
||||
}
|
||||
|
|
|
@ -24,13 +24,18 @@ import org.apache.activemq.artemis.api.core.TransportConfiguration;
|
|||
import org.apache.activemq.artemis.core.config.Configuration;
|
||||
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
|
||||
import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQComponent;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQServer;
|
||||
import org.apache.activemq.artemis.core.server.ActiveMQServers;
|
||||
import org.apache.activemq.artemis.core.server.ServiceComponent;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class EmbeddedServerTest {
|
||||
|
||||
private static final String SERVER_LOCK_NAME = "server.lock";
|
||||
|
@ -64,6 +69,74 @@ public class EmbeddedServerTest {
|
|||
public void testNoLockFileWithPersistenceFalse() {
|
||||
Path journalDir = Paths.get(SERVER_JOURNAL_DIR, SERVER_LOCK_NAME);
|
||||
boolean lockExists = Files.exists(journalDir);
|
||||
Assert.assertFalse(lockExists);
|
||||
assertFalse(lockExists);
|
||||
}
|
||||
|
||||
@Test
|
||||
//make sure the correct stop/exit API is called.
|
||||
public void testExternalComponentStop() throws Exception {
|
||||
FakeExternalComponent normalComponent = new FakeExternalComponent();
|
||||
FakeExternalServiceComponent serviceComponent = new FakeExternalServiceComponent();
|
||||
|
||||
server.addExternalComponent(normalComponent);
|
||||
server.addExternalComponent(serviceComponent);
|
||||
|
||||
server.stop();
|
||||
assertTrue(normalComponent.stopCalled);
|
||||
|
||||
assertTrue(serviceComponent.stopCalled);
|
||||
assertFalse(serviceComponent.exitCalled);
|
||||
|
||||
normalComponent.resetFlags();
|
||||
serviceComponent.resetFlags();
|
||||
|
||||
server.start();
|
||||
server.exit();
|
||||
assertTrue(normalComponent.stopCalled);
|
||||
|
||||
assertFalse(serviceComponent.stopCalled);
|
||||
assertTrue(serviceComponent.exitCalled);
|
||||
}
|
||||
|
||||
private class FakeExternalComponent implements ActiveMQComponent {
|
||||
|
||||
volatile boolean startCalled;
|
||||
volatile boolean stopCalled;
|
||||
|
||||
@Override
|
||||
public void start() throws Exception {
|
||||
startCalled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws Exception {
|
||||
stopCalled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
return startCalled;
|
||||
}
|
||||
|
||||
public void resetFlags() {
|
||||
startCalled = false;
|
||||
stopCalled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private class FakeExternalServiceComponent extends FakeExternalComponent implements ServiceComponent {
|
||||
|
||||
volatile boolean exitCalled;
|
||||
|
||||
@Override
|
||||
public void exit() throws Exception {
|
||||
exitCalled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetFlags() {
|
||||
super.resetFlags();
|
||||
exitCalled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ public class WebServerComponent implements ExternalComponent {
|
|||
//somehow when broker is stopped and restarted quickly
|
||||
//this tmpdir won't get deleted sometimes
|
||||
boolean fileDeleted = TimeUtils.waitOnBoolean(false, 5000, tmpdir::exists);
|
||||
|
||||
if (!fileDeleted) {
|
||||
//because the execution order of shutdown hooks are
|
||||
//not determined, so it's possible that the deleteOnExit
|
||||
|
@ -190,6 +191,10 @@ public class WebServerComponent implements ExternalComponent {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void exit() throws Exception {
|
||||
stop(true);
|
||||
}
|
||||
|
||||
public void stop(boolean isShutdown) throws Exception {
|
||||
if (isShutdown) {
|
||||
internalStop();
|
||||
|
|
Loading…
Reference in New Issue