modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java | 260 +++++-----
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java | 3
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java | 1
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/Domain2Descriptor.java | 188 +++----
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TemplatedComponent.java | 11
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Result.java | 8
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/AbstractConfigurationHandlingTest.java | 31 -
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/TemplatedComponentTest.java | 13
8 files changed, 273 insertions(+), 242 deletions(-)
New commits:
commit e9406f9060c6d893e03e8f1d00bbf88053b5a9ca
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Fri Nov 29 14:51:57 2013 +0100
Reverted commit dd1f836e7df7b6be3773b6b15165baa85a7b703e and updated test code which caused NPE
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TemplatedComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TemplatedComponent.java
index 57cfadd..21211dc 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TemplatedComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/TemplatedComponent.java
@@ -1,8 +1,7 @@
/*
* RHQ Management Platform
- * Copyright 2012, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
+ * 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
@@ -14,8 +13,8 @@
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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;
@@ -109,7 +108,7 @@ public class TemplatedComponent extends BaseComponent<ResourceComponent<?>> {
additionalProperties.put("attributes-only", "true");
currentAttributesOp.setAdditionalProperties(additionalProperties);
Result currentAttributes = getASConnection().execute(currentAttributesOp);
- if ((currentAttributes!=null)&&(currentAttributes.isSuccess())) {
+ if (currentAttributes.isSuccess()) {
currentAttributeList = (Map<String, Object>) currentAttributes.getResult();
}
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/AbstractConfigurationHandlingTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/AbstractConfigurationHandlingTest.java
index 5eaa0e9..ca1cc36 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/AbstractConfigurationHandlingTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/AbstractConfigurationHandlingTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,13 +13,15 @@
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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;
+import static org.rhq.modules.plugins.jbossas7.json.Result.FAILURE;
+
import java.io.BufferedReader;
-import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
@@ -32,8 +34,6 @@ import javax.xml.bind.util.ValidationEventCollector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;
@@ -53,15 +53,16 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* @author Heiko W. Rupp
*/
public abstract class AbstractConfigurationHandlingTest {
+ private static final Log LOG = LogFactory.getLog(AbstractConfigurationHandlingTest.class);
private static final String DESCRIPTOR_FILENAME = "test-plugin.xml";
- private Log log = LogFactory.getLog(getClass());
+
private PluginDescriptor pluginDescriptor;
void loadPluginDescriptor() throws Exception {
try {
URL descriptorUrl = this.getClass().getClassLoader().getResource(DESCRIPTOR_FILENAME);
- log.info("Loading plugin descriptor at: " + descriptorUrl);
+ LOG.info("Loading plugin descriptor at: " + descriptorUrl);
JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN);
@@ -151,15 +152,15 @@ public abstract class AbstractConfigurationHandlingTest {
@Override
public Result execute(Operation op) {
JsonNode json = executeRaw(op);
- Result result = null;
+ Result result;
try {
result = mapper.readValue(json, Result.class);
- } catch (JsonParseException e) {
- e.printStackTrace();
- } catch (JsonMappingException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+ } catch (Exception e) {
+ LOG.warn("Could not read jsonValue", e);
+ result = new Result();
+ result.setOutcome(FAILURE);
+ result.setFailureDescription(e.getMessage());
+ result.setRhqThrowable(e);
}
return result;
}
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/TemplatedComponentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/TemplatedComponentTest.java
index 061390c..3cd06f7 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/TemplatedComponentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/TemplatedComponentTest.java
@@ -1,8 +1,7 @@
/*
* RHQ Management Platform
- * Copyright 2011, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
+ * 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
@@ -14,8 +13,8 @@
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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;
@@ -48,6 +47,8 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.modules.plugins.jbossas7.json.Address;
+import org.rhq.modules.plugins.jbossas7.json.ReadResource;
+import org.rhq.modules.plugins.jbossas7.json.Result;
/**
* @author Stefan Negrea
@@ -230,6 +231,7 @@ public class TemplatedComponentTest {
.thenReturn(mockConfigurationWriteDelegate);
ASConnection mockASConnection = mock(ASConnection.class);
+ when(mockASConnection.execute(any(ReadResource.class))).thenReturn(new Result());
//create object to test and inject required dependencies
@@ -287,6 +289,7 @@ public class TemplatedComponentTest {
.thenReturn(mockConfigurationWriteDelegate);
ASConnection mockASConnection = mock(ASConnection.class);
+ when(mockASConnection.execute(any(ReadResource.class))).thenReturn(new Result());
//create object to test and inject required dependencies
TemplatedComponent objectUnderTest = new TemplatedComponent();
commit 8b7322dcc1ca48ca7fc108297956a3b497c70acf
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Fri Nov 29 14:15:13 2013 +0100
Remove finalizer from ASConnection
Make ASConnection code easier to read
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java
index 5ae86d1..bb4414f 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java
@@ -19,14 +19,16 @@
package org.rhq.modules.plugins.jbossas7;
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static org.rhq.modules.plugins.jbossas7.json.Result.FAILURE;
+
import java.io.IOException;
import java.lang.ref.WeakReference;
-import java.util.StringTokenizer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -69,6 +71,7 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* @author Thomas Segismont
*/
public class ASConnection {
+ private static final Log LOG = LogFactory.getLog(ASConnection.class);
public static final String HTTP_SCHEME = "http";
@@ -85,7 +88,7 @@ public class ASConnection {
static final String FAILURE_NO_RESPONSE = "The server closed the connection before sending the response";
- private static final Log LOG = LogFactory.getLog(ASConnection.class);
+ private static final String FAILURE_SHUTDOWN = "The HTTP connection has already been shutdown";
private static final int MAX_POOLED_CONNECTIONS = 10;
@@ -97,24 +100,8 @@ public class ASConnection {
// A shared scheduled executor service to free HttpClient resources
// One thread is enough as tasks will execute quickly
- private static final ScheduledExecutorService cleanerExecutor = Executors.newScheduledThreadPool(1,
- new ThreadFactory() {
-
- private ThreadFactory defaultThreadFactory = Executors.defaultThreadFactory();
-
- private AtomicInteger threadCounter = new AtomicInteger(0);
-
- @Override
- public Thread newThread(Runnable runnable) {
- Thread thread = defaultThreadFactory.newThread(runnable);
- thread.setName("ASConnection Cleaner-" + threadCounter.incrementAndGet());
- // With daemon threads, there is no need to call #shutdown on the executor to let the JVM go down
- thread.setDaemon(true);
- return thread;
- }
- });
-
- private String scheme = ASConnection.HTTP_SCHEME;
+ private static final ScheduledExecutorService cleanerExecutor = Executors
+ .newSingleThreadScheduledExecutor(new ThreadFactory());
private String host;
@@ -130,6 +117,8 @@ public class ASConnection {
private ObjectMapper mapper;
+ private volatile boolean shutdown;
+
/**
* Construct an ASConnection object. The real "physical" connection is done in {@link #executeRaw(Operation)}.
*
@@ -157,7 +146,6 @@ public class ASConnection {
public ASConnection(String host, int port, String user, String password, Long managementConnectionTimeout) {
// Check and store the basic parameters
-
if (host == null) {
throw new IllegalArgumentException("Management host cannot be null.");
}
@@ -169,7 +157,8 @@ public class ASConnection {
if (user != null && password != null) {
credentials = new UsernamePasswordCredentials(user, password);
}
- managementUrl = scheme + "://" + host + ":" + port + MANAGEMENT_URI;
+
+ managementUrl = HTTP_SCHEME + "://" + host + ":" + port + MANAGEMENT_URI;
// Each ASConnection instance will have its own HttpClient instance
// HttpClient will use a pooling connection manager to allow concurrent request processing
@@ -223,6 +212,8 @@ public class ASConnection {
mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+
+ shutdown = false;
}
@@ -230,13 +221,12 @@ public class ASConnection {
return new ASConnection(serverPluginConfig.getHostname(), serverPluginConfig.getPort(), serverPluginConfig.getUser(), serverPluginConfig.getPassword(), serverPluginConfig.getManagementConnectionTimeout());
}
-
- @Override
- protected void finalize() throws Throwable {
+ public void shutdown() {
// Defensive call to shutdown the HttpClient connection manager
// If an ASConnection instance is no longer used, its cleaning task should already
// have closed expired connections
httpClient.getConnectionManager().shutdown();
+ shutdown = true;
}
/**
@@ -272,41 +262,33 @@ public class ASConnection {
* @see #executeComplex(org.rhq.modules.plugins.jbossas7.json.Operation)
*/
public JsonNode executeRaw(Operation operation, int timeoutSec) {
+ if (shutdown) {
+ return resultAsJsonNode(FAILURE, FAILURE_SHUTDOWN, null, FALSE);
+ }
- long requestStartTime = System.currentTimeMillis();
+ long requestStartTime = System.nanoTime();
- // Check for spaces in the path, which the AS7 server will reject. Log verbose error and
- // generate failure indicator.
- if ((operation != null) && (operation.getAddress() != null) && operation.getAddress().getPath() != null) {
- if (containsSpaces(operation.getAddress().getPath())) {
- Result noResult = new Result();
- String outcome = "- Path '" + operation.getAddress().getPath() + "' is invalid as it contains spaces -";
- if (verbose) {
- LOG.error(outcome);
- }
- noResult.setFailureDescription(outcome);
- noResult.setOutcome("failure");
- JsonNode invalidPathResult = mapper.valueToTree(noResult);
- return invalidPathResult;
+ if (addressPathContainsSpaces(operation) == TRUE) {
+ // Check for spaces in the path, which the AS7 server will reject. Log verbose error and
+ // generate failure indicator.
+ String failureDescription = "- Path '" + operation.getAddress().getPath()
+ + "' is invalid as it contains spaces -";
+ if (verbose) {
+ LOG.error(failureDescription);
}
+ return resultAsJsonNode(FAILURE, failureDescription, null, FALSE);
}
- HttpPost httpRequest = new HttpPost(managementUrl);
- httpRequest.addHeader(ACCEPT_HTTP_HEADER, ContentType.APPLICATION_JSON.getMimeType());
- HttpParams httpParams = httpClient.getParams();
- int timeoutMillis = timeoutSec * 1000;
- HttpConnectionParams.setConnectionTimeout(httpParams, timeoutMillis);
- HttpConnectionParams.setSoTimeout(httpParams, timeoutMillis);
-
+ HttpPost httpPost = null;
try {
-
String jsonToSend = mapper.writeValueAsString(operation);
if (verbose) {
LOG.info("JSON to send: " + jsonToSend);
}
- httpRequest.setEntity(new StringEntity(jsonToSend, ContentType.APPLICATION_JSON));
- HttpResponse httpResponse = httpClient.execute(httpRequest);
+ httpPost = initHttpPost(timeoutSec, jsonToSend);
+
+ HttpResponse httpResponse = httpClient.execute(httpPost);
StatusLine statusLine = httpResponse.getStatusLine();
if (isAuthorizationFailureResponse(statusLine)) {
handleAuthorizationFailureResponse(operation, statusLine);
@@ -315,83 +297,72 @@ public class ASConnection {
HttpEntity httpResponseEntity = httpResponse.getEntity();
String responseBody = httpResponseEntity == null ? StringUtil.EMPTY_STRING : EntityUtils
.toString(httpResponseEntity);
- if (statusLine.getStatusCode() >= 400) {
- if (verbose) {
- if (responseBody.contains("JBAS014807") || responseBody.contains("JBAS010850")
- || responseBody.contains("JBAS014792") || responseBody.contains("JBAS014793")
- || responseBody.contains("JBAS014739")) {
- // management resource not found or not readable or no known child-type
- LOG.info("Requested management resource not found: " + operation.getAddress().getPath());
- } else {
- LOG.warn(operation + " failed with " + statusAsString(statusLine) + " - response body was ["
- + responseBody + "].");
- }
- }
+ if (verbose && statusLine.getStatusCode() >= 400) {
+ logHttpError(operation, statusLine, responseBody);
}
JsonNode operationResult;
if (!responseBody.isEmpty()) {
- try {
- operationResult = mapper.readTree(responseBody);
- } catch (IOException ioe) {
- LOG.error("Failed to deserialize response to " + operation + " to JsonNode - response status was "
- + statusAsString(statusLine) + ", and body was [" + responseBody + "]: " + ioe);
- Result result = new Result();
- result.setOutcome("failure");
- result.setFailureDescription("Failed to deserialize response to " + operation
- + " to JsonNode - response status was " + statusAsString(statusLine) + ", and body was ["
- + responseBody + "]: " + ioe);
- result.setRolledBack(responseBody.contains("rolled-back=true"));
- result.setRhqThrowable(ioe);
- operationResult = mapper.valueToTree(result);
- }
-
+ operationResult = deserializeResponseBody(operation, statusLine, responseBody);
if (verbose) {
- ObjectMapper om2 = new ObjectMapper();
- om2.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
- try {
- String resultString = om2.writeValueAsString(operationResult);
- LOG.info(resultString);
- } catch (IOException ioe) {
- LOG.error("Failed to convert result of " + operation + " to string.", ioe);
- }
+ logFormatted(operationResult);
}
} else {
- Result noResult = new Result();
- noResult.setOutcome("failure");
- noResult.setFailureDescription("- empty response body with HTTP status code "
- + statusAsString(statusLine) + " -");
- operationResult = mapper.valueToTree(noResult);
+ operationResult = resultAsJsonNode(FAILURE, "- empty response body with HTTP status code "
+ + statusAsString(statusLine) + " -", null, FALSE);
}
-
return operationResult;
-
} catch (NoHttpResponseException e) {
// For some operations like reload or shutdown, the server closes the connection before sending the
// response. We use a specific description here so that callers can write code to decide what to do
// in this situation.
- Result failure = new Result();
- failure.setFailureDescription(FAILURE_NO_RESPONSE);
- failure.setOutcome("failure");
- failure.setRhqThrowable(e);
- JsonNode ret = mapper.valueToTree(failure);
- return ret;
+ return resultAsJsonNode(FAILURE, FAILURE_NO_RESPONSE, e, FALSE);
} catch (IOException e) {
- Result failure = new Result();
- failure.setFailureDescription(e.getMessage());
- failure.setOutcome("failure");
- failure.setRhqThrowable(e);
- JsonNode ret = mapper.valueToTree(failure);
- return ret;
+ return resultAsJsonNode(FAILURE, e.getMessage(), e, FALSE);
} finally {
- // Force release of httpclient resources
- httpRequest.abort();
- // Update statistics
- long requestEndTime = System.currentTimeMillis();
- PluginStats stats = PluginStats.getInstance();
- stats.incrementRequestCount();
- stats.addRequestTime(requestEndTime - requestStartTime);
+ if (httpPost != null) {
+ // Release of httpclient resources
+ httpPost.abort();
+ }
+ updateStatistics(requestStartTime, System.nanoTime());
+ }
+ }
+
+ private JsonNode resultAsJsonNode(String outcome, String failureDescription, Throwable rhqThrowable,
+ Boolean rolledBack) {
+ Result result = new Result();
+ result.setOutcome(outcome);
+ if (failureDescription != null) {
+ result.setFailureDescription(failureDescription);
}
+ if (rhqThrowable != null) {
+ result.setRhqThrowable(rhqThrowable);
+ }
+ if (rolledBack == TRUE) {
+ result.setRolledBack(true);
+ }
+ return mapper.valueToTree(result);
+ }
+
+ private Boolean addressPathContainsSpaces(Operation operation) {
+ Boolean addressPathContainsSpaces = FALSE;
+ if ((operation != null) && (operation.getAddress() != null) && operation.getAddress().getPath() != null) {
+ if (containsSpaces(operation.getAddress().getPath())) {
+ addressPathContainsSpaces = TRUE;
+ }
+ }
+ return addressPathContainsSpaces;
+ }
+
+ private HttpPost initHttpPost(int timeoutSec, String jsonToSend) {
+ HttpPost httpPost = new HttpPost(managementUrl);
+ httpPost.addHeader(ACCEPT_HTTP_HEADER, ContentType.APPLICATION_JSON.getMimeType());
+ HttpParams httpParams = httpClient.getParams();
+ int timeoutMillis = timeoutSec * 1000;
+ HttpConnectionParams.setConnectionTimeout(httpParams, timeoutMillis);
+ HttpConnectionParams.setSoTimeout(httpParams, timeoutMillis);
+ httpPost.setEntity(new StringEntity(jsonToSend, ContentType.APPLICATION_JSON));
+ return httpPost;
}
// When no management users have been configured, a 307 (Temporary Redirect) response will be returned, and
@@ -405,7 +376,7 @@ public class ASConnection {
private void handleAuthorizationFailureResponse(Operation operation, StatusLine statusLine) {
if (LOG.isDebugEnabled()) {
LOG.debug("Response to " + operation + " was " + statusAsString(statusLine)
- + " - throwing InvalidPluginConfigurationException...");
+ + " - throwing InvalidPluginConfigurationException...");
}
// Throw a InvalidPluginConfigurationException, so the user will get a yellow plugin connection
// warning message in the GUI.
@@ -418,18 +389,55 @@ public class ASConnection {
throw new InvalidPluginConfigurationException(message);
}
+ private void logHttpError(Operation operation, StatusLine statusLine, String responseBody) {
+ if (responseBody.contains("JBAS014807") || responseBody.contains("JBAS010850")
+ || responseBody.contains("JBAS014792") || responseBody.contains("JBAS014793")
+ || responseBody.contains("JBAS014739")) {
+ // management resource not found or not readable or no known child-type
+ LOG.info("Requested management resource not found: " + operation.getAddress().getPath());
+ } else {
+ LOG.warn(operation + " failed with " + statusAsString(statusLine) + " - response body was ["
+ + responseBody + "].");
+ }
+ }
+
+ private void logFormatted(JsonNode operationResult) {
+ ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+ try {
+ LOG.info(objectMapper.writeValueAsString(operationResult));
+ } catch (IOException ignore) {
+ }
+ }
+
+ private JsonNode deserializeResponseBody(Operation operation, StatusLine statusLine, String responseBody) {
+ JsonNode operationResult;
+ try {
+ operationResult = mapper.readTree(responseBody);
+ } catch (IOException ioe) {
+ String failureDescription = "Failed to deserialize response to " + operation
+ + " to JsonNode - response status was " + statusAsString(statusLine) + ", and body was ["
+ + responseBody + "]: " + ioe;
+ LOG.error(failureDescription);
+ operationResult = resultAsJsonNode(FAILURE, failureDescription, ioe,
+ responseBody.contains("rolled-back=true"));
+ }
+ return operationResult;
+ }
+
+ private void updateStatistics(long requestStartTime, long requestEndTime) {
+ PluginStats stats = PluginStats.getInstance();
+ stats.incrementRequestCount();
+ stats.addRequestTime(NANOSECONDS.toMillis(requestEndTime - requestStartTime));
+ }
+
/** Method parses Operation.getAddress().getPath() for invalid spaces in the path passed in.
*
* @param path Operation.getAddress().getPath() value.
* @return boolean indicating invalid spaces found.
*/
private boolean containsSpaces(String path) {
- boolean includesSpaces = false;
- StringTokenizer components = new StringTokenizer(path, " ");
- if (components.countTokens() > 1) {
- includesSpaces = true;
- }
- return includesSpaces;
+ return path.indexOf(" ") != -1;
}
/**
@@ -579,8 +587,7 @@ public class ASConnection {
@Override
public void run() {
ASConnection asConnection = asConnectionWeakReference.get();
- if (asConnection != null) {
- // The target ASConnection instance has not been marked for collection yet
+ if (asConnection != null && !asConnection.shutdown) {
try {
asConnection.httpClient.getConnectionManager().closeExpiredConnections();
// Defensive call to close idle connections
@@ -595,4 +602,15 @@ public class ASConnection {
}
}
+ private static class ThreadFactory implements java.util.concurrent.ThreadFactory {
+
+ @Override
+ public Thread newThread(Runnable runnable) {
+ Thread thread = Executors.defaultThreadFactory().newThread(runnable);
+ thread.setName("ASConnection Cleaner");
+ // With daemon threads, there is no need to call #shutdown on the executor to let the JVM go down
+ thread.setDaemon(true);
+ return thread;
+ }
+ }
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
index 85f409d..25063ac 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java
@@ -16,6 +16,7 @@
* 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;
import static java.lang.Boolean.FALSE;
@@ -725,6 +726,8 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
} catch (InvalidPluginConfigurationException e) {
log.debug("Could not get the product info from [" + hostname + ":" + port
+ "] - probably a connection failure");
+ } finally {
+ connection.shutdown();
}
return this;
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
index 1e84c06..944d7c5 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java
@@ -123,6 +123,7 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend
@Override
public void stop() {
+ connection.shutdown();
logFileEventDelegate.stopLogFileEventPollers();
previousAvailabilityType = null;
if (this.availabilityCollector != null) {
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/Domain2Descriptor.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/Domain2Descriptor.java
index a532c3a..633997b 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/Domain2Descriptor.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/Domain2Descriptor.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2012 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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;
@@ -111,103 +111,107 @@ public class Domain2Descriptor {
//create connection
ASConnection conn = new ASConnection("localhost", 9990, user, pass);
-
- Address address = new Address(path);
-
- //create request to get metadata type information
- Operation op = new Operation("read-resource-description", address);
- //recurse down the tree.
- op.addAdditionalProperty("recursive", "true");
-
- //additionally request operation metadata
- if (mode == D2DMode.OPERATION) {
- op.addAdditionalProperty("operations", true);
- }
- //additionally request metric metadata
- if (mode == D2DMode.METRICS) {
- op.addAdditionalProperty("include-runtime", true);
- }
- //additionally request both metric and operations metadata
- if (mode == D2DMode.RECURSIVE) {
- op.addAdditionalProperty("operations", true);
- op.addAdditionalProperty("include-runtime", true);
- }
-
- ComplexResult res = conn.executeComplex(op);
- if (res == null) {
- System.err.println("Got no result");
- return;
- }
- if (!res.isSuccess()) {
- System.err.println("Failure: " + res.getFailureDescription());
- return;
- }
-
- //load json object hierarchy of response
- Map<String, Object> resMap = res.getResult();
- String what;
- if (mode == D2DMode.OPERATION) {
- what = "operations";
- } else {
- what = "attributes";
- }
-
- //Determine which attributes to focus on.
- Map<String, Object> attributesMap = null;
-
- //when will childtype is actually passed then...
- if (childType != null) {
-
- Map childMap = (Map) resMap.get("children");
- Map<String, Object> typeMap = (Map<String, Object>) childMap.get(childType);
- if (typeMap == null) {
- System.err.println("No child with type '" + childType + "' found");
+ try {
+
+ Address address = new Address(path);
+
+ //create request to get metadata type information
+ Operation op = new Operation("read-resource-description", address);
+ //recurse down the tree.
+ op.addAdditionalProperty("recursive", "true");
+
+ //additionally request operation metadata
+ if (mode == D2DMode.OPERATION) {
+ op.addAdditionalProperty("operations", true);
+ }
+ //additionally request metric metadata
+ if (mode == D2DMode.METRICS) {
+ op.addAdditionalProperty("include-runtime", true);
+ }
+ //additionally request both metric and operations metadata
+ if (mode == D2DMode.RECURSIVE) {
+ op.addAdditionalProperty("operations", true);
+ op.addAdditionalProperty("include-runtime", true);
+ }
+
+ ComplexResult res = conn.executeComplex(op);
+ if (res == null) {
+ System.err.println("Got no result");
return;
}
- Map descriptionMap = (Map) typeMap.get("model-description");
- if (descriptionMap == null) {
- System.err.println("No model description found");
+ if (!res.isSuccess()) {
+ System.err.println("Failure: " + res.getFailureDescription());
return;
}
- Map starMap = (Map) descriptionMap.get("*");
- if (starMap != null) {
- attributesMap = (Map<String, Object>) starMap.get(what);
- } else {//when no *map is provided check for 'classic'
- Map classicMap = (Map) descriptionMap.get("classic");
- attributesMap = (Map<String, Object>) classicMap.get(what);
- }//spinder: What about 'jsapi'? This occurs on some nodes.
- } else {//no child type passed in just load typical map
- attributesMap = (Map<String, Object>) resMap.get(what);
- }
-
- if (mode == D2DMode.OPERATION) {
- //populate operations(each special map type) and sort them for ordered listing
- Set<String> strings = attributesMap.keySet();
- String[] keys = strings.toArray(new String[strings.size()]);
- Arrays.sort(keys);
-
- for (String key : keys) {
- //exclude typical 'read-' and 'write-attribute' operations typical to all types.
- if (!isExcludedOperation(key)) {
- //for each custom operation found, retrieve child hierarchy and pass into
- Map<String, Object> value = (Map<String, Object>) attributesMap.get(key);
- createOperation(key, value);
+
+ //load json object hierarchy of response
+ Map<String, Object> resMap = res.getResult();
+ String what;
+ if (mode == D2DMode.OPERATION) {
+ what = "operations";
+ } else {
+ what = "attributes";
+ }
+
+ //Determine which attributes to focus on.
+ Map<String, Object> attributesMap = null;
+
+ //when will childtype is actually passed then...
+ if (childType != null) {
+
+ Map childMap = (Map) resMap.get("children");
+ Map<String, Object> typeMap = (Map<String, Object>) childMap.get(childType);
+ if (typeMap == null) {
+ System.err.println("No child with type '" + childType + "' found");
+ return;
}
+ Map descriptionMap = (Map) typeMap.get("model-description");
+ if (descriptionMap == null) {
+ System.err.println("No model description found");
+ return;
+ }
+ Map starMap = (Map) descriptionMap.get("*");
+ if (starMap != null) {
+ attributesMap = (Map<String, Object>) starMap.get(what);
+ } else {//when no *map is provided check for 'classic'
+ Map classicMap = (Map) descriptionMap.get("classic");
+ attributesMap = (Map<String, Object>) classicMap.get(what);
+ }//spinder: What about 'jsapi'? This occurs on some nodes.
+ } else {//no child type passed in just load typical map
+ attributesMap = (Map<String, Object>) resMap.get(what);
}
- } else if (mode == D2DMode.RECURSIVE) {// list the child nodes and properties
- String legend = "Key: - property, -M metric,* req'd, + operation, [] child node.";
- StringBuilder tree = new StringBuilder(path + " ->\t" + legend + " \n");
- if (!descriptorSegment) {
- System.out.print(tree);
- listPropertiesAndChildren(3, resMap);
+
+ if (mode == D2DMode.OPERATION) {
+ //populate operations(each special map type) and sort them for ordered listing
+ Set<String> strings = attributesMap.keySet();
+ String[] keys = strings.toArray(new String[strings.size()]);
+ Arrays.sort(keys);
+
+ for (String key : keys) {
+ //exclude typical 'read-' and 'write-attribute' operations typical to all types.
+ if (!isExcludedOperation(key)) {
+ //for each custom operation found, retrieve child hierarchy and pass into
+ Map<String, Object> value = (Map<String, Object>) attributesMap.get(key);
+ createOperation(key, value);
+ }
+ }
+ } else if (mode == D2DMode.RECURSIVE) {// list the child nodes and properties
+ String legend = "Key: - property, -M metric,* req'd, + operation, [] child node.";
+ StringBuilder tree = new StringBuilder(path + " ->\t" + legend + " \n");
+ if (!descriptorSegment) {
+ System.out.print(tree);
+ listPropertiesAndChildren(3, resMap);
+ } else {
+ System.out.println(generateSegment(path, 0));
+ listPropertiesAndChildren(3, resMap);
+ System.out.println("</service>\n");
+ }
+
} else {
- System.out.println(generateSegment(path, 0));
- listPropertiesAndChildren(3, resMap);
- System.out.println("</service>\n");
+ createProperties(mode, attributesMap, 0, false);
}
-
- } else {
- createProperties(mode, attributesMap, 0, false);
+ } finally {
+ conn.shutdown();
}
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Result.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Result.java
index 3fbdb90..a490baf 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Result.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/json/Result.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,9 +13,10 @@
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.json;
import java.util.Map;
@@ -35,6 +36,7 @@ import org.codehaus.jackson.annotate.JsonProperty;
public class Result {
public static final String SUCCESS = "success";
+ public static final String FAILURE = "failure";
private String outcome;
private Object result;
@JsonProperty("failure-description")