modules/plugins/jboss-as-7/pom.xml
| 10
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java
| 239 ++++++++++
2 files changed, 249 insertions(+)
New commits:
commit 5fecc675d08aa9220a163f0e35530dc6c07447b6
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Mon May 6 16:20:24 2013 +0200
Add test case for Bug 911321 - [EAP 6.1] Reload operation fails in standalone mode
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml
index 23a02c4..33b2bd7 100644
--- a/modules/plugins/jboss-as-7/pom.xml
+++ b/modules/plugins/jboss-as-7/pom.xml
@@ -30,6 +30,7 @@
<java.tieredCompilation>-Dxxx</java.tieredCompilation>
<java.useCompressedOOPS>-Dxxx</java.useCompressedOOPS>
<rhq.internal>false</rhq.internal>
+
<as7.itest.mock.http.management.server.port>32259</as7.itest.mock.http.management.server.port>
</properties>
@@ -118,6 +119,13 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty.aggregate</groupId>
+ <artifactId>jetty-all</artifactId>
+ <version>8.1.8.v20121106</version>
+ <scope>test</scope>
+ </dependency>
+
<!-- For native subsystem -->
<dependency>
<groupId>org.hyperic</groupId>
@@ -588,6 +596,7 @@
<!-- only include integration tests; normal unit tests are handled
above by surefire plugin -->
<include>org/rhq/modules/plugins/jbossas7/itest/**/*Test.java</include>
<!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java</include>-->
+
<!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java</include>-->
<!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java</include>-->
<!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java</include>-->
<!--<include>org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java</include>-->
@@ -609,6 +618,7 @@
<jboss.domain.portOffset>${jboss.domain.portOffset}</jboss.domain.portOffset>
<jboss.domain.httpManagementPort>${jboss.domain.httpManagementPort}</jboss.domain.httpManagementPort>
<settings.localRepository>${settings.localRepository}</settings.localRepository>
+
<as7.itest.mock.http.management.server.port>${as7.itest.mock.http.management.server.port}</as7.itest.mock.http.management.server.port>
</systemPropertyVariables>
</configuration>
<executions>
diff --git
a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java
b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java
new file mode 100644
index 0000000..9597d47
--- /dev/null
+++
b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java
@@ -0,0 +1,239 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+package org.rhq.modules.plugins.jbossas7.itest.standalone;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.mockito.Mockito.when;
+import static
org.rhq.core.pluginapi.event.log.LogFileEventResourceComponentHelper.LOG_EVENT_SOURCES_CONFIG_PROP;
+import static
org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.HOSTNAME;
+import static
org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.MANAGEMENT_CONNECTION_TIMEOUT;
+import static
org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.PASSWORD;
+import static
org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.PORT;
+import static
org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.USER;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.pluginapi.availability.AvailabilityContext;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.system.SystemInfoFactory;
+import org.rhq.core.util.StringUtil;
+import org.rhq.modules.plugins.jbossas7.StandaloneASComponent;
+import org.rhq.modules.plugins.jbossas7.json.Operation;
+import org.rhq.modules.plugins.jbossas7.json.Result;
+
+/**
+ * Check that management operations that might be interrupted by AS server (connection
closed before the http response
+ * is sent) don't make RHQ operations fail.
+ *
+ * See
https://bugzilla.redhat.com/show_bug.cgi?id=911321
+ *
+ * @author Thomas Segismont
+ */
+public class InterruptibleOperationsTest {
+
+ private static final Log LOG = LogFactory.getLog(InterruptibleOperationsTest.class);
+
+ private static final String HTTP_HOST = "localhost";
+
+ private static final int HTTP_PORT = 31159;
+
+ private static final String HTTP_PORT_VARIABLE =
"as7.itest.mock.http.management.server.port";
+
+ @Mock
+ private ResourceContext resourceContext;
+
+ private StandaloneASComponent serverComponent;
+
+ private Server jettyServer;
+
+ private ExecutorService executorService;
+
+ @BeforeMethod
+ private void setup() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ serverComponent = new TestStandaloneASComponent();
+ int httpPort = getJettyPort();
+ setupResourceContext(httpPort);
+ setupJettyServer(httpPort);
+ jettyServer.start();
+ executorService = Executors.newSingleThreadExecutor();
+ serverComponent.start(resourceContext);
+ }
+
+ private void setupJettyServer(int httpPort) {
+ jettyServer = new Server(new InetSocketAddress(HTTP_HOST, httpPort));
+ ServletContextHandler context = new
ServletContextHandler(ServletContextHandler.SESSIONS);
+ context.setContextPath("/");
+ jettyServer.setHandler(context);
+ HttpServlet testServlet = new TestServlet();
+ context.addServlet(new ServletHolder(testServlet), "/*");
+ }
+
+ private static int getJettyPort() {
+ String httpPortVariable = System.getProperty(HTTP_PORT_VARIABLE);
+ if (StringUtil.isNotBlank(httpPortVariable)) {
+ try {
+ int port = Integer.parseInt(httpPortVariable);
+ LOG.info("Using port " + httpPortVariable + " for http
server");
+ return port;
+ } catch (NumberFormatException e) {
+ LOG.warn("Invalid port variable: " + httpPortVariable);
+ }
+ }
+ LOG.info("Using default port " + String.valueOf(HTTP_PORT) + " for
http server");
+ return HTTP_PORT;
+ }
+
+ private void setupResourceContext(int httpPort) {
+
when(resourceContext.getPluginConfiguration()).thenReturn(pluginConfig(httpPort));
+ when(resourceContext.getResourceKey()).thenReturn("/TestServer");
+
when(resourceContext.getSystemInformation()).thenReturn(SystemInfoFactory.createJavaSystemInfo());
+
when(resourceContext.getAvailabilityContext()).thenReturn(Mockito.mock(AvailabilityContext.class));
+ }
+
+ private Configuration pluginConfig(int httpPort) {
+ Configuration pluginConfig = new Configuration();
+ pluginConfig.setSimpleValue(HOSTNAME, "localhost");
+ pluginConfig.setSimpleValue(PORT, String.valueOf(httpPort));
+ pluginConfig.setSimpleValue(USER, "pipo");
+ pluginConfig.setSimpleValue(PASSWORD, "molo");
+ pluginConfig.setSimpleValue(MANAGEMENT_CONNECTION_TIMEOUT, "-1");
+ pluginConfig.getMap().put(LOG_EVENT_SOURCES_CONFIG_PROP, new PropertyList());
+ return pluginConfig;
+ }
+
+ @AfterMethod
+ private void tearDown() throws Exception {
+ LOG.info("Shutting down Jetty test server");
+ try {
+ if (jettyServer != null) {
+ jettyServer.stop();
+ }
+ } catch (Exception ignore) {
+ }
+ if (executorService != null) {
+ executorService.shutdownNow();
+ }
+ }
+
+ @Test(timeOut = 60 * 1000)
+ public void testReloadOperation() throws Exception {
+ OperationResult operationResult =
serverComponent.invokeOperation("reload", new Configuration());
+ assertEquals(operationResult.getSimpleResult(), "Success");
+ }
+
+ @Test(timeOut = 60 * 1000)
+ public void testShutdown() throws Exception {
+ OperationResult operationResult =
serverComponent.invokeOperation("shutdown", new Configuration());
+ assertEquals(operationResult.getSimpleResult(), "Success");
+ }
+
+ private class RestartJetty implements Runnable {
+ @Override
+ public void run() {
+ try {
+ jettyServer.stop();
+ } catch (Exception ignore) {
+ }
+ try {
+ Thread.sleep(SECONDS.toMillis(2));
+ } catch (Exception ignore) {
+ }
+ try {
+ jettyServer.start();
+ } catch (Exception ignore) {
+ }
+ }
+ }
+
+ private class TestServlet extends HttpServlet {
+
+ private ObjectMapper objectMapper = new ObjectMapper();
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
+ Operation operation = objectMapper.readValue(req.getInputStream(),
Operation.class);
+ // Check if we recevied an operation which a real http management interface
might interrupt
+ if (operation.getOperation().equals("reload") ||
operation.getOperation().equals("shutdown")) {
+ // Schedule a Jetty restart
+ executorService.submit(new RestartJetty());
+ // Then wait until Jetty is shutdown
+ try {
+ Thread.sleep(Long.MAX_VALUE);
+ } catch (InterruptedException ignore) {
+ }
+ return;
+ }
+ // Standard operation. Return simple success
+ Result result = new Result();
+ result.setOutcome("success");
+ objectMapper.writeValue(resp.getOutputStream(), result);
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
+ doPost(req, resp);
+ }
+
+ }
+
+ // Tweak StandaloneASComponent implementation for this test case
+ private class TestStandaloneASComponent extends StandaloneASComponent {
+
+ @Override
+ public AvailabilityType getAvailability() {
+ // Avoid various management requests when component is started
+ return AvailabilityType.DOWN;
+ }
+
+ @Override
+ protected boolean waitUntilDown() throws InterruptedException {
+ // Standard implementation relies on discovery of some resource properties
+ return true;
+ }
+ }
+
+}