diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java index 0b9c8fd0ea..5efbef4c7b 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java @@ -134,7 +134,7 @@ public class Run extends LockAbstract { if (file.exists()) { try { try { - server.stop(); + server.stop(true); } catch (Exception e) { e.printStackTrace(); } @@ -155,7 +155,7 @@ public class Run extends LockAbstract { @Override public void run() { try { - server.stop(); + server.stop(true); } catch (Exception e) { e.printStackTrace(); } diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/components/ExternalComponent.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/components/ExternalComponent.java index 4969d6a3b2..407c48ca19 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/components/ExternalComponent.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/components/ExternalComponent.java @@ -16,10 +16,10 @@ */ package org.apache.activemq.artemis.components; -import org.apache.activemq.artemis.core.server.ActiveMQComponent; +import org.apache.activemq.artemis.core.server.ServiceComponent; import org.apache.activemq.artemis.dto.ComponentDTO; -public interface ExternalComponent extends ActiveMQComponent { +public interface ExternalComponent extends ServiceComponent { void configure(ComponentDTO config, String artemisInstance, String artemisHome) throws Exception; } diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/Broker.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/Broker.java index 8da0480e9f..2cae955d47 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/Broker.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/Broker.java @@ -16,13 +16,13 @@ */ package org.apache.activemq.artemis.integration; -import org.apache.activemq.artemis.core.server.ActiveMQComponent; import org.apache.activemq.artemis.core.server.ActiveMQServer; +import org.apache.activemq.artemis.core.server.ServiceComponent; /** * A Broker os a set of ActiveMQComponents that create a Server, for instance core and jms. */ -public interface Broker extends ActiveMQComponent { +public interface Broker extends ServiceComponent { ActiveMQServer getServer(); } diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java index 0556cccf89..b21d7c227b 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/integration/FileBroker.java @@ -28,6 +28,7 @@ import org.apache.activemq.artemis.core.config.impl.FileConfiguration; import org.apache.activemq.artemis.core.server.ActiveMQComponent; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.RoutingType; +import org.apache.activemq.artemis.core.server.ServiceComponent; import org.apache.activemq.artemis.dto.ServerDTO; import org.apache.activemq.artemis.integration.bootstrap.ActiveMQBootstrapLogger; import org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration; @@ -113,13 +114,22 @@ public class FileBroker implements Broker { @Override public void stop() throws Exception { + stop(false); + } + + @Override + public 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--) { - mqComponents[i].stop(); + if (mqComponents[i] instanceof ServiceComponent) { + ((ServiceComponent)mqComponents[i]).stop(isShutdown); + } else { + mqComponents[i].stop(); + } } started = false; } @@ -151,4 +161,5 @@ public class FileBroker implements Broker { public ActiveMQServer getServer() { return (ActiveMQServer) components.get("core"); } + } diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/core/server/ServiceComponent.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/core/server/ServiceComponent.java new file mode 100644 index 0000000000..2fb0b6f309 --- /dev/null +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/core/server/ServiceComponent.java @@ -0,0 +1,25 @@ +/* + * 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.activemq.artemis.core.server; + +/** + * A Component that needs to know the stop reason. + */ +public interface ServiceComponent extends ActiveMQComponent { + + void stop(boolean isShutdown) throws Exception; +} diff --git a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java index e24215c76d..c58bafb318 100644 --- a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java +++ b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java @@ -124,6 +124,9 @@ public class WebServerComponent implements ExternalComponent { @Override public void start() throws Exception { + if (isStarted()) { + return; + } server.start(); ActiveMQWebLogger.LOGGER.webserverStarted(webServerConfig.bind); if (jolokiaUrl != null) { @@ -131,8 +134,7 @@ public class WebServerComponent implements ExternalComponent { } } - @Override - public void stop() throws Exception { + public void internalStop() throws Exception { server.stop(); if (webContexts != null) { File tmpdir = null; @@ -170,4 +172,16 @@ public class WebServerComponent implements ExternalComponent { handlers.addHandler(webapp); return webapp; } + + @Override + public void stop() throws Exception { + stop(false); + } + + @Override + public void stop(boolean isShutdown) throws Exception { + if (isShutdown) { + internalStop(); + } + } } diff --git a/artemis-web/src/test/java/org/apache/activemq/cli/test/WebServerComponentTest.java b/artemis-web/src/test/java/org/apache/activemq/cli/test/WebServerComponentTest.java index 1e0aff787f..3660f603fb 100644 --- a/artemis-web/src/test/java/org/apache/activemq/cli/test/WebServerComponentTest.java +++ b/artemis-web/src/test/java/org/apache/activemq/cli/test/WebServerComponentTest.java @@ -95,7 +95,49 @@ public class WebServerComponentTest extends Assert { // Wait for the server to close the connection. ch.close(); Assert.assertTrue(webServerComponent.isStarted()); + webServerComponent.stop(true); + Assert.assertFalse(webServerComponent.isStarted()); + } + + @Test + public void testComponentStopBehavior() throws Exception { + WebServerDTO webServerDTO = new WebServerDTO(); + webServerDTO.bind = "http://localhost:8161"; + webServerDTO.path = "webapps"; + WebServerComponent webServerComponent = new WebServerComponent(); + Assert.assertFalse(webServerComponent.isStarted()); + webServerComponent.configure(webServerDTO, "./src/test/resources/", "./src/test/resources/"); + webServerComponent.start(); + // Make the connection attempt. + CountDownLatch latch = new CountDownLatch(1); + final ClientHandler clientHandler = new ClientHandler(latch); + bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer() { + @Override + protected void initChannel(Channel ch) throws Exception { + ch.pipeline().addLast(new HttpClientCodec()); + ch.pipeline().addLast(clientHandler); + } + }); + Channel ch = bootstrap.connect("localhost", 8161).sync().channel(); + + URI uri = new URI(URL); + // Prepare the HTTP request. + HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath()); + request.headers().set(HttpHeaders.Names.HOST, "localhost"); + + // Send the HTTP request. + ch.writeAndFlush(request); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + assertEquals(clientHandler.body, "12345"); + // Wait for the server to close the connection. + ch.close(); + Assert.assertTrue(webServerComponent.isStarted()); + + //usual stop won't actually stop it webServerComponent.stop(); + assertTrue(webServerComponent.isStarted()); + + webServerComponent.stop(true); Assert.assertFalse(webServerComponent.isStarted()); } @@ -145,7 +187,7 @@ public class WebServerComponentTest extends Assert { // Wait for the server to close the connection. ch.close(); Assert.assertTrue(webServerComponent.isStarted()); - webServerComponent.stop(); + webServerComponent.stop(true); Assert.assertFalse(webServerComponent.isStarted()); } @@ -198,7 +240,7 @@ public class WebServerComponentTest extends Assert { // Wait for the server to close the connection. ch.close(); Assert.assertTrue(webServerComponent.isStarted()); - webServerComponent.stop(); + webServerComponent.stop(true); Assert.assertFalse(webServerComponent.isStarted()); }