[rhq] modules/plugins
by Thomas Segismont
modules/plugins/jboss-as-7/pom.xml | 4
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnection.java | 241 +++++----
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnectionParams.java | 214 ++++++++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnectionParamsBuilder.java | 131 +++++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java | 254 +++++-----
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java | 4
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseProcessDiscovery.java | 71 +-
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java | 6
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DeploymentComponent.java | 6
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/Domain2Descriptor.java | 11
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SchemeRegistryBuilder.java | 142 +++++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java | 6
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java | 130 +++--
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostPort.java | 11
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostnameVerification.java | 45 +
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java | 113 ++++
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/TrustStrategy.java | 45 +
modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml | 88 +++
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/AbstractConfigurationHandlingTest.java | 9
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java | 14
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/AbstractIntegrationTest.java | 26 -
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/InterruptibleOperationsTest.java | 251 +++++++++
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java | 31 +
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java | 241 ---------
24 files changed, 1520 insertions(+), 574 deletions(-)
New commits:
commit a201914f7204e59fb40ce3eba2cbbea7accd728c
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Wed Jan 22 16:02:06 2014 +0100
Bug 840403 - (PRODMGT-454) the plugin for JBoss EAP 6 / AS 7 needs to support SSL/TLS encryption and authentication
Introduced new ASConnectionParams and ASConnectionParamsBuilder to avoid rebuilding ASConnection and ASUploadConnection constructors over and over
Manually tested different versions AS7 / EAP6 Standalone and domain mode (including content upload)
API check passes
Updated Httpclient version (new version is already productized)
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml
index 401f21c..d764f6c 100644
--- a/modules/plugins/jboss-as-7/pom.xml
+++ b/modules/plugins/jboss-as-7/pom.xml
@@ -22,7 +22,7 @@
<json.version>${project.json.version}</json.version>
<jboss.sasl.version>1.0.0.Final</jboss.sasl.version>
<!-- If you change httpclient4.version make sure to update httpcore version below accordingly -->
- <httpclient4.version>4.2.3</httpclient4.version>
+ <httpclient4.version>${apache.httpcomponents.version}</httpclient4.version>
<as7.version>7.1.2.Final-SNAPSHOT</as7.version>
<as7.url>https://hudson.jboss.org/hudson/view/JBoss%20AS/job/JBoss-AS-7.0.x/lastSu...</as7.url>
<jboss-as-arquillian-container-managed.version>7.1.1.Final</jboss-as-arquillian-container-managed.version>
@@ -151,7 +151,7 @@
<artifactItem>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
- <version>4.2.2</version>
+ <version>${httpclient4.version}</version>
</artifactItem>
<artifactItem>
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 bb4414f..299dadf 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
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,8 @@ import static org.rhq.modules.plugins.jbossas7.json.Result.FAILURE;
import java.io.IOException;
import java.lang.ref.WeakReference;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -39,8 +41,11 @@ import org.apache.http.NoHttpResponseException;
import org.apache.http.StatusLine;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.HttpClientParams;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
@@ -74,7 +79,7 @@ public class ASConnection {
private static final Log LOG = LogFactory.getLog(ASConnection.class);
public static final String HTTP_SCHEME = "http";
-
+ public static final String HTTPS_SCHEME = "https";
public static final String MANAGEMENT_URI = "/management";
// This is a variable on purpose, so devs can switch it on in the debugger or in the agent
@@ -89,13 +94,8 @@ public class ASConnection {
static final String FAILURE_NO_RESPONSE = "The server closed the connection before sending the response";
private static final String FAILURE_SHUTDOWN = "The HTTP connection has already been shutdown";
-
private static final int MAX_POOLED_CONNECTIONS = 10;
-
- private static final int DEFAULT_KEEPALIVE_TIMEOUT = 5 * 1000; // 5sec
-
private static final String ACCEPT_HTTP_HEADER = "Accept";
-
private static final String JSON_NODE_FAILURE_DESCRIPTION = "failure-description";
// A shared scheduled executor service to free HttpClient resources
@@ -103,111 +103,86 @@ public class ASConnection {
private static final ScheduledExecutorService cleanerExecutor = Executors
.newSingleThreadScheduledExecutor(new ThreadFactory());
- private String host;
-
- private int port;
-
- private UsernamePasswordCredentials credentials;
-
- private long keepAliveTimeout;
-
- private String managementUrl;
-
- private DefaultHttpClient httpClient;
-
- private ObjectMapper mapper;
+ private final ASConnectionParams asConnectionParams;
+ private final URI managementUri;
+ private final DefaultHttpClient httpClient;
+ private final ObjectMapper mapper;
+ private volatile long keepAliveTimeout;
private volatile boolean shutdown;
/**
- * Construct an ASConnection object. The real "physical" connection is done in {@link #executeRaw(Operation)}.
- *
- * The returned instance will use the default keep alive connection timeout.
- *
- * @param host Host of the DomainController or standalone server
- * @param port Port of the JSON api.
- * @param user user needed for authentication
- * @param password password needed for authentication
+ * @deprecated as of RHQ 4.10, use {@link #ASConnection(ASConnectionParams)} instead
*/
+ @Deprecated
public ASConnection(String host, int port, String user, String password) {
this(host, port, user, password, null);
}
/**
- * Create a new instance.
- *
- * @param host Host of the DomainController or standalone server
- * @param port Port of the JSON api.
- * @param user User needed for authentication
- * @param password Password needed for authentication
- * @param managementConnectionTimeout Maximum time to keep alive a management connection. Zero and negative values
- * will disable connection persistence.
+ * @deprecated as of RHQ 4.10, use {@link #ASConnection(ASConnectionParams)} instead
*/
+ @Deprecated
public ASConnection(String host, int port, String user, String password, Long managementConnectionTimeout) {
+ this(new ASConnectionParamsBuilder() //
+ .setHost(host) //
+ .setPort(port) //
+ .setUsername(user) //
+ .setPassword(password) //
+ .setKeepAliveTimeout(managementConnectionTimeout) //
+ .createASConnectionParams());
+ }
+
+ public ASConnection(ASConnectionParams params) {
+ asConnectionParams = params;
// Check and store the basic parameters
- if (host == null) {
+ if (asConnectionParams.getHost() == null) {
throw new IllegalArgumentException("Management host cannot be null.");
}
- if (port <= 0 || port > 65535) {
- throw new IllegalArgumentException("Invalid port: " + port);
+ if (asConnectionParams.getPort() <= 0 || asConnectionParams.getPort() > 65535) {
+ throw new IllegalArgumentException("Invalid port: " + asConnectionParams.getPort());
}
- this.host = host;
- this.port = port;
- if (user != null && password != null) {
- credentials = new UsernamePasswordCredentials(user, password);
+
+ UsernamePasswordCredentials credentials = null;
+ if (asConnectionParams.getUsername() != null && asConnectionParams.getPassword() != null) {
+ credentials = new UsernamePasswordCredentials(asConnectionParams.getUsername(),
+ asConnectionParams.getPassword());
}
- managementUrl = HTTP_SCHEME + "://" + host + ":" + port + MANAGEMENT_URI;
+ keepAliveTimeout = asConnectionParams.getKeepAliveTimeout();
+
+ managementUri = buildManagementUri();
+
+ // Each ASConnection instance will have its own HttpClient instance. Setup begins here
+
+ SchemeRegistry schemeRegistry = new SchemeRegistryBuilder(asConnectionParams).buildSchemeRegistry();
- // Each ASConnection instance will have its own HttpClient instance
// HttpClient will use a pooling connection manager to allow concurrent request processing
- PoolingClientConnectionManager httpConnectionManager = new PoolingClientConnectionManager();
+ PoolingClientConnectionManager httpConnectionManager = new PoolingClientConnectionManager(schemeRegistry);
httpConnectionManager.setDefaultMaxPerRoute(MAX_POOLED_CONNECTIONS);
httpConnectionManager.setMaxTotal(MAX_POOLED_CONNECTIONS);
+
httpClient = new DefaultHttpClient(httpConnectionManager);
- // Disable stale connection checking on connection lease to get better performance
HttpParams httpParams = httpClient.getParams();
+
+ // Disable stale connection checking on connection lease to get better performance
// See http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html
HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);
- keepAliveTimeout = managementConnectionTimeout == null ? DEFAULT_KEEPALIVE_TIMEOUT : managementConnectionTimeout;
- // Do not reuse connection if keep alive timeout has zero or negative value
- httpClient.setReuseStrategy(new DefaultConnectionReuseStrategy() {
- @Override
- public boolean keepAlive(HttpResponse response, HttpContext context) {
- return keepAliveTimeout > 0 && super.keepAlive(response, context);
- }
- });
+
+ httpClient.setReuseStrategy(new CustomConnectionReuseStrategy(this));
if (keepAliveTimeout > 0) {
- // The default keep-alive strategy does not expire connections if the 'Keep-Alive' header is not present
- // in the response. This strategy will apply the desired duration in this case.
- httpClient.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy() {
- @Override
- public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
- long duration = super.getKeepAliveDuration(response, context);
- if (duration < 0 || duration > keepAliveTimeout) {
- duration = keepAliveTimeout;
- }
- if (duration < keepAliveTimeout) {
- if (LOG.isWarnEnabled()) {
- LOG.warn(ASConnection.this.host + ":" + ASConnection.this.port
- + " declares a keep alive timeout value of [" + duration
- + "] ms. Will now use this value instead of the value from configuration ["
- + keepAliveTimeout + "] ms.");
- }
- keepAliveTimeout = duration;
- }
- return duration;
- }
- });
+ httpClient.setKeepAliveStrategy(new CustomConnectionKeepAliveStrategy(this));
// Initial schedule of a cleaning task. Subsequent executions will be scheduled as needed.
// See ConnectionManagerCleaner implementation.
- cleanerExecutor.schedule(new ConnectionManagerCleaner(this), keepAliveTimeout / 2,
- TimeUnit.MILLISECONDS);
+ cleanerExecutor.schedule(new ConnectionManagerCleaner(this), keepAliveTimeout / 2, TimeUnit.MILLISECONDS);
}
+
HttpClientParams.setRedirecting(httpParams, false);
+
if (credentials != null) {
- httpClient.getCredentialsProvider().setCredentials(new AuthScope(host, port), credentials);
+ httpClient.getCredentialsProvider().setCredentials(
+ new AuthScope(asConnectionParams.getHost(), asConnectionParams.getPort()), credentials);
}
mapper = new ObjectMapper();
@@ -216,9 +191,25 @@ public class ASConnection {
shutdown = false;
}
+ private URI buildManagementUri() {
+ try {
+ return new URIBuilder() //
+ .setScheme(asConnectionParams.isSecure() ? HTTPS_SCHEME : HTTP_SCHEME) //
+ .setHost(asConnectionParams.getHost()) //
+ .setPort(asConnectionParams.getPort()) //
+ .setPath(MANAGEMENT_URI) //
+ .build();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Could not build management URI: " + e.getMessage(), e);
+ }
+ }
+ /**
+ * @deprecated as of RHQ 4.10, use {@link #ASConnection(ASConnectionParams)} instead
+ */
+ @Deprecated
public static ASConnection newInstanceForServerPluginConfiguration(ServerPluginConfiguration serverPluginConfig) {
- return new ASConnection(serverPluginConfig.getHostname(), serverPluginConfig.getPort(), serverPluginConfig.getUser(), serverPluginConfig.getPassword(), serverPluginConfig.getManagementConnectionTimeout());
+ return new ASConnection(ASConnectionParams.createFrom(serverPluginConfig));
}
public void shutdown() {
@@ -291,7 +282,8 @@ public class ASConnection {
HttpResponse httpResponse = httpClient.execute(httpPost);
StatusLine statusLine = httpResponse.getStatusLine();
if (isAuthorizationFailureResponse(statusLine)) {
- handleAuthorizationFailureResponse(operation, statusLine);
+ throw new InvalidPluginConfigurationException(
+ createErrorMessageForAuthorizationFailureResponse(statusLine));
}
HttpEntity httpResponseEntity = httpResponse.getEntity();
@@ -355,7 +347,7 @@ public class ASConnection {
}
private HttpPost initHttpPost(int timeoutSec, String jsonToSend) {
- HttpPost httpPost = new HttpPost(managementUrl);
+ HttpPost httpPost = new HttpPost(managementUri);
httpPost.addHeader(ACCEPT_HTTP_HEADER, ContentType.APPLICATION_JSON.getMimeType());
HttpParams httpParams = httpClient.getParams();
int timeoutMillis = timeoutSec * 1000;
@@ -373,20 +365,11 @@ public class ASConnection {
|| statusLine.getStatusCode() == HttpStatus.SC_TEMPORARY_REDIRECT;
}
- private void handleAuthorizationFailureResponse(Operation operation, StatusLine statusLine) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Response to " + operation + " was " + statusAsString(statusLine)
- + " - throwing InvalidPluginConfigurationException...");
- }
- // Throw a InvalidPluginConfigurationException, so the user will get a yellow plugin connection
- // warning message in the GUI.
- String message;
+ private String createErrorMessageForAuthorizationFailureResponse(StatusLine statusLine) {
if (statusLine.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
- message = "Credentials for plugin to connect to AS7 management interface are invalid - update Connection Settings with valid credentials.";
- } else {
- message = "Authorization to AS7 failed - did you install a management user?";
+ return "Credentials for plugin to connect to AS7 management interface are invalid - update Connection Settings with valid credentials.";
}
- throw new InvalidPluginConfigurationException(message);
+ return "Authorization to AS7 failed - did you install a management user?";
}
private void logHttpError(Operation operation, StatusLine statusLine, String responseBody) {
@@ -547,20 +530,40 @@ public class ASConnection {
}
}
+ /**
+ * @deprecated as of RHQ 4.10, use {@link #getAsConnectionParams()} instead
+ */
+ @Deprecated
public String getHost() {
- return host;
+ return asConnectionParams.getHost();
}
+ /**
+ * @deprecated as of RHQ 4.10, use {@link #getAsConnectionParams()} instead
+ */
+ @Deprecated
public int getPort() {
- return port;
+ return asConnectionParams.getPort();
}
+ /**
+ * @deprecated as of RHQ 4.10, use {@link #getAsConnectionParams()} instead
+ */
+ @Deprecated
public String getUser() {
- return credentials.getUserName();
+ return asConnectionParams.getUsername();
}
+ /**
+ * @deprecated as of RHQ 4.10, use {@link #getAsConnectionParams()} instead
+ */
+ @Deprecated
public String getPassword() {
- return credentials.getPassword();
+ return asConnectionParams.getPassword();
+ }
+
+ public ASConnectionParams getAsConnectionParams() {
+ return asConnectionParams;
}
static String statusAsString(StatusLine statusLine) {
@@ -613,4 +616,46 @@ public class ASConnection {
return thread;
}
}
+
+ private static class CustomConnectionReuseStrategy extends DefaultConnectionReuseStrategy {
+ private final ASConnection asConnection;
+
+ private CustomConnectionReuseStrategy(ASConnection asConnection) {
+ this.asConnection = asConnection;
+ }
+
+ @Override
+ public boolean keepAlive(HttpResponse response, HttpContext context) {
+ // Do not reuse connection if keep alive timeout has zero or negative value
+ return asConnection.keepAliveTimeout > 0 && super.keepAlive(response, context);
+ }
+ }
+
+ // The default keep-alive strategy does not expire connections if the 'Keep-Alive' header is not present
+ // in the response. This strategy will apply the desired duration in this case.
+ private static class CustomConnectionKeepAliveStrategy extends DefaultConnectionKeepAliveStrategy {
+ private final ASConnection asConnection;
+
+ private CustomConnectionKeepAliveStrategy(ASConnection asConnection) {
+ this.asConnection = asConnection;
+ }
+
+ @Override
+ public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
+ long duration = super.getKeepAliveDuration(response, context);
+ if (duration < 0 || duration > asConnection.keepAliveTimeout) {
+ duration = asConnection.keepAliveTimeout;
+ }
+ if (duration < asConnection.keepAliveTimeout) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn(asConnection.asConnectionParams.getHost() + ":"
+ + asConnection.asConnectionParams.getPort() + " declares a keep alive timeout value of ["
+ + duration + "] ms. Will now use this value instead of the value from configuration ["
+ + asConnection.keepAliveTimeout + "] ms.");
+ }
+ asConnection.keepAliveTimeout = duration;
+ }
+ return duration;
+ }
+ }
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnectionParams.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnectionParams.java
new file mode 100644
index 0000000..0604a1f
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnectionParams.java
@@ -0,0 +1,214 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import org.rhq.modules.plugins.jbossas7.helper.HostnameVerification;
+import org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration;
+import org.rhq.modules.plugins.jbossas7.helper.TrustStrategy;
+
+/**
+ * Groups {@link ASConnection} parameters.
+ *
+ * @author Thomas Segismont
+ */
+public final class ASConnectionParams {
+ /**
+ * By default, expire persistent connection after 5 seconds.
+ */
+ public static final int DEFAULT_KEEPALIVE_TIMEOUT = (int) SECONDS.toMillis(5);
+
+ private final String host;
+ private final int port;
+ private final boolean secure;
+ private final String username;
+ private final String password;
+ private final long keepAliveTimeout;
+ private final TrustStrategy trustStrategy;
+ private final HostnameVerification hostnameVerification;
+ private final String truststoreType;
+ private final String truststore;
+ private final String truststorePassword;
+ private final boolean clientcertAuthentication;
+ private final String keystoreType;
+ private final String keystore;
+ private final String keystorePassword;
+ private final String keyPassword;
+
+ ASConnectionParams(String host, int port, boolean secure, String username, String password, Long keepAliveTimeout,
+ TrustStrategy trustStrategy, HostnameVerification hostnameVerification, String truststoreType,
+ String truststore, String truststorePassword, boolean clientcertAuthentication, String keystoreType,
+ String keystore, String keystorePassword, String keyPassword) {
+ this.host = host;
+ this.port = port;
+ this.secure = secure;
+ this.username = username;
+ this.password = password;
+ this.keyPassword = keyPassword;
+ this.keepAliveTimeout = keepAliveTimeout != null ? keepAliveTimeout : DEFAULT_KEEPALIVE_TIMEOUT;
+ this.trustStrategy = trustStrategy;
+ this.hostnameVerification = hostnameVerification;
+ this.truststoreType = truststoreType;
+ this.truststore = truststore;
+ this.truststorePassword = truststorePassword;
+ this.clientcertAuthentication = clientcertAuthentication;
+ this.keystoreType = keystoreType;
+ this.keystore = keystore;
+ this.keystorePassword = keystorePassword;
+ }
+
+ /**
+ * Creates a new instance from a standalone or host controller resource plugin configuration object.
+ *
+ * @param serverPluginConfig top level server plugin configuration object
+ */
+ public static ASConnectionParams createFrom(ServerPluginConfiguration serverPluginConfig) {
+ return new ASConnectionParamsBuilder() //
+ .setHost(serverPluginConfig.getHostname()) //
+ .setPort(serverPluginConfig.getPort()) //
+ .setSecure(serverPluginConfig.isSecure()) //
+ .setUsername(serverPluginConfig.getUser()) //
+ .setPassword(serverPluginConfig.getPassword()) //
+ .setKeepAliveTimeout(serverPluginConfig.getManagementConnectionTimeout()) //
+ .setTrustStrategy(serverPluginConfig.getTrustStrategy()) //
+ .setHostnameVerification(serverPluginConfig.getHostnameVerification()) //
+ .setTruststoreType(serverPluginConfig.getTruststoreType()) //
+ .setTruststore(serverPluginConfig.getTruststore()) //
+ .setTruststorePassword(serverPluginConfig.getTruststorePassword()) //
+ .setClientcertAuthentication(serverPluginConfig.isClientcertAuthentication()) //
+ .setKeystoreType(serverPluginConfig.getKeystoreType()) //
+ .setKeystore(serverPluginConfig.getKeystore()) //
+ .setKeystorePassword(serverPluginConfig.getKeystorePassword()) //
+ .setKeyPassword(serverPluginConfig.getKeyPassword()).createASConnectionParams();
+ }
+
+ /**
+ * @return the remote host
+ */
+ public String getHost() {
+ return host;
+ }
+
+ /**
+ * @return the remote port
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * @return true if connection should be established over SSL, false otherwise
+ */
+ public boolean isSecure() {
+ return secure;
+ }
+
+ /**
+ * @return the username for authentication challenges
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * @return the password for authentication challenges
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * @return the number of milliseconds the connection can stay idle before being closed
+ */
+ public long getKeepAliveTimeout() {
+ return keepAliveTimeout;
+ }
+
+ /**
+ * @return how to trust server certicates
+ */
+ public TrustStrategy getTrustStrategy() {
+ return trustStrategy;
+ }
+
+ /**
+ * @return how to verify server hostname
+ */
+ public HostnameVerification getHostnameVerification() {
+ return hostnameVerification;
+ }
+
+ /**
+ * @return for example, jks or pkcs12
+ */
+ public String getTruststoreType() {
+ return truststoreType;
+ }
+
+ /**
+ * @return Location of the truststore file
+ */
+ public String getTruststore() {
+ return truststore;
+ }
+
+ /**
+ * @return truststore file password
+ */
+ public String getTruststorePassword() {
+ return truststorePassword;
+ }
+
+ /**
+ * @return truststore file password
+ */
+ public boolean isClientcertAuthentication() {
+ return clientcertAuthentication;
+ }
+
+ /**
+ * @return for example, jks or pkcs12
+ */
+ public String getKeystoreType() {
+ return keystoreType;
+ }
+
+ /**
+ * @return keystore file password
+ */
+ public String getKeystore() {
+ return keystore;
+ }
+
+ /**
+ * @return keystore file password
+ */
+ public String getKeystorePassword() {
+ return keystorePassword;
+ }
+
+ /**
+ * @return key password (securing the entry in the keystore file)
+ */
+ public String getKeyPassword() {
+ return keyPassword;
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnectionParamsBuilder.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnectionParamsBuilder.java
new file mode 100644
index 0000000..e3aa175
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASConnectionParamsBuilder.java
@@ -0,0 +1,131 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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;
+
+import org.rhq.modules.plugins.jbossas7.helper.HostnameVerification;
+import org.rhq.modules.plugins.jbossas7.helper.TrustStrategy;
+
+/**
+ * @author Thomas Segismont
+ */
+public class ASConnectionParamsBuilder {
+ private String host;
+ private int port;
+ private boolean secure;
+ private String username;
+ private String password;
+ private Long keepAliveTimeout;
+ private TrustStrategy trustStrategy;
+ private HostnameVerification hostnameVerification;
+ private String truststoreType;
+ private String truststore;
+ private String truststorePassword;
+ private boolean clientcertAuthentication;
+ private String keystoreType;
+ private String keystore;
+ private String keystorePassword;
+ private String keyPassword;
+
+ public ASConnectionParamsBuilder setHost(String host) {
+ this.host = host;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setPort(int port) {
+ this.port = port;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setSecure(boolean secure) {
+ this.secure = secure;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setUsername(String username) {
+ this.username = username;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setPassword(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setKeepAliveTimeout(Long keepAliveTimeout) {
+ this.keepAliveTimeout = keepAliveTimeout;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setTrustStrategy(TrustStrategy trustStrategy) {
+ this.trustStrategy = trustStrategy;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setHostnameVerification(HostnameVerification hostnameVerification) {
+ this.hostnameVerification = hostnameVerification;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setTruststoreType(String truststoreType) {
+ this.truststoreType = truststoreType;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setTruststore(String truststore) {
+ this.truststore = truststore;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setTruststorePassword(String truststorePassword) {
+ this.truststorePassword = truststorePassword;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setClientcertAuthentication(boolean clientcertAuthentication) {
+ this.clientcertAuthentication = clientcertAuthentication;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setKeystoreType(String keystoreType) {
+ this.keystoreType = keystoreType;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setKeystore(String keystore) {
+ this.keystore = keystore;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setKeystorePassword(String keystorePassword) {
+ this.keystorePassword = keystorePassword;
+ return this;
+ }
+
+ public ASConnectionParamsBuilder setKeyPassword(String keyPassword) {
+ this.keyPassword = keyPassword;
+ return this;
+ }
+
+ public ASConnectionParams createASConnectionParams() {
+ return new ASConnectionParams(host, port, secure, username, password, keepAliveTimeout, trustStrategy,
+ hostnameVerification, truststoreType, truststore, truststorePassword, clientcertAuthentication,
+ keystoreType, keystore, keystorePassword, keyPassword);
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java
index 03e55f7..d836b7c 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ASUploadConnection.java
@@ -19,6 +19,9 @@
package org.rhq.modules.plugins.jbossas7;
+import static org.rhq.modules.plugins.jbossas7.ASConnection.HTTPS_SCHEME;
+import static org.rhq.modules.plugins.jbossas7.ASConnection.HTTP_SCHEME;
+
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
@@ -26,6 +29,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -35,7 +40,9 @@ import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
@@ -46,7 +53,6 @@ import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
-import org.rhq.core.util.StringUtil;
import org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration;
/**
@@ -69,124 +75,135 @@ import org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration;
* @author Thomas Segismont
*/
public class ASUploadConnection {
-
private static final Log LOG = LogFactory.getLog(ASUploadConnection.class);
private static final int SOCKET_CONNECTION_TIMEOUT = 30 * 1000; // 30sec
-
private static final int SOCKET_READ_TIMEOUT = 60 * 1000; // 60sec
-
private static final String TRIGGER_AUTH_URI = ASConnection.MANAGEMENT_URI;
-
private static final String UPLOAD_URI = ASConnection.MANAGEMENT_URI + "/add-content";
-
- private static final int FILE_POST_MAX_LOGGABLE_RESPONSE_LENGTH = 1024 * 2; // 2k max
-
+ private static final int FILE_POST_MAX_LOGGABLE_RESPONSE_LENGTH = 1024 * 2; // 2k max
private static final String EMPTY_JSON_TREE = "{}";
-
private static final String JSON_NODE_FAILURE_DESCRIPTION = "failure-description";
-
private static final String JSON_NODE_FAILURE_DESCRIPTION_VALUE_DEFAULT = "FailureDescription: -input was null-";
-
private static final String JSON_NODE_OUTCOME = "outcome";
-
private static final String JSON_NODE_OUTCOME_VALUE_FAILED = "failed";
-
private static final String SYSTEM_LINE_SEPARATOR = System.getProperty("line.separator");
- private String scheme = ASConnection.HTTP_SCHEME;
-
- private String host;
-
- private int port;
-
- private UsernamePasswordCredentials credentials;
-
- private String fileName;
-
- private int timeout;
-
+ private final ASConnectionParams asConnectionParams;
+ private final int timeout;
+ private final URI triggerAuthUri;
+ private final URI uploadUri;
+ private final UsernamePasswordCredentials credentials;
+ private String filename;
private File cacheFile;
-
private BufferedOutputStream cacheOutputStream;
/**
* @deprecated as of 4.6. This class is not reusable so there is no reason not to provide the filename to the
- * constructor. Use {@link #ASUploadConnection(String, int, String, String, String)} instead.
+ * constructor. Use {@link #ASUploadConnection(ASConnectionParams, String)} instead.
*/
@Deprecated
public ASUploadConnection(String host, int port, String user, String password) {
- this(host, port, user, password, null);
+ this(new ASConnectionParamsBuilder() //
+ .setHost(host) //
+ .setPort(port) //
+ .setUsername(user) //
+ .setPassword(password) //
+ .createASConnectionParams(), null);
}
/**
- * Creates a new {@link ASUploadConnection} for a remote http management interface.
- *
- * If null user or password is given, this instance will not be able to reply to an authentication challenge.
- *
- * It's the responsibility of the caller to make sure either {@link #finishUpload()} or {@link #cancelUpload()}
- * will be called to free resources this class helds.
- *
- * @param host - hostname of the remote http management interface
- * @param port - port of the remote http management interface
- * @param user - username to logon with to the remote http management interface.
- * @param password - password to logon with to the remote http management interface
- * @param fileName - fileName of the content (to provide in multipart post request)
+ * @deprecated as of RHQ 4.10. Use {@link #ASUploadConnection(ASConnectionParams, String)} instead.
*/
+ @Deprecated
public ASUploadConnection(String host, int port, String user, String password, String fileName) {
- if (host == null) {
- throw new IllegalArgumentException("Management host cannot be null.");
- }
- if (port <= 0 || port > 65535) {
- throw new IllegalArgumentException("Invalid port: " + port);
- }
- if (StringUtil.isBlank(fileName)) {
- throw new IllegalArgumentException("Filename cannot be blank");
- }
- this.host = host;
- this.port = port;
- if (user != null && password != null) {
- credentials = new UsernamePasswordCredentials(user, password);
- }
- this.fileName = fileName;
- this.timeout = SOCKET_READ_TIMEOUT;
+ this(new ASConnectionParamsBuilder() //
+ .setHost(host) //
+ .setPort(port) //
+ .setUsername(user) //
+ .setPassword(password) //
+ .createASConnectionParams(), fileName);
}
/**
* @deprecated as of 4.6. This class is not reusable so there is no reason not to provide the filename to the
- * constructor. Use {@link #ASUploadConnection(ASConnection, String) instead.
+ * constructor. Use {@link #ASUploadConnection(ASConnection, String)} instead.
*/
@Deprecated
public ASUploadConnection(ASConnection asConnection) {
- this(asConnection.getHost(), asConnection.getPort(), asConnection.getUser(), asConnection.getPassword(), null);
+ this(asConnection.getAsConnectionParams(), null);
}
/**
- * Creates a new {@link ASUploadConnection} from an existing {@link ASConnection}.
- *
- * This constructor has the same requirements as {@link #ASUploadConnection(String, int, String, String, String)}
- * which it uses internally.
- *
- * @param asConnection - existing {@link ASConnection} instance
- * @param fileName - fileName of the content (to provide in multipart post request)
+ * @param asConnection the object which will provide the {@link ASConnectionParams}
+ * @param fileName
+ * @see #ASUploadConnection(ASConnectionParams, String)
*/
public ASUploadConnection(ASConnection asConnection, String fileName) {
- this(asConnection.getHost(), asConnection.getPort(), asConnection.getUser(), asConnection.getPassword(),
- fileName);
+ this(asConnection.getAsConnectionParams(), fileName);
}
/**
- * This factory method simplifies creation of a new {@link ASUploadConnection} instance given the caller has
- * access to the {@link ServerPluginConfiguration}.
- *
- * @param pluginConfig - the {@link ServerPluginConfiguration}
- * @param fileName - fileName of the content (to provide in multipart post request)
- * @return
+ * Creates a new {@link ASUploadConnection} for a remote http management interface.
+ *
+ * It's the responsibility of the caller to make sure either {@link #finishUpload()} or {@link #cancelUpload()}
+ * will be called to free resources this class helds.
+ *
+ * @param params
+ */
+ public ASUploadConnection(ASConnectionParams params, String filename) {
+ asConnectionParams = params;
+ if (asConnectionParams.getHost() == null) {
+ throw new IllegalArgumentException("Management host cannot be null.");
+ }
+ if (asConnectionParams.getPort() <= 0 || asConnectionParams.getPort() > 65535) {
+ throw new IllegalArgumentException("Invalid port: " + asConnectionParams.getPort());
+ }
+ this.filename = filename;
+ timeout = SOCKET_READ_TIMEOUT;
+ triggerAuthUri = buildTriggerAuthUri();
+ uploadUri = buildUploadUri();
+ if (asConnectionParams.getUsername() != null && asConnectionParams.getPassword() != null) {
+ credentials = new UsernamePasswordCredentials(asConnectionParams.getUsername(),
+ asConnectionParams.getPassword());
+ } else {
+ credentials = null;
+ }
+ }
+
+ private URI buildTriggerAuthUri() {
+ try {
+ return new URIBuilder() //
+ .setScheme(asConnectionParams.isSecure() ? HTTPS_SCHEME : HTTP_SCHEME) //
+ .setHost(asConnectionParams.getHost()) //
+ .setPort(asConnectionParams.getPort()) //
+ .setPath(TRIGGER_AUTH_URI) //
+ .build();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Could not build auth trigger URI: " + e.getMessage(), e);
+ }
+ }
+
+ private URI buildUploadUri() {
+ try {
+ return new URIBuilder() //
+ .setScheme(asConnectionParams.isSecure() ? HTTPS_SCHEME : HTTP_SCHEME) //
+ .setHost(asConnectionParams.getHost()) //
+ .setPort(asConnectionParams.getPort()) //
+ .setPath(UPLOAD_URI) //
+ .build();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Could not build upload URI: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * @deprecated as of RHQ 4.10. Use {@link #ASUploadConnection(ASConnectionParams, String)} instead.
*/
+ @Deprecated
public static ASUploadConnection newInstanceForServerPluginConfiguration(ServerPluginConfiguration pluginConfig,
String fileName) {
- return new ASUploadConnection(pluginConfig.getHostname(), pluginConfig.getPort(), pluginConfig.getUser(),
- pluginConfig.getPassword(), fileName);
+ return new ASUploadConnection(ASConnectionParams.createFrom(pluginConfig), fileName);
}
/**
@@ -196,7 +213,7 @@ public class ASUploadConnection {
*/
@Deprecated
public OutputStream getOutputStream(String fileName) {
- this.fileName = fileName;
+ filename = fileName;
return getOutputStream();
}
@@ -212,7 +229,7 @@ public class ASUploadConnection {
cacheOutputStream = new BufferedOutputStream(new FileOutputStream(cacheFile));
return cacheOutputStream;
} catch (IOException e) {
- LOG.error("Could not create outputstream for " + fileName, e);
+ LOG.error("Could not create outputstream for " + filename, e);
}
return null;
}
@@ -234,57 +251,60 @@ public class ASUploadConnection {
* @return a {@link JsonNode} instance read from the upload response body or null if something went wrong.
*/
public JsonNode finishUpload() {
-
- if (fileName == null) {
+ if (filename == null) {
// At this point the fileName should have been set whether at instanciation or in #getOutputStream(String)
throw new IllegalStateException("Upload fileName is null");
}
closeQuietly(cacheOutputStream);
- // We will first send a simple get request in order to trigger authentication challenge.
- // This allows to send the potentially big file only once to the server
- // The typical resulting http exchange would be:
- //
- // GET without auth <- 401 (start auth challenge : the server will name the realm and the scheme)
- // GET with auth <- 200
- // POST big file
- //
- // Note this only works because we use SimpleHttpConnectionManager which maintains
- // only one HttpConnection
- //
- // A better way to avoid uploading a big file multiple times would be to use header Expect: Continue
- // Unfortunately AS7 responds 100 Continue even if the authentication headers are not yet present
-
- ClientConnectionManager httpConnectionManager = new BasicClientConnectionManager();
+ SchemeRegistry schemeRegistry = new SchemeRegistryBuilder(asConnectionParams).buildSchemeRegistry();
+ ClientConnectionManager httpConnectionManager = new BasicClientConnectionManager(schemeRegistry);
DefaultHttpClient httpClient = new DefaultHttpClient(httpConnectionManager);
HttpParams httpParams = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, SOCKET_CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParams, timeout);
- if (credentials != null) {
- httpClient.getCredentialsProvider().setCredentials(new AuthScope(host, port), credentials);
- }
- String triggerAuthUrl = scheme + "://" + host + ":" + port + TRIGGER_AUTH_URI;
- HttpGet triggerAuthRequest = new HttpGet(triggerAuthUrl);
- try {
- // Send GET request in order to trigger authentication
- // We don't check response code because we're not already uploading the file
- httpClient.execute(triggerAuthRequest);
- } catch (Exception ignore) {
- // We don't stop trying upload if triggerAuthRequest raises exception
- // See comment above
- } finally {
- triggerAuthRequest.abort();
+ if (credentials != null && !asConnectionParams.isClientcertAuthentication()) {
+ httpClient.getCredentialsProvider().setCredentials(
+ new AuthScope(asConnectionParams.getHost(), asConnectionParams.getPort()), credentials);
+
+ // If credentials were provided, we will first send a GET request to trigger the authentication challenge
+ // This allows to send the potentially big file only once to the server
+ // The typical resulting http exchange would be:
+ //
+ // GET without auth <- 401 (start auth challenge : the server will name the realm and the scheme)
+ // GET with auth <- 200
+ // POST big file
+ //
+ // Note this only works because we use SimpleHttpConnectionManager which maintains only one HttpConnection
+ //
+ // A better way to avoid uploading a big file twice would be to use the header "Expect: Continue"
+ // Unfortunately AS7 replies "100 Continue" even if authentication headers are not present yet
+ //
+ // There is no need to trigger digest authentication when client certification authentication is used
+
+ HttpGet triggerAuthRequest = new HttpGet(triggerAuthUri);
+ try {
+ // Send GET request in order to trigger authentication
+ // We don't check response code because we're not already uploading the file
+ httpClient.execute(triggerAuthRequest);
+ } catch (Exception ignore) {
+ // We don't stop trying upload if triggerAuthRequest raises exception
+ // See comment above
+ } finally {
+ triggerAuthRequest.abort();
+ }
}
- String uploadURL = scheme + "://" + host + ":" + port + UPLOAD_URI;
- HttpPost uploadRequest = new HttpPost(uploadURL);
+ String uploadURL = (asConnectionParams.isSecure() ? HTTPS_SCHEME : HTTP_SCHEME) + "://"
+ + asConnectionParams.getHost() + ":" + asConnectionParams.getPort() + UPLOAD_URI;
+ HttpPost uploadRequest = new HttpPost(uploadUri);
try {
// Now upload file with multipart POST request
MultipartEntity multipartEntity = new MultipartEntity();
- multipartEntity.addPart(fileName, new FileBody(cacheFile));
+ multipartEntity.addPart(filename, new FileBody(cacheFile));
uploadRequest.setEntity(multipartEntity);
HttpResponse uploadResponse = httpClient.execute(uploadRequest);
if (uploadResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
@@ -356,12 +376,6 @@ public class ASUploadConnection {
return false;
}
- private boolean credentialsProvided() {
- // If null user or password is given to the constructor
- // no credentials instance is created
- return credentials != null;
- }
-
private void logUploadDoesNotEndWithHttpOkStatus(HttpResponse uploadResponse) {
StringBuilder logMessageBuilder = new StringBuilder("File upload failed: ").append(ASConnection
.statusAsString(uploadResponse.getStatusLine()));
@@ -397,7 +411,9 @@ public class ASUploadConnection {
/**
* Get the currently active upload timeout
* @return timeout in seconds
+ * @deprecated there is no reason to expose this attribute
*/
+ @Deprecated
public int getTimeout() {
return timeout;
}
@@ -405,9 +421,9 @@ public class ASUploadConnection {
/**
* Set upload timeout in seconds.
* @param timeout upload timeout in seconds
+ * @deprecated there is no reason to expose this attribute
*/
+ @Deprecated
public void setTimeout(int timeout) {
- this.timeout = timeout;
}
-
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index bda2e5e..af505dc 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -451,8 +451,8 @@ public class BaseComponent<T extends ResourceComponent<?>> implements AS7Compone
ContentServices contentServices = cctx.getContentServices();
String resourceTypeName = report.getResourceType().getName();
- ASUploadConnection uploadConnection = ASUploadConnection.newInstanceForServerPluginConfiguration(
- getServerComponent().getServerPluginConfiguration(), details.getKey().getName());
+ ASUploadConnection uploadConnection = new ASUploadConnection(getServerComponent().getASConnection(), details
+ .getKey().getName());
OutputStream out = uploadConnection.getOutputStream();
if (out == null) {
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 25063ac..0f1254d 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
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -76,6 +76,7 @@ import org.rhq.modules.plugins.jbossas7.json.Result;
* "JBossAS7 Standalone Server".
*/
public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent, ManualAddFacet, ResourceUpgradeFacet {
+ private static final Log LOG = LogFactory.getLog(BaseProcessDiscovery.class);
private static final String JBOSS_AS_PREFIX = "jboss-as-";
private static final String JBOSS_EAP_PREFIX = "jboss-eap-";
@@ -137,8 +138,6 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
START_SCRIPT_OPTION_EXCLUDES.add(new CommandLineOption("Djboss.home.dir", null));
}
- private final Log log = LogFactory.getLog(this.getClass());
-
// Auto-discover running AS7 instances.
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext discoveryContext) throws Exception {
Set<DiscoveredResourceDetails> discoveredResources = new HashSet<DiscoveredResourceDetails>();
@@ -150,15 +149,17 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
AS7CommandLine commandLine = new AS7CommandLine(process);
DiscoveredResourceDetails details = buildResourceDetails(discoveryContext, process, commandLine);
discoveredResources.add(details);
- log.debug("Discovered new " + discoveryContext.getResourceType().getName() + " Resource (key=["
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Discovered new " + discoveryContext.getResourceType().getName() + " Resource (key=["
+ details.getResourceKey() + "], name=[" + details.getResourceName() + "], version=["
+ details.getResourceVersion() + "]).");
+ }
} catch (RuntimeException e) {
// Only barf a stack trace for runtime exceptions.
- log.error("Discovery of a " + discoveryContext.getResourceType().getName()
+ LOG.error("Discovery of a " + discoveryContext.getResourceType().getName()
+ " Resource failed for " + processScanResult.getProcessInfo() + ".", e);
} catch (Exception e) {
- log.error("Discovery of a " + discoveryContext.getResourceType().getName()
+ LOG.error("Discovery of a " + discoveryContext.getResourceType().getName()
+ " Resource failed for " + processScanResult.getProcessInfo() + " - cause: " + e);
}
}
@@ -204,6 +205,7 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
HostPort managementHostPort = hostConfig.getManagementHostPort(commandLine, getMode());
serverPluginConfig.setHostname(managementHostPort.host);
serverPluginConfig.setPort(managementHostPort.port);
+ serverPluginConfig.setSecure(managementHostPort.isSecure);
pluginConfig.setSimpleValue("realm", hostConfig.getManagementSecurityRealm());
String apiVersion = hostConfig.getDomainApiVersion();
JBossProductType productType = JBossProductType.determineJBossProductType(homeDir, apiVersion);
@@ -264,7 +266,7 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
File homeDir = new File(pluginConfig.getSimpleValue("homeDir"));
File startScriptAbsolute = new File(homeDir, startScript.getPath());
if (!startScriptAbsolute.exists()) {
- log.warn("Failed to find start script file for AS7 server with command line [" + commandLine
+ LOG.warn("Failed to find start script file for AS7 server with command line [" + commandLine
+ "] - defaulting 'startScripFile' plugin config prop to [" + startScript + "].");
}
}
@@ -438,13 +440,12 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
String hostname = serverPluginConfig.getHostname();
Integer port = serverPluginConfig.getPort();
String user = serverPluginConfig.getUser();
- String pass = serverPluginConfig.getPassword();
if (hostname == null || port == null) {
throw new InvalidPluginConfigurationException("Hostname and port must both be set.");
}
- ProductInfo productInfo = new ProductInfo(hostname, user, pass, port).getFromRemote();
+ ProductInfo productInfo = new ProductInfo(ASConnectionParams.createFrom(serverPluginConfig)).getFromRemote();
JBossProductType productType = productInfo.getProductType();
if (productType==null) {
@@ -491,7 +492,7 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
report.setNewResourceKey(createKeyForRemoteResource(currentResourceKey));
} else {
upgraded = FALSE;
- log.warn("Unknown format, cannot upgrade resource key [" + currentResourceKey + "]");
+ LOG.warn("Unknown format, cannot upgrade resource key [" + currentResourceKey + "]");
}
}
@@ -535,14 +536,14 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
Properties props = new Properties();
if (!mgmUsersPropsFile.exists()) {
- if (log.isDebugEnabled()) {
- log.debug("Management user properties file not found at [" + mgmUsersPropsFile + "].");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Management user properties file not found at [" + mgmUsersPropsFile + "].");
}
return props;
}
if (!mgmUsersPropsFile.canRead()) {
- log.warn("Management user properties at [" + mgmUsersPropsFile + "] is not readable.");
+ LOG.warn("Management user properties at [" + mgmUsersPropsFile + "] is not readable.");
return props;
}
@@ -550,20 +551,22 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
try {
inputStream = new FileInputStream(mgmUsersPropsFile);
} catch (FileNotFoundException e) {
- log.debug("Management user properties file not found at [" + mgmUsersPropsFile + "].");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Management user properties file not found at [" + mgmUsersPropsFile + "].");
+ }
return props;
}
try {
props.load(inputStream);
} catch (IOException e) {
- log.error("Failed to parse management users properties file at [" + mgmUsersPropsFile + "]: "
+ LOG.error("Failed to parse management users properties file at [" + mgmUsersPropsFile + "]: "
+ e.getMessage());
} finally {
try {
inputStream.close();
} catch (IOException e) {
- log.error("Failed to close management users properties file at [" + mgmUsersPropsFile + "]: "
+ LOG.error("Failed to close management users properties file at [" + mgmUsersPropsFile + "]: "
+ e.getMessage());
}
}
@@ -584,7 +587,7 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
is.close();
}
} catch (Exception e) {
- log.error(e.getMessage());
+ LOG.error(e.getMessage());
}
if (hostName == null)
hostName = "local"; // Fallback to the installation default
@@ -649,8 +652,8 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
.toString();
}
} catch (IOException e) {
- if (log.isDebugEnabled()) {
- log.debug("Could not read file " + file.getAbsolutePath(), e);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not read file " + file.getAbsolutePath(), e);
}
}
return null;
@@ -674,22 +677,15 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
}
private class ProductInfo {
- private String hostname;
- private String user;
- private String pass;
- private int port;
+ private ASConnectionParams asConnectionParams;
private String productVersion;
private JBossProductType productType;
private String releaseVersion;
private String releaseCodeName;
private boolean fromRemote = false;
- private String serverName;
- public ProductInfo(String hostname, String user, String pass, int port) {
- this.hostname = hostname;
- this.user = user;
- this.pass = pass;
- this.port = port;
+ public ProductInfo(ASConnectionParams asConnectionParams) {
+ this.asConnectionParams = asConnectionParams;
}
public String getProductVersion() {
@@ -701,7 +697,7 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
}
public ProductInfo getFromRemote() {
- ASConnection connection = new ASConnection(hostname, port, user, pass);
+ ASConnection connection = new ASConnection(asConnectionParams);
try {
String productName = getServerAttribute(connection, "product-name");
if ((productName != null) && !productName.isEmpty())
@@ -717,15 +713,16 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
}
releaseVersion = getServerAttribute(connection, "release-version");
releaseCodeName = getServerAttribute(connection, "release-codename");
- serverName = getServerAttribute(connection, "name");
productVersion = getServerAttribute(connection, "product-version");
if (productVersion == null) {
productVersion = releaseVersion;
}
fromRemote = true;
} catch (InvalidPluginConfigurationException e) {
- log.debug("Could not get the product info from [" + hostname + ":" + port
- + "] - probably a connection failure");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Could not get the product info from [" + asConnectionParams.getHost() + ":"
+ + asConnectionParams.getPort() + "] - probably a connection failure");
+ }
} finally {
connection.shutdown();
}
@@ -734,10 +731,10 @@ public abstract class BaseProcessDiscovery implements ResourceDiscoveryComponent
@Override
public String toString() {
- return "ProductInfo{" + "hostname='" + hostname + '\'' + ", port=" + port + ", productVersion='"
- + productVersion + '\'' + ", productType='" + productType + '\'' + ", releaseVersion='"
- + releaseVersion + '\'' + ", releaseCodeName='" + releaseCodeName + '\'' + ", fromRemote=" + fromRemote
- + '}';
+ return "ProductInfo{" + "hostname='" + asConnectionParams.getHost() + '\'' + ", port="
+ + asConnectionParams.getPort() + ", productVersion='" + productVersion + '\'' + ", productType='"
+ + productType + '\'' + ", releaseVersion='" + releaseVersion + '\'' + ", releaseCodeName='"
+ + releaseCodeName + '\'' + ", fromRemote=" + fromRemote + '}';
}
}
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 7654c62..f0d13c2 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
@@ -90,11 +90,9 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend
@Override
public void start(ResourceContext<T> resourceContext) throws InvalidPluginConfigurationException, Exception {
super.start(resourceContext);
-
serverPluginConfig = new ServerPluginConfiguration(pluginConfiguration);
- connection = ASConnection.newInstanceForServerPluginConfiguration(serverPluginConfig);
- // The availabilityCollector is still null at this point. So this call will always perform a real availability
- // check and throw InvalidPluginConfigurationException as needed.
+ serverPluginConfig.validate();
+ connection = new ASConnection(ASConnectionParams.createFrom(serverPluginConfig));
getAvailability();
logFileEventDelegate = new LogFileEventResourceComponentHelper(context);
logFileEventDelegate.startLogFileEventPollers();
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DeploymentComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DeploymentComponent.java
index 94c101f..c253bb8 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DeploymentComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/DeploymentComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -154,8 +154,8 @@ public class DeploymentComponent extends BaseComponent<ResourceComponent<?>> imp
ResourcePackageDetails detail = packages.iterator().next();
- ASUploadConnection uploadConnection = ASUploadConnection.newInstanceForServerPluginConfiguration(
- getServerComponent().getServerPluginConfiguration(), detail.getKey().getName());
+ ASUploadConnection uploadConnection = new ASUploadConnection(getServerComponent().getASConnection(), detail
+ .getKey().getName());
OutputStream out = uploadConnection.getOutputStream();
if (out == null) {
response.setOverallRequestResult(ContentResponseResult.FAILURE);
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 633997b..e903f89 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-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -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 java.util.ArrayList;
@@ -110,7 +111,13 @@ public class Domain2Descriptor {
}
//create connection
- ASConnection conn = new ASConnection("localhost", 9990, user, pass);
+ ASConnectionParams asConnectionParams = new ASConnectionParamsBuilder() //
+ .setHost("localhost") //
+ .setPort(9990) //
+ .setUsername(user) //
+ .setPassword(pass)//
+ .createASConnectionParams();
+ ASConnection conn = new ASConnection(asConnectionParams);
try {
Address address = new Address(path);
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SchemeRegistryBuilder.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SchemeRegistryBuilder.java
new file mode 100644
index 0000000..12c04ac
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/SchemeRegistryBuilder.java
@@ -0,0 +1,142 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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;
+
+import static org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
+import static org.apache.http.conn.ssl.SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
+import static org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER;
+import static org.rhq.modules.plugins.jbossas7.ASConnection.HTTPS_SCHEME;
+import static org.rhq.modules.plugins.jbossas7.ASConnection.HTTP_SCHEME;
+
+import java.io.FileInputStream;
+import java.security.KeyStore;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+
+/**
+ * Helper class which creates Apache HTTP Client 4.x {@link SchemeRegistry} instances.
+ *
+ * @author Thomas Segismont
+ */
+class SchemeRegistryBuilder {
+ private static final TrustSelfSignedStrategy TRUST_SELF_SIGNED_STRATEGY = new TrustSelfSignedStrategy();
+ private static final TrustAnyStrategy TRUST_ANY_STRATEGY = new TrustAnyStrategy();
+
+ private final ASConnectionParams asConnectionParams;
+
+ public SchemeRegistryBuilder(ASConnectionParams asConnectionParams) {
+ this.asConnectionParams = asConnectionParams;
+ }
+
+ public SchemeRegistry buildSchemeRegistry() {
+ SchemeRegistry schemeRegistry = new SchemeRegistry();
+ if (asConnectionParams.isSecure()) {
+ SSLSocketFactory sslSocketFactory;
+ try {
+ KeyStore truststore = null;
+ if (asConnectionParams.getTruststore() != null) {
+ truststore = loadKeystore(asConnectionParams.getTruststoreType(),
+ asConnectionParams.getTruststore(), asConnectionParams.getTruststorePassword());
+ }
+ KeyStore keystore = null;
+ String keyPassword = null;
+ if (asConnectionParams.isClientcertAuthentication()) {
+ if (asConnectionParams.getKeystore() == null) {
+ keystore = loadKeystore( //
+ System.getProperty("javax.net.ssl.keyStoreType", KeyStore.getDefaultType()), //
+ System.getProperty("javax.net.ssl.keyStore"), //
+ System.getProperty("javax.net.ssl.keyStorePassword") //
+ );
+ } else {
+ keystore = loadKeystore( //
+ asConnectionParams.getKeystoreType(), //
+ asConnectionParams.getKeystore(), //
+ asConnectionParams.getKeystorePassword() //
+ );
+ keyPassword = asConnectionParams.getKeyPassword();
+ }
+ }
+ sslSocketFactory = new SSLSocketFactory(null, keystore, keyPassword, truststore, null,
+ getTrustStrategy(), getHostnameVerifier());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ schemeRegistry.register(new Scheme(HTTPS_SCHEME, asConnectionParams.getPort(), sslSocketFactory));
+ } else {
+ schemeRegistry.register(new Scheme(HTTP_SCHEME, asConnectionParams.getPort(), PlainSocketFactory
+ .getSocketFactory()));
+ }
+ return schemeRegistry;
+ }
+
+ private KeyStore loadKeystore(String keystoreType, String keystore, String keystorePassword) throws Exception {
+ KeyStore ks = KeyStore.getInstance(keystoreType);
+ char[] password = keystorePassword.toCharArray();
+ FileInputStream fileInputStream = null;
+ try {
+ fileInputStream = new FileInputStream(keystore);
+ ks.load(fileInputStream, password);
+ return ks;
+ } finally {
+ if (fileInputStream != null) {
+ fileInputStream.close();
+ }
+ }
+ }
+
+ private TrustStrategy getTrustStrategy() {
+ switch (asConnectionParams.getTrustStrategy()) {
+ case TRUST_SELFSIGNED:
+ return TRUST_SELF_SIGNED_STRATEGY;
+ case TRUST_ANY:
+ return TRUST_ANY_STRATEGY;
+ case STANDARD:
+ return null;
+ }
+ throw new UnsupportedOperationException(asConnectionParams.getTrustStrategy().name);
+ }
+
+ private X509HostnameVerifier getHostnameVerifier() {
+ switch (asConnectionParams.getHostnameVerification()) {
+ case STRICT:
+ return STRICT_HOSTNAME_VERIFIER;
+ case BROWSER_COMPATIBLE:
+ return BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
+ case SKIP:
+ return ALLOW_ALL_HOSTNAME_VERIFIER;
+ }
+ throw new UnsupportedOperationException(asConnectionParams.getHostnameVerification().name);
+ }
+
+ private static class TrustAnyStrategy implements TrustStrategy {
+ @Override
+ public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ return true;
+ }
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
index bbf57f9..defdf65 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/ServerGroupComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -93,8 +93,8 @@ public class ServerGroupComponent extends BaseComponent implements ContentFacet,
String packageName = details.getName();
- ASUploadConnection uploadConnection = ASUploadConnection.newInstanceForServerPluginConfiguration(
- getServerComponent().getServerPluginConfiguration(), packageName);
+ ASUploadConnection uploadConnection = new ASUploadConnection(getServerComponent().getASConnection(),
+ packageName);
OutputStream out = uploadConnection.getOutputStream();
if (out == null) {
response.addPackageResponse(new DeployIndividualPackageResponse(details.getKey(),
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java
index 3c71135..df36e11 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostConfiguration.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -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.helper;
import static org.rhq.core.util.StringUtil.EMPTY_STRING;
@@ -37,6 +38,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import org.rhq.core.pluginapi.util.CommandLineOption;
import org.rhq.modules.plugins.jbossas7.AS7CommandLine;
@@ -85,68 +87,109 @@ public class HostConfiguration {
/**
* Try to obtain the management IP and port from the already parsed host.xml or standalone.xml
*
- *
* @param commandLine Command line arguments of the process to
*
* @return an Object containing host and port
*/
public HostPort getManagementHostPort(AS7CommandLine commandLine, AS7Mode mode) {
+ // There are three ways to configure the http(s) management endpoint
+ //
+ // 1. Standalone servers favored style (socket-binding style)
+ // The socket-binding node attribute is *either* 'https' *or* 'http'
+ // <management>
+ // <management-interfaces>
+ // <http-interface security-realm="ManagementRealm">
+ // <socket-binding https="management-https"/>
+ // </http-interface>
+ // </management-interfaces>
+ // </management>
+ //
+ // 2. Host controllers style, unfavored standalone servers style (socket style)
+ // <management>
+ // <management-interfaces>
+ // <http-interface security-realm="ManagementRealm">
+ // <socket interface="management" port="9990" secure-port="9443"/>
+ // </http-interface>
+ // </management-interfaces>
+ // </management>
+ //
+ //
+ // 3. Very old and deprecated style (early as7 style)
+ // <management>
+ // <management-interfaces>
+ // <http-interface security-realm="ManagementRealm" interface="management" port="9990" secure-port="9443"/>
+ // </management-interfaces>
+ // </management>
+
String portString;
String interfaceExpression;
-
String socketBindingName;
-
- socketBindingName = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/socket-binding/@http");
- String socketInterface = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/socket/@interface");
String portOffsetRaw = null;
+ boolean isSecure = false;
+
+ if (findMatchingElements("//management/management-interfaces/http-interface/socket-binding").getLength() != 0) {
+ // This is case 1
+ socketBindingName = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/socket-binding/@https");
+ if (!socketBindingName.isEmpty()) {
+ isSecure = true;
+ } else {
+ socketBindingName = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/socket-binding/@http");
+ }
+ portString = obtainXmlPropertyViaXPath("/server/socket-binding-group/socket-binding[@name='"
+ + socketBindingName + "']/@port");
+ String interfaceName = obtainXmlPropertyViaXPath("/server/socket-binding-group/socket-binding[@name='"
+ + socketBindingName + "']/@interface");
+ String xpathExpression = "/server/socket-binding-group/@port-offset";
+ portOffsetRaw = obtainXmlPropertyViaXPath(xpathExpression);
- if (!socketInterface.isEmpty()) {
- interfaceExpression = obtainXmlPropertyViaXPath("//interfaces/interface[@name='" + socketInterface
+ interfaceExpression = obtainXmlPropertyViaXPath("/server/interfaces/interface[@name='" + interfaceName
+ "']/inet-address/@value");
if (interfaceExpression.isEmpty()) {
- interfaceExpression = obtainXmlPropertyViaXPath("//interfaces/interface[@name='" + socketInterface
- + "']/loopback-address/@value");
+ interfaceExpression = obtainXmlPropertyViaXPath("/server/interfaces/interface[@name='" + interfaceName
+ + "']/loopback-address/@value");
}
- portString = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/socket/@port");
- } else if (socketBindingName.isEmpty()) {
- // old AS7.0, early 7.1 style
- portString = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/@port");
- String interfaceName = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/@interface");
- interfaceExpression = obtainXmlPropertyViaXPath("/server/interfaces/interface[@name='" + interfaceName
+ } else if (findMatchingElements("//management/management-interfaces/http-interface/socket").getLength() != 0) {
+ // This is case 2
+ String socketInterface = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/socket/@interface");
+ interfaceExpression = obtainXmlPropertyViaXPath("//interfaces/interface[@name='" + socketInterface
+ "']/inet-address/@value");
if (interfaceExpression.isEmpty()) {
- interfaceExpression = obtainXmlPropertyViaXPath("/server/interfaces/interface[@name='" + interfaceName
- + "']/loopback-address/@value");
+ interfaceExpression = obtainXmlPropertyViaXPath("//interfaces/interface[@name='" + socketInterface
+ + "']/loopback-address/@value");
+ }
+ portString = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/socket/@secure-port");
+ if (!portString.isEmpty()) {
+ isSecure = true;
+ } else {
+ portString = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/socket/@port");
}
} else {
- // later AS7.1 and EAP6 standalone.xml
- portString = obtainXmlPropertyViaXPath("/server/socket-binding-group/socket-binding[@name='"
- + socketBindingName + "']/@port");
- String interfaceName = obtainXmlPropertyViaXPath("/server/socket-binding-group/socket-binding[@name='"
- + socketBindingName + "']/@interface");
- String socketBindingGroupName = "standard-sockets";
- // /server/socket-binding-group[@name='standard-sockets']/@port-offset
- String xpathExpression =
- "/server/socket-binding-group[@name='" + socketBindingGroupName + "']/@port-offset";
- portOffsetRaw = obtainXmlPropertyViaXPath(xpathExpression);
-
- // TODO the next may also be expressed differently
+ // This is case 3
+ portString = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/@secure-port");
+ if (!portString.isEmpty()) {
+ isSecure = true;
+ } else {
+ portString = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/@port");
+ }
+ String interfaceName = obtainXmlPropertyViaXPath("//management/management-interfaces/http-interface/@interface");
interfaceExpression = obtainXmlPropertyViaXPath("/server/interfaces/interface[@name='" + interfaceName
- + "']/inet-address/@value");
+ + "']/inet-address/@value");
if (interfaceExpression.isEmpty()) {
interfaceExpression = obtainXmlPropertyViaXPath("/server/interfaces/interface[@name='" + interfaceName
- + "']/loopback-address/@value");
+ + "']/loopback-address/@value");
}
}
+
HostPort hp = new HostPort();
+ hp.isSecure = isSecure;
- if (!interfaceExpression.isEmpty())
+ if (!interfaceExpression.isEmpty()) {
hp.host = replaceDollarExpression(interfaceExpression, commandLine, "localhost");
- else
+ } else {
hp.host = "localhost"; // Fallback
+ }
hp.port = 0;
-
if (portString != null && !portString.isEmpty()) {
String tmp = replaceDollarExpression(portString, commandLine, String.valueOf(DEFAULT_MGMT_PORT));
hp.port = Integer.valueOf(tmp);
@@ -157,12 +200,8 @@ public class HostConfiguration {
Integer portOffset = Integer.valueOf(portOffsetString);
hp.port += portOffset;
hp.withOffset = true;
- }
-
- // TODO (ips): We shouldn't need the below code if the above code that reads the port offset from the config
- // file is working correctly.
- if (!hp.withOffset && (mode == AS7Mode.STANDALONE)) {
- // Only standalone applies the port offset to the management ports.
+ } else if (mode == AS7Mode.STANDALONE) {
+ // On standalone servers, offset may also be set with a system property
String value = commandLine.getSystemProperties().get(SOCKET_BINDING_PORT_OFFSET_SYSPROP);
if (value != null) {
int offset = Integer.valueOf(value);
@@ -173,6 +212,15 @@ public class HostConfiguration {
return hp;
}
+ private NodeList findMatchingElements(String expression) {
+ try {
+ XPathExpression xPathExpression = xpathFactory.newXPath().compile(expression);
+ return (NodeList) xPathExpression.evaluate(document, XPathConstants.NODESET);
+ } catch (XPathExpressionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/**
* Try to determine the host name - that is the name of a standalone server or a
* host in domain mode by looking at the standalone.xml/host.xml files
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostPort.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostPort.java
index f85d5c0..bdd4d63 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostPort.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostPort.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2005-2014 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.helper;
/**
@@ -25,6 +26,7 @@ public class HostPort {
public String host;
public int port;
+ public boolean isSecure = false;
public boolean isLocal = true;
public boolean withOffset = false;
@@ -41,7 +43,8 @@ public class HostPort {
@Override
public String toString() {
- return "HostPort{" + "host='" + host + '\'' + ", port=" + port + ", isLocal=" + isLocal + '}';
+ return "HostPort[" + "host='" + host + '\'' + ", port=" + port + ", isSecure=" + isSecure + ", isLocal="
+ + isLocal + ", withOffset=" + withOffset + ']';
}
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostnameVerification.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostnameVerification.java
new file mode 100644
index 0000000..8eb4c84
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/HostnameVerification.java
@@ -0,0 +1,45 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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.helper;
+
+/**
+* @author Thomas Segismont
+*/
+public enum HostnameVerification {
+ STRICT("strict"), BROWSER_COMPATIBLE("browserCompatible"), SKIP("skip");
+
+ public final String name;
+
+ HostnameVerification(String name) {
+ this.name = name;
+ }
+
+ public static HostnameVerification findByName(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("name is null");
+ }
+ for (HostnameVerification hostnameVerification : values()) {
+ if (hostnameVerification.name.equals(name)) {
+ return hostnameVerification;
+ }
+ }
+ throw new IllegalArgumentException("No constant with name: " + name);
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java
index d4c7e48..4cf6ee4 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/ServerPluginConfiguration.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -20,8 +20,11 @@
package org.rhq.modules.plugins.jbossas7.helper;
import java.io.File;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.modules.plugins.jbossas7.JBossProductType;
/**
@@ -35,6 +38,7 @@ public class ServerPluginConfiguration {
public abstract class Property {
public static final String HOSTNAME = "hostname";
public static final String PORT = "port";
+ public static final String SECURE = "secure";
public static final String USER = "user";
public static final String PASSWORD = "password";
public static final String MANAGEMENT_CONNECTION_TIMEOUT = "managementConnectionTimeout";
@@ -46,9 +50,19 @@ public class ServerPluginConfiguration {
public static final String HOST_CONFIG_FILE = "hostConfigFile";
@Deprecated
public static final String AVAIL_CHECK_PERIOD_CONFIG_PROP = "availabilityCheckPeriod";
+ public static final String TRUST_STRATEGY = "trustStrategy";
+ public static final String HOSTNAME_VERIFICATION = "hostnameVerification";
+ public static final String TRUSTSTORE_TYPE = "truststoreType";
+ public static final String TRUSTSTORE = "truststore";
+ public static final String TRUSTSTORE_PASSWORD = "truststorePassword";
+ public static final String CLIENTCERT_AUTHENTICATION = "clientcertAuthentication";
+ public static final String KEYSTORE_TYPE = "keystoreType";
+ public static final String KEYSTORE = "keystore";
+ public static final String KEYSTORE_PASSWORD = "keystorePassword";
+ public static final String KEY_PASSWORD = "keyPassword";
}
- private Configuration pluginConfig;
+ private final Configuration pluginConfig;
public ServerPluginConfiguration(Configuration pluginConfig) {
this.pluginConfig = pluginConfig;
@@ -71,6 +85,15 @@ public class ServerPluginConfiguration {
this.pluginConfig.setSimpleValue(Property.PORT, String.valueOf(port));
}
+ public boolean isSecure() {
+ String stringValue = this.pluginConfig.getSimpleValue(Property.SECURE);
+ return stringValue != null && Boolean.parseBoolean(stringValue);
+ }
+
+ public void setSecure(boolean secure) {
+ this.pluginConfig.setSimpleValue(Property.SECURE, String.valueOf(secure));
+ }
+
public String getUser() {
return this.pluginConfig.getSimpleValue(Property.USER);
}
@@ -155,4 +178,90 @@ public class ServerPluginConfiguration {
public void setAvailabilityCheckPeriod(Integer availabilityCheckPeriod) {
}
+ public TrustStrategy getTrustStrategy() {
+ return TrustStrategy.findByName(pluginConfig.getSimpleValue(Property.TRUST_STRATEGY));
+ }
+
+ public HostnameVerification getHostnameVerification() {
+ return HostnameVerification.findByName(pluginConfig.getSimpleValue(Property.HOSTNAME_VERIFICATION));
+ }
+
+ public String getTruststoreType() {
+ return this.pluginConfig.getSimpleValue(Property.TRUSTSTORE_TYPE);
+ }
+
+ public String getTruststore() {
+ return this.pluginConfig.getSimpleValue(Property.TRUSTSTORE);
+ }
+
+ public String getTruststorePassword() {
+ return this.pluginConfig.getSimpleValue(Property.TRUSTSTORE_PASSWORD);
+ }
+
+ public boolean isClientcertAuthentication() {
+ String stringValue = this.pluginConfig.getSimpleValue(Property.CLIENTCERT_AUTHENTICATION);
+ return stringValue != null && Boolean.parseBoolean(stringValue);
+ }
+
+ public String getKeystoreType() {
+ return this.pluginConfig.getSimpleValue(Property.KEYSTORE_TYPE);
+ }
+
+ public String getKeystore() {
+ return this.pluginConfig.getSimpleValue(Property.KEYSTORE);
+ }
+
+ public String getKeystorePassword() {
+ return this.pluginConfig.getSimpleValue(Property.KEYSTORE_PASSWORD);
+ }
+
+ public String getKeyPassword() {
+ return this.pluginConfig.getSimpleValue(Property.KEY_PASSWORD);
+ }
+
+ /**
+ * Checks server resource connection settings
+ *
+ * @throws InvalidPluginConfigurationException if settings are incorrect
+ */
+ public void validate() {
+ if (isSecure()) {
+ String truststore = getTruststore();
+ if (truststore != null) {
+ if (!new File(truststore).isFile()) {
+ throw new InvalidPluginConfigurationException("Truststore file does not exist");
+ }
+ String truststoreType = getTruststoreType();
+ if (truststoreType == null) {
+ throw new InvalidPluginConfigurationException(
+ "Truststore type is required when using a custom truststore file");
+ }
+ try {
+ KeyStore.getInstance(truststoreType);
+ } catch (KeyStoreException e) {
+ throw new InvalidPluginConfigurationException("Truststore type not supported: " + e.getMessage(), e);
+ }
+ }
+ if (isClientcertAuthentication()) {
+ String keystore = getKeystore();
+ if (keystore == null) {
+ throw new InvalidPluginConfigurationException(
+ "Keystore is required when using client certificate authentication");
+ }
+ if (!new File(keystore).isFile()) {
+ throw new InvalidPluginConfigurationException("Keystore file does not exist");
+ }
+ String keystoreType = getKeystoreType();
+ if (keystoreType == null) {
+ throw new InvalidPluginConfigurationException(
+ "Keystore type is required when using a custom keystore file");
+ }
+ try {
+ KeyStore.getInstance(keystoreType);
+ } catch (KeyStoreException e) {
+ throw new InvalidPluginConfigurationException("Keystore type not supported: " + e.getMessage(), e);
+ }
+ }
+ }
+ }
}
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/TrustStrategy.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/TrustStrategy.java
new file mode 100644
index 0000000..780124a
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/helper/TrustStrategy.java
@@ -0,0 +1,45 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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.helper;
+
+/**
+* @author Thomas Segismont
+*/
+public enum TrustStrategy {
+ STANDARD("standard"), TRUST_SELFSIGNED("trustSelfsigned"), TRUST_ANY("trustAny");
+
+ public final String name;
+
+ TrustStrategy(String name) {
+ this.name = name;
+ }
+
+ public static TrustStrategy findByName(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("name is null");
+ }
+ for (TrustStrategy strategy : values()) {
+ if (strategy.name.equals(name)) {
+ return strategy;
+ }
+ }
+ throw new IllegalArgumentException("No constant with name: " + name);
+ }
+}
diff --git a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
index 972e31f..b7dcaaa 100644
--- a/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/jboss-as-7/src/main/resources/META-INF/rhq-plugin.xml
@@ -102,6 +102,90 @@
</c:group>
'>
+ <!ENTITY managementInterfaceSecureConnectionSettings '
+ <c:group name="secureConnectionSettings">
+ <c:simple-property name="trustStrategy" default="standard">
+ <c:description>
+ Defines the trust strategy to use when reading the server certificate:
+ <ul>
+ <li>Standard: standard verification using a truststore</li>
+ <li>Trust Self-signed: trust self-signed certificates (certification chain size equals to 1)</li>
+ <li>Trust Any: trust any server certificate</li>
+ </ul>
+ </c:description>
+ <c:property-options>
+ <c:option value="standard" name="Standard"/>
+ <c:option value="trustSelfsigned" name="Trust Self-signed"/>
+ <c:option value="trustAny" name="Trust Any"/>
+ </c:property-options>
+ </c:simple-property>
+ <c:simple-property name="hostnameVerification" default="strict">
+ <c:description>
+ Defines the hostname verification logic:
+ <ul>
+ <li>Strict: The hostname must match either the first CN, or any of the
+ <a href="http://en.wikipedia.org/wiki/Subject_Alternative_Name">Subject Alternatives</a>.
+ A wildcard can occur in the CN, and in any of the Subject Alternatives.</li>
+ <li>Browser-compatible: same as <em>Strict</em>, except that it allows nested subdomains
+ validation with wildcards.</li>
+ <li>Skip: no hostname verification</li>
+ </ul>
+ </c:description>
+ <c:property-options>
+ <c:option value="strict" name="Strict"/>
+ <c:option value="browserCompatible" name="Browser-compatible"/>
+ <c:option value="skip" name="Skip"/>
+ </c:property-options>
+ </c:simple-property>
+ <c:simple-property name="truststore" required="false">
+ <c:description>
+ Path to a truststore file. If undefined, the JVM default truststore is used.
+ </c:description>
+ </c:simple-property>
+ <c:simple-property name="truststoreType" required="false" default="jks">
+ <c:description>
+ Truststore file format (required when the <em>Truststore</em> property is set).
+ All certified JVMs support <em>jks</em> (Java KeyStore) or <em>pkcs12</em> formats.
+ </c:description>
+ <c:property-options allowCustomValue="true">
+ <c:option value="jks"/>
+ <c:option value="pkcs12"/>
+ </c:property-options>
+ </c:simple-property>
+ <c:simple-property name="truststorePassword" required="false" type="password">
+ <c:description>
+ Password protecting the truststore file.
+ </c:description>
+ </c:simple-property>
+ <c:simple-property name="clientcertAuthentication" default="false" type="boolean" displayName="Client Certificate Authentication"/>
+ <c:simple-property name="keystore" required="false">
+ <c:description>
+ Path to a keystore file. Required when <em>Client Certificate Authentication</em> is on.
+ </c:description>
+ </c:simple-property>
+ <c:simple-property name="keystoreType" required="false" default="jks">
+ <c:description>
+ Keystore file format (required when the <em>Keystore</em> property is set).
+ All certified JVMs support <em>jks</em> (Java KeyStore) or <em>pkcs12</em> formats.
+ </c:description>
+ <c:property-options allowCustomValue="true">
+ <c:option value="jks"/>
+ <c:option value="pkcs12"/>
+ </c:property-options>
+ </c:simple-property>
+ <c:simple-property name="keystorePassword" required="false" type="password">
+ <c:description>
+ Password protecting the keystore file.
+ </c:description>
+ </c:simple-property>
+ <c:simple-property name="keyPassword" required="false" type="password">
+ <c:description>
+ Password protecting the secret key in the keystore file.
+ </c:description>
+ </c:simple-property>
+ </c:group>
+'>
+
<!ENTITY serverKindMetrics '
<metric property="_skm:release-codename" dataType="trait" displayName="Server Code Name"/>
<metric property="_skm:release-version" dataType="trait" displayName="Server Version"/>
@@ -929,6 +1013,7 @@
<plugin-configuration>
<c:simple-property name="hostname" default="localhost" required="true" description="Host name of the domain API"/>
<c:simple-property name="port" default="9990" type="integer" required="true" description="Port of the domain API"/>
+ <c:simple-property name="secure" default="false" type="boolean" description="Encrypted transport indicator"/>
<c:simple-property name="user" type="string" description="Management user for a secured Host controller" required="false"/>
<c:simple-property name="password" type="password" description="Password for the management user" required="false"/>
<c:simple-property name="managementConnectionTimeout" type="long" description="Maximum time in milliseconds to keep alive an idle management connection. Zero and negative values will disable connection persistence. Defaults to 5000 ms." required="false" default="5000"/>
@@ -941,6 +1026,7 @@
&startScriptPluginConfigGroup;
&logSources;
+ &managementInterfaceSecureConnectionSettings;
</plugin-configuration>
@@ -1247,6 +1333,7 @@
<plugin-configuration>
<c:simple-property name="hostname" default="localhost" required="true"/>
<c:simple-property name="port" default="9990" type="integer" required="true"/>
+ <c:simple-property name="secure" default="false" type="boolean" description="Encrypted transport indicator"/>
<c:simple-property name="user" type="string" description="Management user for a secured AS" required="false"/>
<c:simple-property name="password" type="password" description="Password for the management user" required="false"/>
<c:simple-property name="managementConnectionTimeout" type="long" description="Maximum time in milliseconds to keep alive an idle management connection. Zero and negative values will disable connection persistence. Defaults to 5000 ms." required="false" default="5000"/>
@@ -1258,6 +1345,7 @@
&startScriptPluginConfigGroup;
&logSources;
+ &managementInterfaceSecureConnectionSettings;
</plugin-configuration>
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 ca1cc36..5f6e468 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-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -168,7 +168,12 @@ public abstract class AbstractConfigurationHandlingTest {
JsonNode content;
public FakeConnection() {
- super("localhost", 1234, "fake", "fake");
+ super(new ASConnectionParamsBuilder() //
+ .setHost("localhost") //
+ .setPort(1234) //
+ .setUsername("fake") //
+ .setPassword("fake") //
+ .createASConnectionParams());
}
public void setContent(JsonNode content) {
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java
index ead0224..c8544c1 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -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.itest.domain;
import static org.testng.Assert.assertEquals;
@@ -54,6 +55,8 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.configuration.ConfigurationManager;
import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.modules.plugins.jbossas7.ASConnection;
+import org.rhq.modules.plugins.jbossas7.ASConnectionParams;
+import org.rhq.modules.plugins.jbossas7.ASConnectionParamsBuilder;
import org.rhq.modules.plugins.jbossas7.ModuleOptionsComponent;
import org.rhq.modules.plugins.jbossas7.ModuleOptionsComponent.Value;
import org.rhq.modules.plugins.jbossas7.itest.AbstractJBossAS7PluginTest;
@@ -95,8 +98,13 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
protected static String DC_PASS = AbstractJBossAS7PluginTest.MANAGEMENT_PASSWORD;
ASConnection getASConnection() {
- ASConnection connection = new ASConnection(DC_HOST, DC_HTTP_PORT, DC_USER, DC_PASS);
- return connection;
+ ASConnectionParams asConnectionParams = new ASConnectionParamsBuilder() //
+ .setHost(DC_HOST) //
+ .setPort(DC_HTTP_PORT) //
+ .setUsername(DC_USER) //
+ .setPassword(DC_PASS) //
+ .createASConnectionParams();
+ return new ASConnection(asConnectionParams);
}
public static final ResourceType RESOURCE_TYPE = new ResourceType(SECURITY_RESOURCE_TYPE, PLUGIN_NAME,
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/AbstractIntegrationTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/AbstractIntegrationTest.java
index 428f854..f0adb67 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/AbstractIntegrationTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/AbstractIntegrationTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
+ * Copyright (C) 2005-2014 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.itest.nonpc;
import java.io.File;
@@ -48,6 +49,8 @@ import org.rhq.core.clientapi.descriptor.plugin.ServiceDescriptor;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.util.stream.StreamUtil;
import org.rhq.modules.plugins.jbossas7.ASConnection;
+import org.rhq.modules.plugins.jbossas7.ASConnectionParams;
+import org.rhq.modules.plugins.jbossas7.ASConnectionParamsBuilder;
import org.rhq.modules.plugins.jbossas7.ASUploadConnection;
import org.rhq.modules.plugins.jbossas7.itest.AbstractJBossAS7PluginTest;
import org.rhq.modules.plugins.jbossas7.json.Address;
@@ -72,7 +75,13 @@ public abstract class AbstractIntegrationTest {
String uploadToAs(String deploymentPath) throws IOException {
String fileName = new File(deploymentPath).getName();
- ASUploadConnection conn = new ASUploadConnection(DC_HOST, DC_HTTP_PORT, DC_USER, DC_PASS, fileName);
+ ASConnectionParams asConnectionParams = new ASConnectionParamsBuilder() //
+ .setHost(DC_HOST) //
+ .setPort(DC_HTTP_PORT) //
+ .setUsername(DC_USER) //
+ .setPassword(DC_PASS) //
+ .createASConnectionParams();
+ ASUploadConnection conn = new ASUploadConnection(asConnectionParams, fileName);
OutputStream os = conn.getOutputStream();
// URL url = getClass().getClassLoader().getResource(".");
@@ -107,8 +116,13 @@ public abstract class AbstractIntegrationTest {
}
ASConnection getASConnection() {
- ASConnection connection = new ASConnection(DC_HOST, DC_HTTP_PORT, DC_USER, DC_PASS);
- return connection;
+ ASConnectionParams asConnectionParams = new ASConnectionParamsBuilder() //
+ .setHost(DC_HOST) //
+ .setPort(DC_HTTP_PORT) //
+ .setUsername(DC_USER) //
+ .setPassword(DC_PASS) //
+ .createASConnectionParams();
+ return new ASConnection(asConnectionParams);
}
Operation addDeployment(String deploymentName, String bytes_value) {
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/InterruptibleOperationsTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/InterruptibleOperationsTest.java
new file mode 100644
index 0000000..5f7f1ecc
--- /dev/null
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/InterruptibleOperationsTest.java
@@ -0,0 +1,251 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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.nonpc;
+
+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.JBossProductType.AS;
+import static org.rhq.modules.plugins.jbossas7.helper.HostnameVerification.SKIP;
+import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.HOSTNAME;
+import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.HOSTNAME_VERIFICATION;
+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.SECURE;
+import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.TRUST_STRATEGY;
+import static org.rhq.modules.plugins.jbossas7.helper.ServerPluginConfiguration.Property.USER;
+import static org.rhq.modules.plugins.jbossas7.helper.TrustStrategy.TRUST_ANY;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.BindException;
+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.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.component.ComponentInvocationContext;
+import org.rhq.core.pluginapi.inventory.ResourceContext;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.system.SystemInfoFactory;
+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
+ */
+@Test(singleThreaded = true)
+public class InterruptibleOperationsTest {
+
+ private static final String HTTP_HOST = "localhost";
+
+ private static final int MIN_DYNAMIC_PORT = 49152;
+
+ private static final int MAX_PORT_NUMBER = 65535;
+
+ @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 = setupJettyServer();
+ setupResourceContext(httpPort);
+ executorService = Executors.newSingleThreadExecutor();
+ when(resourceContext.getComponentInvocationContext()).thenReturn(new MockComponentInvocationContext());
+ serverComponent.start(resourceContext);
+ }
+
+ private int setupJettyServer() throws Exception {
+ // Loop until Jetty binds to an available port
+ for (int httpPort = MIN_DYNAMIC_PORT; httpPort <= MAX_PORT_NUMBER; httpPort++) {
+ ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ context.setContextPath("/");
+ HttpServlet testServlet = new TestServlet();
+ context.addServlet(new ServletHolder(testServlet), "/*");
+ jettyServer = new Server(new InetSocketAddress(HTTP_HOST, httpPort));
+ jettyServer.setHandler(context);
+ try {
+ jettyServer.start();
+ return httpPort;
+ } catch (BindException e) {
+ // Port already in use
+ }
+ }
+ throw new RuntimeException("Could not find an available 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(SECURE, String.valueOf(false));
+ pluginConfig.setSimpleValue(USER, "pipo");
+ pluginConfig.setSimpleValue(PASSWORD, "molo");
+ pluginConfig.setSimpleValue(MANAGEMENT_CONNECTION_TIMEOUT, "-1");
+ pluginConfig.getMap().put(LOG_EVENT_SOURCES_CONFIG_PROP, new PropertyList());
+ pluginConfig.setSimpleValue(TRUST_STRATEGY, TRUST_ANY.name);
+ pluginConfig.setSimpleValue(HOSTNAME_VERIFICATION, SKIP.name);
+ pluginConfig.setSimpleValue("expectedRuntimeProductName", AS.PRODUCT_NAME);
+ return pluginConfig;
+ }
+
+ @AfterMethod
+ private void tearDown() throws Exception {
+ 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 static class MockComponentInvocationContext implements ComponentInvocationContext {
+ @Override
+ public boolean isInterrupted() {
+ return false;
+ }
+
+ @Override
+ public void markInterrupted() {
+ }
+ }
+
+ 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;
+ }
+ }
+
+}
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java
index 1111b9f..c1e1d8a 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -34,6 +34,8 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.rhq.modules.plugins.jbossas7.ASConnection;
+import org.rhq.modules.plugins.jbossas7.ASConnectionParams;
+import org.rhq.modules.plugins.jbossas7.ASConnectionParamsBuilder;
import org.rhq.modules.plugins.jbossas7.json.Address;
import org.rhq.modules.plugins.jbossas7.json.ReadAttribute;
import org.rhq.modules.plugins.jbossas7.json.Result;
@@ -61,7 +63,14 @@ public class ManagementConnectionPersistenceTest extends AbstractIntegrationTest
@Test(timeOut = 60 * 1000)
public void testWithDisabledConnectionPersistence() throws Exception {
- final ASConnection asConnection = new ASConnection(DC_HOST, DC_HTTP_PORT, DC_USER, DC_PASS, Long.valueOf(-1));
+ ASConnectionParams asConnectionParams = new ASConnectionParamsBuilder() //
+ .setHost(DC_HOST) //
+ .setPort(DC_HTTP_PORT) //
+ .setUsername(DC_USER) //
+ .setPassword(DC_PASS) //
+ .setKeepAliveTimeout(Long.valueOf(-1)) //
+ .createASConnectionParams();
+ ASConnection asConnection = new ASConnection(asConnectionParams);
List<Future<Result>> results = doTest(asConnection);
checkResults(results, true);
// Wait a bit
@@ -72,7 +81,13 @@ public class ManagementConnectionPersistenceTest extends AbstractIntegrationTest
@Test(timeOut = 60 * 1000)
public void testWithDefaultConnectionPersistence() throws Exception {
- final ASConnection asConnection = new ASConnection(DC_HOST, DC_HTTP_PORT, DC_USER, DC_PASS);
+ ASConnectionParams asConnectionParams = new ASConnectionParamsBuilder() //
+ .setHost(DC_HOST) //
+ .setPort(DC_HTTP_PORT) //
+ .setUsername(DC_USER) //
+ .setPassword(DC_PASS) //
+ .createASConnectionParams();
+ ASConnection asConnection = new ASConnection(asConnectionParams);
List<Future<Result>> results = doTest(asConnection);
checkResults(results, true);
// Wait for EAP to close persistent connections server side
@@ -83,8 +98,14 @@ public class ManagementConnectionPersistenceTest extends AbstractIntegrationTest
@Test(timeOut = 60 * 1000)
public void shouldFailForTooLongKeepAliveDuration() throws Exception {
- final ASConnection asConnection = new ASConnection(DC_HOST, DC_HTTP_PORT, DC_USER, DC_PASS,
- Long.valueOf(1000 * 60 * 60));
+ ASConnectionParams asConnectionParams = new ASConnectionParamsBuilder() //
+ .setHost(DC_HOST) //
+ .setPort(DC_HTTP_PORT) //
+ .setUsername(DC_USER) //
+ .setPassword(DC_PASS) //
+ .setKeepAliveTimeout(Long.valueOf(1000 * 60 * 60)) //
+ .createASConnectionParams();
+ ASConnection asConnection = new ASConnection(asConnectionParams);
List<Future<Result>> results = doTest(asConnection);
checkResults(results, true);
// Wait for EAP to close persistent connections server side
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
deleted file mode 100644
index b0acf4d..0000000
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/InterruptibleOperationsTest.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * 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.BindException;
-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.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.rhq.core.pluginapi.component.ComponentInvocationContext;
-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.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
- */
-@Test(singleThreaded = true)
-public class InterruptibleOperationsTest {
-
- private static final String HTTP_HOST = "localhost";
-
- private static final int MIN_DYNAMIC_PORT = 49152;
-
- private static final int MAX_PORT_NUMBER = 65535;
-
- @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 = setupJettyServer();
- setupResourceContext(httpPort);
- executorService = Executors.newSingleThreadExecutor();
- when(resourceContext.getComponentInvocationContext()).thenReturn(new MockComponentInvocationContext());
- serverComponent.start(resourceContext);
- }
-
- private int setupJettyServer() throws Exception {
- // Loop until Jetty binds to an available port
- for (int httpPort = MIN_DYNAMIC_PORT; httpPort <= MAX_PORT_NUMBER; httpPort++) {
- ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
- context.setContextPath("/");
- HttpServlet testServlet = new TestServlet();
- context.addServlet(new ServletHolder(testServlet), "/*");
- jettyServer = new Server(new InetSocketAddress(HTTP_HOST, httpPort));
- jettyServer.setHandler(context);
- try {
- jettyServer.start();
- return httpPort;
- } catch (BindException e) {
- // Port already in use
- }
- }
- throw new RuntimeException("Could not find an available 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 {
- 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 static class MockComponentInvocationContext implements ComponentInvocationContext {
- @Override
- public boolean isInterrupted() {
- return false;
- }
-
- @Override
- public void markInterrupted() {
- }
- }
-
- 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;
- }
- }
-
-}
10 years, 3 months
[rhq] Branch 'feature/embeddedagent' - 43 commits - etc/rhq-ircBot modules/core modules/enterprise modules/plugins pom.xml
by mazz
etc/rhq-ircBot/pom.xml | 22
etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/BugResolver.java | 27
etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/BugzillaResolver.java | 75 ++
etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/Color.java | 46 +
etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/JiraResolver.java | 67 ++
etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java | 145 ++--
modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java | 23
modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java | 3
modules/core/domain/src/main/resources/META-INF/persistence.xml | 2
modules/core/native-system/src/main/java/org/rhq/core/system/FileSystemInfo.java | 52 -
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventPoller.java | 66 +-
modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventResourceComponentHelper.java | 18
modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/avail/AvailTest.java | 20
modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java | 10
modules/core/plugin-container/pom.xml | 1
modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationCheckExecutor.java | 77 +-
modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java | 8
modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java | 9
modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/SnapshotGenerator.java | 17
modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java | 21
modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/InventoryPrinter.java | 26
modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java | 11
modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java | 96 ++
modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java | 10
modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/CmdlineClient.java | 7
modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java | 322 ++--------
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/common/graph/ButtonBarDateTimeRangeEditor.java | 62 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/groups/detail/monitoring/metric/MetricsGroupViewDataSource.java | 27
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/resource/detail/monitoring/table/MetricsViewDataSource.java | 27
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties | 8
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties | 2
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties | 2
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties | 2
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties | 2
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties | 2
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties | 2
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java | 7
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java | 7
modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java | 26
modules/plugins/jboss-as-7/pom.xml | 67 +-
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java | 24
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java | 32
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java | 13
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java | 21
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java | 2
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java | 41 -
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java | 82 +-
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java | 46 -
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java | 57 -
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java | 2
modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/TemplatedResourcesTest.java | 6
modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemComponent.java | 7
pom.xml | 6
54 files changed, 1058 insertions(+), 707 deletions(-)
New commits:
commit 1a94219de01fb3ab5e24e1119307dfc7d8abdeb7
Merge: 37c6e18 e4aedd0
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Feb 4 09:54:26 2014 -0500
Merge branch 'feature/embeddedagent' of ssh://git.fedorahosted.org/git/rhq/rhq into feature/embeddedagent
commit 37c6e18453d4d3781c8e4e3b2ce7c09b9a8c62ff
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Feb 3 17:19:54 2014 -0500
add ability to set generic config preferences
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
index 115f74b..154d5d8 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -43,6 +43,7 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
AgentSubsystemDefinition.SERVER_TRANSPORT_PARAMS_ATTRIBDEF.validateAndSet(operation, model);
AgentSubsystemDefinition.SERVER_ALIAS_ATTRIBDEF.validateAndSet(operation, model);
AgentSubsystemDefinition.SOCKET_BINDING_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.CUSTOM_CONFIG_ATTRIBDEF.validateAndSet(operation, model);
log.info("Populating the embedded agent subsystem model: " + operation + "=" + model);
}
@@ -85,6 +86,20 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_TRANSPORT_ATTRIBDEF);
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_TRANSPORT_PARAMS_ATTRIBDEF);
+ // allow the user to provide their own overrides
+ ModelNode customConfigNode = AgentSubsystemDefinition.CUSTOM_CONFIG_ATTRIBDEF.resolveModelAttribute(context,
+ model);
+ if (customConfigNode != null && customConfigNode.isDefined()) {
+ HashMap<String, String> customConfig = new HashMap<String, String>();
+ List<Property> prefList = customConfigNode.asPropertyList();
+ for (Property pref : prefList) {
+ String name = pref.getName();
+ String val = pref.getValue().asString();
+ customConfig.put(name, val);
+ }
+ overrides.putAll(customConfig);
+ }
+
// create our service
AgentService service = new AgentService();
service.setPlugins(pluginsWithEnableFlag);
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
index 78d274b..1224d84 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
@@ -30,6 +30,8 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
protected static final PluginsAttributeDefinition PLUGINS_ATTRIBDEF = new PluginsAttributeDefinition();
+ protected static final CustomConfigAttributeDefinition CUSTOM_CONFIG_ATTRIBDEF = new CustomConfigAttributeDefinition();
+
protected static final SimpleAttributeDefinition AGENT_NAME_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_AGENT_NAME, ModelType.STRING).setAllowExpression(true)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
@@ -97,6 +99,7 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
public void registerAttributes(ManagementResourceRegistration rr) {
rr.registerReadWriteAttribute(AGENT_ENABLED_ATTRIBDEF, null, AgentEnabledAttributeHandler.INSTANCE);
rr.registerReadWriteAttribute(PLUGINS_ATTRIBDEF, null, PluginsAttributeHandler.INSTANCE);
+ registerReloadRequiredWriteAttributeHandler(rr, CUSTOM_CONFIG_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, AGENT_NAME_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, DISABLE_NATIVE_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, SERVER_TRANSPORT_ATTRIBDEF);
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
index 637b7a8..4463ad9 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
@@ -17,6 +17,7 @@ import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.SubsystemRegistration;
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
+import org.jboss.as.controller.parsing.Attribute;
import org.jboss.as.controller.parsing.ExtensionParsingContext;
import org.jboss.as.controller.parsing.ParseUtils;
import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
@@ -51,6 +52,8 @@ public class AgentSubsystemExtension implements Extension {
protected static final String AGENT_ENABLED = "enabled";
protected static final boolean AGENT_ENABLED_DEFAULT = false;
protected static final boolean PLUGIN_ENABLED_DEFAULT = true;
+ protected static final String AGENT_CONFIG_ELEMENT = "extra-configuration";
+ protected static final String PREFERENCE_ELEMENT = "preference";
protected static final String SERVER_ENDPOINT_ELEMENT = "server-endpoint";
protected static final String SERVER_ENDPOINT_ADDRESS_XML = "address";
protected static final String SERVER_ENDPOINT_PORT_XML = "port";
@@ -131,6 +134,13 @@ public class AgentSubsystemExtension implements Extension {
readPlugin(reader, pluginsAttributeNode);
}
}
+ } else if (elementName.equals(AGENT_CONFIG_ELEMENT)) {
+ ModelNode configAttributeNode = opAdd.get(AGENT_CONFIG_ELEMENT);
+ while (reader.hasNext() && reader.nextTag() != END_ELEMENT) {
+ if (reader.isStartElement()) {
+ readPreference(reader, configAttributeNode);
+ }
+ }
} else if (elementName.equals(SERVER_ENDPOINT_ELEMENT)) {
String val = reader.getAttributeValue(null, SERVER_ENDPOINT_ADDRESS_XML);
if (val != null) {
@@ -206,6 +216,21 @@ public class AgentSubsystemExtension implements Extension {
pluginsAttributeNode.add(pluginName, pluginEnabled);
}
+ private void readPreference(XMLExtendedStreamReader reader, ModelNode configAttributeNode)
+ throws XMLStreamException {
+
+ if (!reader.getLocalName().equals(PREFERENCE_ELEMENT)) {
+ throw ParseUtils.unexpectedElement(reader);
+ }
+
+ ParseUtils.requireAttributes(reader, Attribute.NAME.getLocalName(), Attribute.VALUE.getLocalName());
+ String attr = reader.getAttributeValue(null, Attribute.NAME.getLocalName());
+ String val = reader.getAttributeValue(null, Attribute.VALUE.getLocalName());
+ ParseUtils.requireNoContent(reader);
+
+ configAttributeNode.add(attr, val);
+ }
+
@Override
public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context)
throws XMLStreamException {
@@ -261,6 +286,22 @@ public class AgentSubsystemExtension implements Extension {
// </agent-endpoint>
writer.writeEndElement();
+ // <extra-configuration>
+ writer.writeStartElement(AGENT_CONFIG_ELEMENT);
+ ModelNode configNode = node.get(AGENT_CONFIG_ELEMENT);
+ if (configNode != null && configNode.isDefined()) {
+ for (Property property : configNode.asPropertyList()) {
+ // <preference>
+ writer.writeStartElement(PREFERENCE_ELEMENT);
+ writer.writeAttribute(Attribute.NAME.getLocalName(), property.getName());
+ writer.writeAttribute(Attribute.VALUE.getLocalName(), property.getValue().asString());
+ // </preference>
+ writer.writeEndElement();
+ }
+ }
+ // </extra-configuration>
+ writer.writeEndElement();
+
// <plugins>
writer.writeStartElement(PLUGINS_ELEMENT);
ModelNode plugins = node.get(PLUGINS_ELEMENT);
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/CustomConfigAttributeDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/CustomConfigAttributeDefinition.java
new file mode 100644
index 0000000..5129f3d
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/CustomConfigAttributeDefinition.java
@@ -0,0 +1,61 @@
+package org.rhq.embeddedagent.extension;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.jboss.as.controller.MapAttributeDefinition;
+import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
+import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
+import org.jboss.as.controller.operations.validation.ModelTypeValidator;
+import org.jboss.as.controller.parsing.Attribute;
+import org.jboss.as.controller.registry.AttributeAccess.Flag;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.ModelType;
+
+/**
+ * A generic catch-all to allow the agent to have any config preference set.
+ *
+ * @author John Mazzitelli
+ */
+public class CustomConfigAttributeDefinition extends MapAttributeDefinition {
+
+ public CustomConfigAttributeDefinition() {
+ super(AgentSubsystemExtension.AGENT_CONFIG_ELEMENT, AgentSubsystemExtension.AGENT_CONFIG_ELEMENT, true,
+ 0, Integer.MAX_VALUE, new ModelTypeValidator(ModelType.STRING), null, null, Flag.RESTART_RESOURCE_SERVICES);
+ }
+
+ @Override
+ protected void addValueTypeDescription(ModelNode node, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ protected void addAttributeValueTypeDescription(ModelNode node, ResourceDescriptionResolver resolver,
+ Locale locale, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ protected void addOperationParameterValueTypeDescription(ModelNode node, String operationName,
+ ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ public void marshallAsElement(ModelNode resourceModel, XMLStreamWriter writer) throws XMLStreamException {
+ if (!isMarshallable(resourceModel))
+ return;
+
+ resourceModel = resourceModel.get(getName());
+ writer.writeStartElement(getName());
+ for (ModelNode property : resourceModel.asList()) {
+ writer.writeEmptyElement(getXmlName());
+ writer.writeAttribute(Attribute.NAME.getLocalName(), property.asProperty().getName());
+ writer.writeAttribute(Attribute.VALUE.getLocalName(), property.asProperty().getValue().asString());
+ }
+ writer.writeEndElement();
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
index 680f9f2..f4b08d1 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
@@ -6,6 +6,7 @@ embeddedagent.stop=Stops the RHQ Agent if it is running.
embeddedagent.status=Tells you if the RHQ Agent is currently started or stopped.
embeddedagent.enabled=When true, the RHQ Agent will be deployed and started. Otherwise, it will be disabled.
embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
+embeddedagent.extra-configuration=Additional preference values used to configure the agent
embeddedagent.socket-binding=Determines the binding address and port the agent listens to for incoming server messages.
embeddedagent.rhq.communications.connector.transport=The transport server must use to communicate with the agent.
embeddedagent.rhq.communications.connector.transport-params=The transport parameters the server must use to communicate with the agent.
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
index a116308..3439cf2 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
@@ -15,6 +15,7 @@
<xs:element name="rhq.agent.server.alias" type="xs:string"/>
<xs:element name="server-endpoint" type="serverEndpointType"/>
<xs:element name="agent-endpoint" type="agentEndpointType"/>
+ <xs:element name="extra-configuration" type="extraConfigurationType"/>
<xs:element name="plugins" type="pluginsType"/>
</xs:all>
</xs:complexType>
@@ -41,4 +42,14 @@
<xs:attribute name="name" use="required"/>
<xs:attribute name="enabled" type="xs:boolean" use="required" default="true"/>
</xs:complexType>
+
+ <xs:complexType name="extraConfigurationType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="preference" type="preferenceType"/>
+ </xs:choice>
+ </xs:complexType>
+ <xs:complexType name="preferenceType">
+ <xs:attribute name="name" use="required"/>
+ <xs:attribute name="value" use="required"/>
+ </xs:complexType>
</xs:schema>
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
index b6126a0..5c2f3d4 100644
--- a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -198,6 +198,7 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
List<Property> attributes = content.get("attributes").asPropertyList();
List<String> expectedAttributes = Arrays.asList( //
+ AgentSubsystemExtension.AGENT_CONFIG_ELEMENT, //
AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT_PARAMS, //
AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT, //
AgentSubsystemExtension.ATTRIB_SOCKET_BINDING, //
diff --git a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
index d4ea3c8..c847ee6 100644
--- a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
+++ b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
@@ -6,6 +6,11 @@
<server-endpoint port="7080" transport="test-transport" transport-params="test-transport-params" />
<agent-endpoint socket-binding="embeddedagent" transport="socket"/>
+ <extra-configuration>
+ <preference name="custom-prop" value="custom-prop-val"/>
+ <preference name="custom-prop2" value="custom-prop-val2"/>
+ </extra-configuration>
+
<plugins>
<plugin name="platform" enabled="true" />
<plugin name="blah" enabled="false" />
commit ec9d3e7c94581958aa99ba48831fecea2607a08b
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Feb 3 15:46:27 2014 -0500
add transport agent-endpoint configurability
make server endpoing configured via one element with some attribs
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
index 937af70..115f74b 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -82,6 +82,8 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_BIND_ADDRESS_ATTRIBDEF);
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_TRANSPORT_PARAMS_ATTRIBDEF);
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_ALIAS_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_TRANSPORT_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_TRANSPORT_PARAMS_ATTRIBDEF);
// create our service
AgentService service = new AgentService();
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
index ad50c4e..78d274b 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
@@ -17,6 +17,7 @@ import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.rhq.enterprise.agent.AgentConfigurationConstants;
+import org.rhq.enterprise.communications.ServiceContainerConfigurationConstants;
public class AgentSubsystemDefinition extends SimpleResourceDefinition {
@@ -31,50 +32,61 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
protected static final SimpleAttributeDefinition AGENT_NAME_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_AGENT_NAME, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_AGENT_NAME).setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setAllowNull(true).build();
protected static final SimpleAttributeDefinition DISABLE_NATIVE_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_DISABLE_NATIVE, ModelType.BOOLEAN).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_DISABLE_NATIVE)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
- protected static final SimpleAttributeDefinition SERVER_TRANSPORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
- AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT)
- .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
- .setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_TRANSPORT)).setAllowNull(false)
- .build();
+ protected static final SimpleAttributeDefinition SERVER_BIND_ADDRESS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.SERVER_ENDPOINT_ADDRESS_XML)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
protected static final SimpleAttributeDefinition SERVER_BIND_PORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT)
+ .setXmlName(AgentSubsystemExtension.SERVER_ENDPOINT_PORT_XML)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_BIND_PORT)).setAllowNull(false)
.build();
- protected static final SimpleAttributeDefinition SERVER_BIND_ADDRESS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
- AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS)
- .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
+ protected static final SimpleAttributeDefinition SERVER_TRANSPORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.SERVER_ENDPOINT_TRANSPORT_XML)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_TRANSPORT)).setAllowNull(false)
+ .build();
protected static final SimpleAttributeDefinition SERVER_TRANSPORT_PARAMS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT_PARAMS, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT_PARAMS)
+ .setXmlName(AgentSubsystemExtension.SERVER_ENDPOINT_TRANSPORT_XML)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_TRANSPORT_PARAMS))
.setAllowNull(false).build();
protected static final SimpleAttributeDefinition SERVER_ALIAS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_SERVER_ALIAS, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_ALIAS)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
protected static final SimpleAttributeDefinition SOCKET_BINDING_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_SOCKET_BINDING, ModelType.STRING)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setDefaultValue(new ModelNode("embeddedagent"))
+ .setValidator(new StringLengthValidator(1)).setAllowNull(false).build();
+
+ protected static final SimpleAttributeDefinition AGENT_TRANSPORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.AGENT_ENDPOINT_TRANSPORT_XML)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
- .setDefaultValue(new ModelNode("embeddedagent")).setValidator(new StringLengthValidator(1)).setAllowNull(false)
- .build();
+ .setDefaultValue(new ModelNode(ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_TRANSPORT))
+ .setAllowNull(true).build();
+
+ protected static final SimpleAttributeDefinition AGENT_TRANSPORT_PARAMS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT_PARAMS, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.AGENT_ENDPOINT_TRANSPORT_PARAMS_XML)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode(ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_TRANSPORT_PARAMS))
+ .setAllowNull(true).build();
private AgentSubsystemDefinition() {
super(AgentSubsystemExtension.SUBSYSTEM_PATH, AgentSubsystemExtension.getResourceDescriptionResolver(null),
@@ -93,6 +105,8 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
registerReloadRequiredWriteAttributeHandler(rr, SERVER_TRANSPORT_PARAMS_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, SERVER_ALIAS_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, SOCKET_BINDING_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, AGENT_TRANSPORT_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, AGENT_TRANSPORT_PARAMS_ATTRIBDEF);
}
private void registerReloadRequiredWriteAttributeHandler(ManagementResourceRegistration rr, AttributeDefinition def) {
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
index 4374c7e..637b7a8 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
@@ -30,6 +30,7 @@ import org.jboss.staxmapper.XMLExtendedStreamReader;
import org.jboss.staxmapper.XMLExtendedStreamWriter;
import org.rhq.enterprise.agent.AgentConfigurationConstants;
+import org.rhq.enterprise.communications.ServiceContainerConfigurationConstants;
public class AgentSubsystemExtension implements Extension {
@@ -50,6 +51,15 @@ public class AgentSubsystemExtension implements Extension {
protected static final String AGENT_ENABLED = "enabled";
protected static final boolean AGENT_ENABLED_DEFAULT = false;
protected static final boolean PLUGIN_ENABLED_DEFAULT = true;
+ protected static final String SERVER_ENDPOINT_ELEMENT = "server-endpoint";
+ protected static final String SERVER_ENDPOINT_ADDRESS_XML = "address";
+ protected static final String SERVER_ENDPOINT_PORT_XML = "port";
+ protected static final String SERVER_ENDPOINT_TRANSPORT_XML = "transport";
+ protected static final String SERVER_ENDPOINT_TRANSPORT_PARAMS_XML = "transport-params";
+ protected static final String AGENT_ENDPOINT_ELEMENT = "agent-endpoint";
+ protected static final String AGENT_ENDPOINT_SOCKET_BINDING_XML = "socket-binding";
+ protected static final String AGENT_ENDPOINT_TRANSPORT_XML = "transport";
+ protected static final String AGENT_ENDPOINT_TRANSPORT_PARAMS_XML = "transport-params";
protected static final String AGENT_RESTART_OP = "restart";
protected static final String AGENT_STOP_OP = "stop";
@@ -62,10 +72,13 @@ public class AgentSubsystemExtension implements Extension {
protected static final String ATTRIB_SERVER_BIND_ADDRESS = AgentConfigurationConstants.SERVER_BIND_ADDRESS;
protected static final String ATTRIB_SERVER_TRANSPORT_PARAMS = AgentConfigurationConstants.SERVER_TRANSPORT_PARAMS;
protected static final String ATTRIB_SERVER_ALIAS = AgentConfigurationConstants.SERVER_ALIAS;
- protected static final String ATTRIB_SOCKET_BINDING = "socket-binding";
+ protected static final String ATTRIB_SOCKET_BINDING = AGENT_ENDPOINT_SOCKET_BINDING_XML;
+ protected static final String ATTRIB_AGENT_TRANSPORT = ServiceContainerConfigurationConstants.CONNECTOR_TRANSPORT;
+ protected static final String ATTRIB_AGENT_TRANSPORT_PARAMS = ServiceContainerConfigurationConstants.CONNECTOR_TRANSPORT_PARAMS;
protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+
static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) {
String prefix = SUBSYSTEM_NAME + (keyPrefix == null ? "" : "." + keyPrefix);
return new StandardResourceDescriptionResolver(prefix, RESOURCE_NAME,
@@ -118,22 +131,44 @@ public class AgentSubsystemExtension implements Extension {
readPlugin(reader, pluginsAttributeNode);
}
}
+ } else if (elementName.equals(SERVER_ENDPOINT_ELEMENT)) {
+ String val = reader.getAttributeValue(null, SERVER_ENDPOINT_ADDRESS_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SERVER_BIND_ADDRESS).set(val);
+ }
+ val = reader.getAttributeValue(null, SERVER_ENDPOINT_PORT_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SERVER_BIND_PORT).set(val);
+ }
+ val = reader.getAttributeValue(null, SERVER_ENDPOINT_TRANSPORT_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SERVER_TRANSPORT).set(val);
+ }
+ val = reader.getAttributeValue(null, SERVER_ENDPOINT_TRANSPORT_PARAMS_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SERVER_TRANSPORT_PARAMS).set(val);
+ }
+ ParseUtils.requireNoContent(reader);
+ } else if (elementName.equals(AGENT_ENDPOINT_ELEMENT)) {
+ String val = reader.getAttributeValue(null, AGENT_ENDPOINT_SOCKET_BINDING_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SOCKET_BINDING).set(val);
+ }
+ val = reader.getAttributeValue(null, AGENT_ENDPOINT_TRANSPORT_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_AGENT_TRANSPORT).set(val);
+ }
+ val = reader.getAttributeValue(null, AGENT_ENDPOINT_TRANSPORT_PARAMS_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_AGENT_TRANSPORT_PARAMS).set(val);
+ }
+ ParseUtils.requireNoContent(reader);
} else if (elementName.equals(ATTRIB_AGENT_NAME)) {
opAdd.get(ATTRIB_AGENT_NAME).set(reader.getElementText());
} else if (elementName.equals(ATTRIB_DISABLE_NATIVE)) {
opAdd.get(ATTRIB_DISABLE_NATIVE).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SERVER_TRANSPORT)) {
- opAdd.get(ATTRIB_SERVER_TRANSPORT).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SERVER_BIND_PORT)) {
- opAdd.get(ATTRIB_SERVER_BIND_PORT).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SERVER_BIND_ADDRESS)) {
- opAdd.get(ATTRIB_SERVER_BIND_ADDRESS).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SERVER_TRANSPORT_PARAMS)) {
- opAdd.get(ATTRIB_SERVER_TRANSPORT_PARAMS).set(reader.getElementText());
} else if (elementName.equals(ATTRIB_SERVER_ALIAS)) {
opAdd.get(ATTRIB_SERVER_ALIAS).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SOCKET_BINDING)) {
- opAdd.get(ATTRIB_SOCKET_BINDING).set(reader.getElementText());
} else {
throw ParseUtils.unexpectedElement(reader);
}
@@ -184,12 +219,47 @@ public class AgentSubsystemExtension implements Extension {
// our config elements
writeElement(writer, node, ATTRIB_AGENT_NAME);
writeElement(writer, node, ATTRIB_DISABLE_NATIVE);
- writeElement(writer, node, ATTRIB_SERVER_TRANSPORT);
- writeElement(writer, node, ATTRIB_SERVER_BIND_PORT);
- writeElement(writer, node, ATTRIB_SERVER_BIND_ADDRESS);
- writeElement(writer, node, ATTRIB_SERVER_TRANSPORT_PARAMS);
writeElement(writer, node, ATTRIB_SERVER_ALIAS);
- writeElement(writer, node, ATTRIB_SOCKET_BINDING);
+
+ // <server-endpoint>
+ writer.writeStartElement(SERVER_ENDPOINT_ELEMENT);
+ ModelNode serverAddressNode = node.get(ATTRIB_SERVER_BIND_ADDRESS);
+ ModelNode serverPortNode = node.get(ATTRIB_SERVER_BIND_PORT);
+ ModelNode serverTransportNode = node.get(ATTRIB_SERVER_TRANSPORT);
+ ModelNode serverTransportParamsNode = node.get(ATTRIB_SERVER_TRANSPORT_PARAMS);
+
+ if (serverPortNode.isDefined()) {
+ writer.writeAttribute(SERVER_ENDPOINT_PORT_XML, serverPortNode.asString());
+ }
+ if (serverAddressNode.isDefined()) {
+ writer.writeAttribute(SERVER_ENDPOINT_ADDRESS_XML, serverAddressNode.asString());
+ }
+ if (serverTransportNode.isDefined()) {
+ writer.writeAttribute(SERVER_ENDPOINT_TRANSPORT_XML, serverTransportNode.asString());
+ }
+ if (serverTransportParamsNode.isDefined()) {
+ writer.writeAttribute(SERVER_ENDPOINT_TRANSPORT_PARAMS_XML, serverTransportParamsNode.asString());
+ }
+ // </server-endpoint>
+ writer.writeEndElement();
+
+ // <agent-endpoint>
+ writer.writeStartElement(AGENT_ENDPOINT_ELEMENT);
+ ModelNode agentSocketBindingNode = node.get(ATTRIB_SOCKET_BINDING);
+ ModelNode agentTransportNode = node.get(ATTRIB_AGENT_TRANSPORT);
+ ModelNode agentTransportParamsNode = node.get(ATTRIB_AGENT_TRANSPORT_PARAMS);
+
+ if (agentSocketBindingNode.isDefined()) {
+ writer.writeAttribute(AGENT_ENDPOINT_SOCKET_BINDING_XML, agentSocketBindingNode.asString());
+ }
+ if (agentTransportNode.isDefined()) {
+ writer.writeAttribute(AGENT_ENDPOINT_TRANSPORT_XML, agentTransportNode.asString());
+ }
+ if (agentTransportParamsNode.isDefined()) {
+ writer.writeAttribute(AGENT_ENDPOINT_TRANSPORT_PARAMS_XML, agentTransportParamsNode.asString());
+ }
+ // </agent-endpoint>
+ writer.writeEndElement();
// <plugins>
writer.writeStartElement(PLUGINS_ELEMENT);
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
index e2badfc..680f9f2 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
@@ -7,6 +7,8 @@ embeddedagent.status=Tells you if the RHQ Agent is currently started or stopped.
embeddedagent.enabled=When true, the RHQ Agent will be deployed and started. Otherwise, it will be disabled.
embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
embeddedagent.socket-binding=Determines the binding address and port the agent listens to for incoming server messages.
+embeddedagent.rhq.communications.connector.transport=The transport server must use to communicate with the agent.
+embeddedagent.rhq.communications.connector.transport-params=The transport parameters the server must use to communicate with the agent.
embeddedagent.rhq.agent.name=Name to uniquely identify this agent among all other agents in the environment
embeddedagent.rhq.agent.disable-native-system=The RHQ Agent has a native system on certain supported platforms to help the \n\
plugin container perform discovery of native components on those platforms. \n\
@@ -20,4 +22,4 @@ alias (see rhq.agent.server.alias), and if that is not defined \n\
the RHQ Agent will default to localhost or 127.0.0.1.
embeddedagent.rhq.agent.server.transport-params=Communications transport parameters used when sending messages to the RHQ Server.
embeddedagent.rhq.agent.server.alias=If the server address is not defined, this is the DNS alias name the \n\
-RHQ Agent will resolve and use for the server address.
+RHQ Agent will resolve and use for the server address.
\ No newline at end of file
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
index d587e23..a116308 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
@@ -11,17 +11,27 @@
<xs:attribute name="enabled" type="xs:boolean" use="required" default="false"/>
<xs:all>
<xs:element name="rhq.agent.name" type="xs:string"/>
- <xs:element name="rhq.agent.disable-native-system" type="xs:boolean" use="optional"/>
- <xs:element name="rhq.agent.server.transport" type="xs:string"/>
- <xs:element name="rhq.agent.server.bind-port" type="xs:integer"/>
- <xs:element name="rhq.agent.server.bind-address" type="xs:string" use="optional"/>
- <xs:element name="rhq.agent.server.transport-params" type="xs:string" />
- <xs:element name="rhq.agent.server.alias" type="xs:string" use="optional"/>
- <xs:element name="socket-binding" type="xs:string"/>
+ <xs:element name="rhq.agent.disable-native-system" type="xs:boolean"/>
+ <xs:element name="rhq.agent.server.alias" type="xs:string"/>
+ <xs:element name="server-endpoint" type="serverEndpointType"/>
+ <xs:element name="agent-endpoint" type="agentEndpointType"/>
<xs:element name="plugins" type="pluginsType"/>
</xs:all>
</xs:complexType>
+ <xs:complexType name="serverEndpointType">
+ <xs:attribute name="address"/>
+ <xs:attribute name="port" type="xs:integer"/>
+ <xs:attribute name="transport"/>
+ <xs:attribute name="transport-params"/>
+ </xs:complexType>
+
+ <xs:complexType name="agentEndpointType">
+ <xs:attribute name="socket-binding"/>
+ <xs:attribute name="transport"/>
+ <xs:attribute name="transport-params"/>
+ </xs:complexType>
+
<xs:complexType name="pluginsType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="plugin" type="pluginType"/>
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
index 0f3a8fa..b6126a0 100644
--- a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -198,6 +198,8 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
List<Property> attributes = content.get("attributes").asPropertyList();
List<String> expectedAttributes = Arrays.asList( //
+ AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT_PARAMS, //
+ AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT, //
AgentSubsystemExtension.ATTRIB_SOCKET_BINDING, //
AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, //
AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT, //
diff --git a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
index 09da3f6..d4ea3c8 100644
--- a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
+++ b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
@@ -1,13 +1,10 @@
<subsystem xmlns="urn:org.rhq:embeddedagent:1.0" enabled="true">
<rhq.agent.name>embeddedagent-test</rhq.agent.name>
<!-- <rhq.agent.disable-native-system>true</rhq.agent.disable-native-system> -->
- <rhq.agent.server.transport>test-transport</rhq.agent.server.transport>
- <rhq.agent.server.bind-port>12345</rhq.agent.server.bind-port>
- <!-- <rhq.agent.server.bind-address>test-bind-address</rhq.agent.server.bind-address> -->
- <rhq.agent.server.transport-params>test-transport-params</rhq.agent.server.transport-params>
<!-- <rhq.agent.server.alias>test-alias</rhq.agent.server.alias> -->
- <socket-binding>embeddedagent</socket-binding>
+ <server-endpoint port="7080" transport="test-transport" transport-params="test-transport-params" />
+ <agent-endpoint socket-binding="embeddedagent" transport="socket"/>
<plugins>
<plugin name="platform" enabled="true" />
commit 5e171db86ceaa8ff1bc461c2f7b77bc3c12fc833
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Feb 3 13:43:15 2014 -0500
add ability to define agent binding addr/port in EAP config xml
diff --git a/.classpath b/.classpath
index 455f739..4916f67 100644
--- a/.classpath
+++ b/.classpath
@@ -334,9 +334,11 @@
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-ejb3/7.2.0.Alpha1-redhat-4/jboss-as-ejb3-7.2.0.Alpha1-redhat-4.jar" sourcepath="/M2_REPO/org/jboss/as/jboss-as-ejb3/7.2.0.Alpha1-redhat-4/jboss-as-ejb3-7.2.0.Alpha1-redhat-4-sources.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/staxmapper/1.1.0.Final/staxmapper-1.1.0.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/modules/jboss-modules/1.1.1.GA/jboss-modules-1.1.1.GA.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-subsystem-test/7.1.1.Final/jboss-as-subsystem-test-7.1.1.Final.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-controller/7.1.1.Final/jboss-as-controller-7.1.1.Final.jar" sourcepath="/M2_REPO/org/jboss/as/jboss-as-controller/7.2.0.Alpha1-redhat-4/jboss-as-controller-7.2.0.Alpha1-redhat-4-sources.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-controller-client/7.1.1.Final/jboss-as-controller-client-7.1.1.Final.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-subsystem-test/7.2.0.Alpha1-redhat-4/jboss-as-subsystem-test-7.2.0.Alpha1-redhat-4.jar" sourcepath="/M2_REPO/org/jboss/as/jboss-as-subsystem-test/7.2.0.Alpha1-redhat-4/jboss-as-subsystem-test-7.2.0.Alpha1-redhat-4-sources.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-controller/7.2.0.Alpha1-redhat-4/jboss-as-controller-7.2.0.Alpha1-redhat-4.jar" sourcepath="/M2_REPO/org/jboss/as/jboss-as-controller/7.2.0.Alpha1-redhat-4/jboss-as-controller-7.2.0.Alpha1-redhat-4-sources.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-controller-client/7.2.0.Alpha1-redhat-4/jboss-as-controller-client-7.2.0.Alpha1-redhat-4.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-model-test/7.2.0.Alpha1-redhat-4/jboss-as-model-test-7.2.0.Alpha1-redhat-4.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-network/7.2.0.Alpha1-redhat-4/jboss-as-network-7.2.0.Alpha1-redhat-4.jar" sourcepath="/M2_REPO/org/jboss/as/jboss-as-network/7.2.0.Alpha1-redhat-4/jboss-as-network-7.2.0.Alpha1-redhat-4-sources.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/resteasy/resteasy-links/2.3.5.Final/resteasy-links-2.3.5.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/resteasy/resteasy-jaxrs/2.3.5.Final/resteasy-jaxrs-2.3.5.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/resteasy/resteasy-jackson-provider/2.3.5.Final/resteasy-jackson-provider-2.3.5.Final.jar"/>
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
index 018519d..651f557 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
@@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
+import org.jboss.as.network.SocketBinding;
import org.jboss.as.server.ServerEnvironment;
import org.jboss.logging.Logger;
import org.jboss.modules.Module;
@@ -18,6 +19,7 @@ import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;
import org.rhq.enterprise.agent.AgentMain;
+import org.rhq.enterprise.communications.ServiceContainerConfigurationConstants;
public class AgentService implements Service<AgentService> {
@@ -31,7 +33,13 @@ public class AgentService implements Service<AgentService> {
* This service gives us information about the server, like the install directory, data directory, etc.
* Package-scoped so the add-step handler can access this.
*/
- InjectedValue<ServerEnvironment> envServiceValue = new InjectedValue<ServerEnvironment>();
+ final InjectedValue<ServerEnvironment> envServiceValue = new InjectedValue<ServerEnvironment>();
+
+ /**
+ * Our subsystem add-step handler will inject this as a dependency for us.
+ * This object will provide the binding address and port for the agent listener.
+ */
+ final InjectedValue<SocketBinding> agentListenerBinding = new InjectedValue<SocketBinding>();
/**
* This service can be configured to be told explicitly about certain plugins to be
@@ -131,10 +139,17 @@ public class AgentService implements Service<AgentService> {
log.info("Starting the embedded agent now");
try {
// make sure we pre-configure the agent with some settings taken from our runtime environment
+ SocketBinding agentListenerBindingValue = agentListenerBinding.getValue();
+ String agentBindAddress = agentListenerBindingValue.getAddress().getHostAddress();
+ String agentBindPort = String.valueOf(agentListenerBindingValue.getAbsolutePort());
+ configOverrides.put(ServiceContainerConfigurationConstants.CONNECTOR_BIND_ADDRESS, agentBindAddress);
+ configOverrides.put(ServiceContainerConfigurationConstants.CONNECTOR_BIND_PORT, agentBindPort);
+
ServerEnvironment env = envServiceValue.getValue();
boolean resetConfigurationAtStartup = true;
AgentConfigurationSetup configSetup = new AgentConfigurationSetup(
getExportedResource("conf/agent-configuration.xml"), resetConfigurationAtStartup, configOverrides, env);
+
// prepare the agent logging first thing so the agent logs messages using this config
configSetup.prepareLogConfigFile(getExportedResource("conf/log4j.xml"));
configSetup.preConfigureAgent();
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
index c2cc801..937af70 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -9,6 +9,7 @@ import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.ServiceVerificationHandler;
+import org.jboss.as.network.SocketBinding;
import org.jboss.as.server.ServerEnvironment;
import org.jboss.as.server.ServerEnvironmentService;
import org.jboss.dmr.ModelNode;
@@ -41,6 +42,7 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
AgentSubsystemDefinition.SERVER_BIND_ADDRESS_ATTRIBDEF.validateAndSet(operation, model);
AgentSubsystemDefinition.SERVER_TRANSPORT_PARAMS_ATTRIBDEF.validateAndSet(operation, model);
AgentSubsystemDefinition.SERVER_ALIAS_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.SOCKET_BINDING_ATTRIBDEF.validateAndSet(operation, model);
log.info("Populating the embedded agent subsystem model: " + operation + "=" + model);
}
@@ -87,10 +89,14 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
service.setConfigurationOverrides(overrides);
// install the service
+ String binding = AgentSubsystemDefinition.SOCKET_BINDING_ATTRIBDEF.resolveModelAttribute(context, model)
+ .asString();
ServiceName name = AgentService.SERVICE_NAME;
ServiceController<AgentService> controller = context.getServiceTarget() //
.addService(name, service) //
.addDependency(ServerEnvironmentService.SERVICE_NAME, ServerEnvironment.class, service.envServiceValue) //
+ .addDependency(SocketBinding.JBOSS_BINDING_NAME.append(binding), SocketBinding.class,
+ service.agentListenerBinding) //
.addListener(verificationHandler) //
.setInitialMode(Mode.ACTIVE) //
.install();
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
index dec1a26..ad50c4e 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
@@ -9,6 +9,7 @@ import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.descriptions.DefaultOperationDescriptionProvider;
import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.operations.validation.StringLengthValidator;
import org.jboss.as.controller.registry.AttributeAccess;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.registry.OperationEntry;
@@ -69,6 +70,12 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
.setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_ALIAS)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
+ protected static final SimpleAttributeDefinition SOCKET_BINDING_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SOCKET_BINDING, ModelType.STRING)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode("embeddedagent")).setValidator(new StringLengthValidator(1)).setAllowNull(false)
+ .build();
+
private AgentSubsystemDefinition() {
super(AgentSubsystemExtension.SUBSYSTEM_PATH, AgentSubsystemExtension.getResourceDescriptionResolver(null),
AgentSubsystemAdd.INSTANCE, AgentSubsystemRemove.INSTANCE);
@@ -85,6 +92,7 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
registerReloadRequiredWriteAttributeHandler(rr, SERVER_BIND_ADDRESS_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, SERVER_TRANSPORT_PARAMS_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, SERVER_ALIAS_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, SOCKET_BINDING_ATTRIBDEF);
}
private void registerReloadRequiredWriteAttributeHandler(ManagementResourceRegistration rr, AttributeDefinition def) {
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
index a74bafb..4374c7e 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
@@ -62,11 +62,10 @@ public class AgentSubsystemExtension implements Extension {
protected static final String ATTRIB_SERVER_BIND_ADDRESS = AgentConfigurationConstants.SERVER_BIND_ADDRESS;
protected static final String ATTRIB_SERVER_TRANSPORT_PARAMS = AgentConfigurationConstants.SERVER_TRANSPORT_PARAMS;
protected static final String ATTRIB_SERVER_ALIAS = AgentConfigurationConstants.SERVER_ALIAS;
+ protected static final String ATTRIB_SOCKET_BINDING = "socket-binding";
protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
-
-
static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) {
String prefix = SUBSYSTEM_NAME + (keyPrefix == null ? "" : "." + keyPrefix);
return new StandardResourceDescriptionResolver(prefix, RESOURCE_NAME,
@@ -133,6 +132,8 @@ public class AgentSubsystemExtension implements Extension {
opAdd.get(ATTRIB_SERVER_TRANSPORT_PARAMS).set(reader.getElementText());
} else if (elementName.equals(ATTRIB_SERVER_ALIAS)) {
opAdd.get(ATTRIB_SERVER_ALIAS).set(reader.getElementText());
+ } else if (elementName.equals(ATTRIB_SOCKET_BINDING)) {
+ opAdd.get(ATTRIB_SOCKET_BINDING).set(reader.getElementText());
} else {
throw ParseUtils.unexpectedElement(reader);
}
@@ -188,6 +189,7 @@ public class AgentSubsystemExtension implements Extension {
writeElement(writer, node, ATTRIB_SERVER_BIND_ADDRESS);
writeElement(writer, node, ATTRIB_SERVER_TRANSPORT_PARAMS);
writeElement(writer, node, ATTRIB_SERVER_ALIAS);
+ writeElement(writer, node, ATTRIB_SOCKET_BINDING);
// <plugins>
writer.writeStartElement(PLUGINS_ELEMENT);
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
index 56419c3..faa971f 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
@@ -48,5 +48,8 @@
<!-- the standalone agent had this in its endorsed dir, but the embedded agent adds it as a dependency -->
<module name="javax.xml.bind.api"/>
+
+ <!-- other dependencies we need -->
+ <module name="org.jboss.as.network"/>
</dependencies>
</module>
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
index 80ea9e5..e2badfc 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
@@ -6,6 +6,7 @@ embeddedagent.stop=Stops the RHQ Agent if it is running.
embeddedagent.status=Tells you if the RHQ Agent is currently started or stopped.
embeddedagent.enabled=When true, the RHQ Agent will be deployed and started. Otherwise, it will be disabled.
embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
+embeddedagent.socket-binding=Determines the binding address and port the agent listens to for incoming server messages.
embeddedagent.rhq.agent.name=Name to uniquely identify this agent among all other agents in the environment
embeddedagent.rhq.agent.disable-native-system=The RHQ Agent has a native system on certain supported platforms to help the \n\
plugin container perform discovery of native components on those platforms. \n\
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
index b9a3689..d587e23 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
@@ -17,6 +17,7 @@
<xs:element name="rhq.agent.server.bind-address" type="xs:string" use="optional"/>
<xs:element name="rhq.agent.server.transport-params" type="xs:string" />
<xs:element name="rhq.agent.server.alias" type="xs:string" use="optional"/>
+ <xs:element name="socket-binding" type="xs:string"/>
<xs:element name="plugins" type="pluginsType"/>
</xs:all>
</xs:complexType>
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
index 0a8758f..0f3a8fa 100644
--- a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -198,6 +198,7 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
List<Property> attributes = content.get("attributes").asPropertyList();
List<String> expectedAttributes = Arrays.asList( //
+ AgentSubsystemExtension.ATTRIB_SOCKET_BINDING, //
AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, //
AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT, //
AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS, //
diff --git a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
index e8641f1..09da3f6 100644
--- a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
+++ b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
@@ -7,6 +7,8 @@
<rhq.agent.server.transport-params>test-transport-params</rhq.agent.server.transport-params>
<!-- <rhq.agent.server.alias>test-alias</rhq.agent.server.alias> -->
+ <socket-binding>embeddedagent</socket-binding>
+
<plugins>
<plugin name="platform" enabled="true" />
<plugin name="blah" enabled="false" />
commit b32406efb7d8a77de7eca42eb506b1e25347825f
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Jan 31 11:58:00 2014 -0500
add more embedded agent config settings - server endpoint details and the ability to disable native system (sigar)
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
index 4867ef7..c2cc801 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map;
import org.jboss.as.controller.AbstractAddStepHandler;
+import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.ServiceVerificationHandler;
@@ -17,8 +18,6 @@ import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceController.Mode;
import org.jboss.msc.service.ServiceName;
-import org.rhq.enterprise.agent.AgentConfigurationConstants;
-
/**
* Handler responsible for adding the subsystem resource to the model
*/
@@ -35,7 +34,13 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
AgentSubsystemDefinition.AGENT_ENABLED_ATTRIBDEF.validateAndSet(operation, model);
AgentSubsystemDefinition.PLUGINS_ATTRIBDEF.validateAndSet(operation, model);
- AgentSubsystemDefinition.PREF_AGENT_NAME_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.AGENT_NAME_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.DISABLE_NATIVE_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.SERVER_TRANSPORT_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.SERVER_BIND_PORT_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.SERVER_BIND_ADDRESS_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.SERVER_TRANSPORT_PARAMS_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.SERVER_ALIAS_ATTRIBDEF.validateAndSet(operation, model);
log.info("Populating the embedded agent subsystem model: " + operation + "=" + model);
}
@@ -68,11 +73,13 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
// set up our runtime configuration overrides that should be used instead of the out-of-box config
Map<String, String> overrides = new HashMap<String, String>();
- ModelNode agentNameNode = AgentSubsystemDefinition.PREF_AGENT_NAME_ATTRIBDEF.resolveModelAttribute(context,
- model);
- if (agentNameNode.isDefined()) {
- overrides.put(AgentConfigurationConstants.NAME, agentNameNode.asString());
- }
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_NAME_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.DISABLE_NATIVE_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_TRANSPORT_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_BIND_PORT_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_BIND_ADDRESS_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_TRANSPORT_PARAMS_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_ALIAS_ATTRIBDEF);
// create our service
AgentService service = new AgentService();
@@ -90,4 +97,13 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
newControllers.add(controller);
return;
}
+
+ private void addOverrideProperty(OperationContext context, ModelNode model, Map<String, String> overrides,
+ AttributeDefinition attribDef)
+ throws OperationFailedException {
+ ModelNode node = attribDef.resolveModelAttribute(context, model);
+ if (node.isDefined()) {
+ overrides.put(attribDef.getName(), node.asString());
+ }
+ }
}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
index 0dffb92..dec1a26 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
@@ -2,6 +2,7 @@ package org.rhq.embeddedagent.extension;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIBE;
+import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.ReloadRequiredWriteAttributeHandler;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
@@ -14,6 +15,8 @@ import org.jboss.as.controller.registry.OperationEntry;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
+import org.rhq.enterprise.agent.AgentConfigurationConstants;
+
public class AgentSubsystemDefinition extends SimpleResourceDefinition {
public static final AgentSubsystemDefinition INSTANCE = new AgentSubsystemDefinition();
@@ -23,12 +26,48 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
.setXmlName(AgentSubsystemExtension.AGENT_ENABLED).setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setDefaultValue(new ModelNode(AgentSubsystemExtension.AGENT_ENABLED_DEFAULT)).setAllowNull(false).build();
- protected static final SimpleAttributeDefinition PREF_AGENT_NAME_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ protected static final PluginsAttributeDefinition PLUGINS_ATTRIBDEF = new PluginsAttributeDefinition();
+
+ protected static final SimpleAttributeDefinition AGENT_NAME_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_AGENT_NAME, ModelType.STRING).setAllowExpression(true)
.setXmlName(AgentSubsystemExtension.ATTRIB_AGENT_NAME).setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setAllowNull(true).build();
- protected static final PluginsAttributeDefinition PLUGINS_ATTRIBDEF = new PluginsAttributeDefinition();
+ protected static final SimpleAttributeDefinition DISABLE_NATIVE_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_DISABLE_NATIVE, ModelType.BOOLEAN).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.ATTRIB_DISABLE_NATIVE)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
+
+ protected static final SimpleAttributeDefinition SERVER_TRANSPORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_TRANSPORT)).setAllowNull(false)
+ .build();
+
+ protected static final SimpleAttributeDefinition SERVER_BIND_PORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_BIND_PORT)).setAllowNull(false)
+ .build();
+
+ protected static final SimpleAttributeDefinition SERVER_BIND_ADDRESS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
+
+ protected static final SimpleAttributeDefinition SERVER_TRANSPORT_PARAMS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT_PARAMS, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT_PARAMS)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_TRANSPORT_PARAMS))
+ .setAllowNull(false).build();
+
+ protected static final SimpleAttributeDefinition SERVER_ALIAS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_ALIAS, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_ALIAS)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
private AgentSubsystemDefinition() {
super(AgentSubsystemExtension.SUBSYSTEM_PATH, AgentSubsystemExtension.getResourceDescriptionResolver(null),
@@ -39,8 +78,17 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
public void registerAttributes(ManagementResourceRegistration rr) {
rr.registerReadWriteAttribute(AGENT_ENABLED_ATTRIBDEF, null, AgentEnabledAttributeHandler.INSTANCE);
rr.registerReadWriteAttribute(PLUGINS_ATTRIBDEF, null, PluginsAttributeHandler.INSTANCE);
- rr.registerReadWriteAttribute(PREF_AGENT_NAME_ATTRIBDEF, null, new ReloadRequiredWriteAttributeHandler(
- PREF_AGENT_NAME_ATTRIBDEF));
+ registerReloadRequiredWriteAttributeHandler(rr, AGENT_NAME_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, DISABLE_NATIVE_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, SERVER_TRANSPORT_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, SERVER_BIND_PORT_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, SERVER_BIND_ADDRESS_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, SERVER_TRANSPORT_PARAMS_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, SERVER_ALIAS_ATTRIBDEF);
+ }
+
+ private void registerReloadRequiredWriteAttributeHandler(ManagementResourceRegistration rr, AttributeDefinition def) {
+ rr.registerReadWriteAttribute(def, null, new ReloadRequiredWriteAttributeHandler(def));
}
@Override
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
index 37ec585..a74bafb 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
@@ -56,9 +56,17 @@ public class AgentSubsystemExtension implements Extension {
protected static final String AGENT_STATUS_OP = "status";
protected static final String ATTRIB_AGENT_NAME = AgentConfigurationConstants.NAME;
+ protected static final String ATTRIB_DISABLE_NATIVE = AgentConfigurationConstants.DISABLE_NATIVE_SYSTEM;
+ protected static final String ATTRIB_SERVER_TRANSPORT = AgentConfigurationConstants.SERVER_TRANSPORT;
+ protected static final String ATTRIB_SERVER_BIND_PORT = AgentConfigurationConstants.SERVER_BIND_PORT;
+ protected static final String ATTRIB_SERVER_BIND_ADDRESS = AgentConfigurationConstants.SERVER_BIND_ADDRESS;
+ protected static final String ATTRIB_SERVER_TRANSPORT_PARAMS = AgentConfigurationConstants.SERVER_TRANSPORT_PARAMS;
+ protected static final String ATTRIB_SERVER_ALIAS = AgentConfigurationConstants.SERVER_ALIAS;
protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+
+
static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) {
String prefix = SUBSYSTEM_NAME + (keyPrefix == null ? "" : "." + keyPrefix);
return new StandardResourceDescriptionResolver(prefix, RESOURCE_NAME,
@@ -113,6 +121,18 @@ public class AgentSubsystemExtension implements Extension {
}
} else if (elementName.equals(ATTRIB_AGENT_NAME)) {
opAdd.get(ATTRIB_AGENT_NAME).set(reader.getElementText());
+ } else if (elementName.equals(ATTRIB_DISABLE_NATIVE)) {
+ opAdd.get(ATTRIB_DISABLE_NATIVE).set(reader.getElementText());
+ } else if (elementName.equals(ATTRIB_SERVER_TRANSPORT)) {
+ opAdd.get(ATTRIB_SERVER_TRANSPORT).set(reader.getElementText());
+ } else if (elementName.equals(ATTRIB_SERVER_BIND_PORT)) {
+ opAdd.get(ATTRIB_SERVER_BIND_PORT).set(reader.getElementText());
+ } else if (elementName.equals(ATTRIB_SERVER_BIND_ADDRESS)) {
+ opAdd.get(ATTRIB_SERVER_BIND_ADDRESS).set(reader.getElementText());
+ } else if (elementName.equals(ATTRIB_SERVER_TRANSPORT_PARAMS)) {
+ opAdd.get(ATTRIB_SERVER_TRANSPORT_PARAMS).set(reader.getElementText());
+ } else if (elementName.equals(ATTRIB_SERVER_ALIAS)) {
+ opAdd.get(ATTRIB_SERVER_ALIAS).set(reader.getElementText());
} else {
throw ParseUtils.unexpectedElement(reader);
}
@@ -160,9 +180,14 @@ public class AgentSubsystemExtension implements Extension {
writer.writeAttribute(AGENT_ENABLED,
String.valueOf(node.get(AGENT_ENABLED).asBoolean(AGENT_ENABLED_DEFAULT)));
- writer.writeStartElement(ATTRIB_AGENT_NAME);
- writer.writeCharacters(node.get(ATTRIB_AGENT_NAME).asString());
- writer.writeEndElement();
+ // our config elements
+ writeElement(writer, node, ATTRIB_AGENT_NAME);
+ writeElement(writer, node, ATTRIB_DISABLE_NATIVE);
+ writeElement(writer, node, ATTRIB_SERVER_TRANSPORT);
+ writeElement(writer, node, ATTRIB_SERVER_BIND_PORT);
+ writeElement(writer, node, ATTRIB_SERVER_BIND_ADDRESS);
+ writeElement(writer, node, ATTRIB_SERVER_TRANSPORT_PARAMS);
+ writeElement(writer, node, ATTRIB_SERVER_ALIAS);
// <plugins>
writer.writeStartElement(PLUGINS_ELEMENT);
@@ -182,5 +207,15 @@ public class AgentSubsystemExtension implements Extension {
// </subsystem>
writer.writeEndElement();
}
+
+ private void writeElement(final XMLExtendedStreamWriter writer, ModelNode node, String attribName)
+ throws XMLStreamException {
+ ModelNode attribNode = node.get(attribName);
+ if (attribNode.isDefined()) {
+ writer.writeStartElement(attribName);
+ writer.writeCharacters(attribNode.asString());
+ writer.writeEndElement();
+ }
+ }
}
}
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
index 05bcfce..80ea9e5 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
@@ -6,4 +6,17 @@ embeddedagent.stop=Stops the RHQ Agent if it is running.
embeddedagent.status=Tells you if the RHQ Agent is currently started or stopped.
embeddedagent.enabled=When true, the RHQ Agent will be deployed and started. Otherwise, it will be disabled.
embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
-embeddedagent.rhq.agent.name=Name to uniquely identify this agent among all other agents in the environment
\ No newline at end of file
+embeddedagent.rhq.agent.name=Name to uniquely identify this agent among all other agents in the environment
+embeddedagent.rhq.agent.disable-native-system=The RHQ Agent has a native system on certain supported platforms to help the \n\
+plugin container perform discovery of native components on those platforms. \n\
+If the native libraries are causing errors within the agent, \n\
+you can disable this native system by setting this to true.
+embeddedagent.rhq.agent.server.transport=The communication transport used to send messages to the RHQ Server
+embeddedagent.rhq.agent.server.bind-port=The port the RHQ Server is listening to for messages
+embeddedagent.rhq.agent.server.bind-address=The address the RHQ Server is listening to for messages. \n\
+If not defined, the RHQ Agent will default to the DNS \n\
+alias (see rhq.agent.server.alias), and if that is not defined \n\
+the RHQ Agent will default to localhost or 127.0.0.1.
+embeddedagent.rhq.agent.server.transport-params=Communications transport parameters used when sending messages to the RHQ Server.
+embeddedagent.rhq.agent.server.alias=If the server address is not defined, this is the DNS alias name the \n\
+RHQ Agent will resolve and use for the server address.
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
index 3e0c546..b9a3689 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
@@ -11,6 +11,12 @@
<xs:attribute name="enabled" type="xs:boolean" use="required" default="false"/>
<xs:all>
<xs:element name="rhq.agent.name" type="xs:string"/>
+ <xs:element name="rhq.agent.disable-native-system" type="xs:boolean" use="optional"/>
+ <xs:element name="rhq.agent.server.transport" type="xs:string"/>
+ <xs:element name="rhq.agent.server.bind-port" type="xs:integer"/>
+ <xs:element name="rhq.agent.server.bind-address" type="xs:string" use="optional"/>
+ <xs:element name="rhq.agent.server.transport-params" type="xs:string" />
+ <xs:element name="rhq.agent.server.alias" type="xs:string" use="optional"/>
<xs:element name="plugins" type="pluginsType"/>
</xs:all>
</xs:complexType>
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
index e857af4..0a8758f 100644
--- a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -196,12 +196,18 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
// check the attributes
Assert.assertTrue(content.get("attributes").isDefined());
List<Property> attributes = content.get("attributes").asPropertyList();
- Assert.assertEquals(attributes.size(), 3);
List<String> expectedAttributes = Arrays.asList( //
+ AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, //
+ AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT, //
+ AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS, //
+ AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT_PARAMS, //
+ AgentSubsystemExtension.ATTRIB_SERVER_ALIAS, //
+ AgentSubsystemExtension.ATTRIB_DISABLE_NATIVE, //
+ AgentSubsystemExtension.ATTRIB_AGENT_NAME, //
AgentSubsystemExtension.AGENT_ENABLED, //
- AgentSubsystemExtension.PLUGINS_ELEMENT, //
- AgentSubsystemExtension.ATTRIB_AGENT_NAME);
+ AgentSubsystemExtension.PLUGINS_ELEMENT);
+ Assert.assertEquals(attributes.size(), expectedAttributes.size());
for (int i = 0 ; i < attributes.size(); i++) {
String attrib = attributes.get(i).getName();
diff --git a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
index 8d60c99..e8641f1 100644
--- a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
+++ b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
@@ -1,5 +1,12 @@
<subsystem xmlns="urn:org.rhq:embeddedagent:1.0" enabled="true">
<rhq.agent.name>embeddedagent-test</rhq.agent.name>
+ <!-- <rhq.agent.disable-native-system>true</rhq.agent.disable-native-system> -->
+ <rhq.agent.server.transport>test-transport</rhq.agent.server.transport>
+ <rhq.agent.server.bind-port>12345</rhq.agent.server.bind-port>
+ <!-- <rhq.agent.server.bind-address>test-bind-address</rhq.agent.server.bind-address> -->
+ <rhq.agent.server.transport-params>test-transport-params</rhq.agent.server.transport-params>
+ <!-- <rhq.agent.server.alias>test-alias</rhq.agent.server.alias> -->
+
<plugins>
<plugin name="platform" enabled="true" />
<plugin name="blah" enabled="false" />
commit 8620d3dcb4e81c37dba84d97be0a779686b8d2d1
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Jan 31 01:08:04 2014 -0500
starting to add config overrides to the extension subsystem - first one is the agent name (we can now set the agent name in the config)
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java
index 24c3d2d..7b654fc 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java
@@ -38,7 +38,7 @@ public class AgentConfigurationSetup {
* Properties that will be used to override preferences found in the preferences node and the configuration
* preferences file.
*/
- private final Properties configurationOverrides;
+ private final Map<String, String> configurationOverrides;
/**
* If <code>true</code>, will revert the agent's configuration back to the original configuration file.
@@ -57,14 +57,14 @@ public class AgentConfigurationSetup {
private final ServerEnvironment serverEnvironment;
public AgentConfigurationSetup(Resource configFile, boolean resetConfigurationAtStartup,
- Properties configurationOverrides, ServerEnvironment serverEnv) {
+ Map<String, String> overrides, ServerEnvironment serverEnv) {
this.configFile = configFile;
this.resetConfigurationAtStartup = resetConfigurationAtStartup;
this.serverEnvironment = serverEnv;
- this.configurationOverrides = prepareConfigurationOverrides(configurationOverrides);
+ this.configurationOverrides = prepareConfigurationOverrides(overrides);
- String agentName = configurationOverrides.getProperty(AgentConfigurationConstants.NAME, "embeddedagent");
+ String agentName = this.configurationOverrides.get(AgentConfigurationConstants.NAME);
preferencesNodeName = agentName;
System.setProperty("rhq.agent.preferences-node", preferencesNodeName);
}
@@ -73,13 +73,12 @@ public class AgentConfigurationSetup {
return this.preferencesNodeName;
}
- private Properties prepareConfigurationOverrides(Properties overrides) {
+ private Map<String, String> prepareConfigurationOverrides(Map<String, String> overrides) {
// perform some checking to setup defaults if need be
- String agentName = overrides.getProperty(AgentConfigurationConstants.NAME, "");
- if (agentName.trim().length() == 0 || "-".equals(agentName)) {
+ String agentName = overrides.get(AgentConfigurationConstants.NAME);
+ if (agentName == null || agentName.trim().length() == 0 || "-".equals(agentName)) {
agentName = "embeddedagent-" + serverEnvironment.getNodeName();
}
-
agentName = StringPropertyReplacer.replaceProperties(agentName);
overrides.put(AgentConfigurationConstants.NAME, agentName);
@@ -201,11 +200,11 @@ public class AgentConfigurationSetup {
}
// now that the configuration preferences are loaded, we need to override them with any bootstrap override properties
- Properties overrides = configurationOverrides;
+ Map<String, String> overrides = configurationOverrides;
if (overrides != null) {
- for (Map.Entry<Object, Object> entry : overrides.entrySet()) {
- String key = entry.getKey().toString();
- String value = entry.getValue().toString();
+ for (Map.Entry<String, String> entry : overrides.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
// allow ${var} notation in the values so we can provide variable replacements in the values
value = StringPropertyReplacer.replaceProperties(value);
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
index 64d11fd..018519d 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
@@ -4,7 +4,6 @@ import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
import org.jboss.as.server.ServerEnvironment;
@@ -44,6 +43,12 @@ public class AgentService implements Service<AgentService> {
private Map<String, Boolean> plugins = Collections.synchronizedMap(new HashMap<String, Boolean>());
/**
+ * Configuration settings that override the out-of-box configuration file. These are settings
+ * that the user set in the subsystem (e.g. standalone.xml or via AS CLI).
+ */
+ private Map<String, String> configOverrides = Collections.synchronizedMap(new HashMap<String, String>());
+
+ /**
* This is the actual embedded agent. This is what handles the plugin container lifecycle
* and communication to/from the server.
*/
@@ -103,6 +108,15 @@ public class AgentService implements Service<AgentService> {
log.info("New plugin definitions: " + pluginsWithEnableFlag);
}
+ protected void setConfigurationOverrides(Map<String, String> overrides) {
+ synchronized (configOverrides) {
+ configOverrides.clear();
+ if (overrides != null) {
+ configOverrides.putAll(overrides);
+ }
+ }
+ }
+
protected boolean isAgentStarted() {
AgentMain agent = theAgent.get();
return (agent != null && agent.isStarted());
@@ -118,10 +132,9 @@ public class AgentService implements Service<AgentService> {
try {
// make sure we pre-configure the agent with some settings taken from our runtime environment
ServerEnvironment env = envServiceValue.getValue();
- Properties overrides = new Properties();
boolean resetConfigurationAtStartup = true;
AgentConfigurationSetup configSetup = new AgentConfigurationSetup(
- getExportedResource("conf/agent-configuration.xml"), resetConfigurationAtStartup, overrides, env);
+ getExportedResource("conf/agent-configuration.xml"), resetConfigurationAtStartup, configOverrides, env);
// prepare the agent logging first thing so the agent logs messages using this config
configSetup.prepareLogConfigFile(getExportedResource("conf/log4j.xml"));
configSetup.preConfigureAgent();
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
index f9d3291..4867ef7 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -2,6 +2,7 @@ package org.rhq.embeddedagent.extension;
import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.jboss.as.controller.AbstractAddStepHandler;
import org.jboss.as.controller.OperationContext;
@@ -16,6 +17,8 @@ import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceController.Mode;
import org.jboss.msc.service.ServiceName;
+import org.rhq.enterprise.agent.AgentConfigurationConstants;
+
/**
* Handler responsible for adding the subsystem resource to the model
*/
@@ -32,6 +35,7 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
AgentSubsystemDefinition.AGENT_ENABLED_ATTRIBDEF.validateAndSet(operation, model);
AgentSubsystemDefinition.PLUGINS_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.PREF_AGENT_NAME_ATTRIBDEF.validateAndSet(operation, model);
log.info("Populating the embedded agent subsystem model: " + operation + "=" + model);
}
@@ -49,6 +53,8 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
}
log.info("Embedded agent is enabled and will be deployed");
+
+ // figure out what plugins we are to support
HashMap<String, Boolean> pluginsWithEnableFlag = new HashMap<String, Boolean>();
ModelNode pluginsNode = AgentSubsystemDefinition.PLUGINS_ATTRIBDEF.resolveModelAttribute(context, model);
if (pluginsNode != null && pluginsNode.isDefined()) {
@@ -60,9 +66,20 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
}
}
+ // set up our runtime configuration overrides that should be used instead of the out-of-box config
+ Map<String, String> overrides = new HashMap<String, String>();
+ ModelNode agentNameNode = AgentSubsystemDefinition.PREF_AGENT_NAME_ATTRIBDEF.resolveModelAttribute(context,
+ model);
+ if (agentNameNode.isDefined()) {
+ overrides.put(AgentConfigurationConstants.NAME, agentNameNode.asString());
+ }
+
+ // create our service
AgentService service = new AgentService();
service.setPlugins(pluginsWithEnableFlag);
+ service.setConfigurationOverrides(overrides);
+ // install the service
ServiceName name = AgentService.SERVICE_NAME;
ServiceController<AgentService> controller = context.getServiceTarget() //
.addService(name, service) //
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
index e43c6c5..0dffb92 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
@@ -2,6 +2,7 @@ package org.rhq.embeddedagent.extension;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIBE;
+import org.jboss.as.controller.ReloadRequiredWriteAttributeHandler;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleResourceDefinition;
@@ -22,6 +23,11 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
.setXmlName(AgentSubsystemExtension.AGENT_ENABLED).setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setDefaultValue(new ModelNode(AgentSubsystemExtension.AGENT_ENABLED_DEFAULT)).setAllowNull(false).build();
+ protected static final SimpleAttributeDefinition PREF_AGENT_NAME_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_AGENT_NAME, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.ATTRIB_AGENT_NAME).setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setAllowNull(true).build();
+
protected static final PluginsAttributeDefinition PLUGINS_ATTRIBDEF = new PluginsAttributeDefinition();
private AgentSubsystemDefinition() {
@@ -33,6 +39,8 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
public void registerAttributes(ManagementResourceRegistration rr) {
rr.registerReadWriteAttribute(AGENT_ENABLED_ATTRIBDEF, null, AgentEnabledAttributeHandler.INSTANCE);
rr.registerReadWriteAttribute(PLUGINS_ATTRIBDEF, null, PluginsAttributeHandler.INSTANCE);
+ rr.registerReadWriteAttribute(PREF_AGENT_NAME_ATTRIBDEF, null, new ReloadRequiredWriteAttributeHandler(
+ PREF_AGENT_NAME_ATTRIBDEF));
}
@Override
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
index 1ab7a7e..37ec585 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
@@ -29,6 +29,8 @@ import org.jboss.staxmapper.XMLElementWriter;
import org.jboss.staxmapper.XMLExtendedStreamReader;
import org.jboss.staxmapper.XMLExtendedStreamWriter;
+import org.rhq.enterprise.agent.AgentConfigurationConstants;
+
public class AgentSubsystemExtension implements Extension {
private final Logger log = Logger.getLogger(AgentSubsystemExtension.class);
@@ -53,6 +55,8 @@ public class AgentSubsystemExtension implements Extension {
protected static final String AGENT_STOP_OP = "stop";
protected static final String AGENT_STATUS_OP = "status";
+ protected static final String ATTRIB_AGENT_NAME = AgentConfigurationConstants.NAME;
+
protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) {
@@ -97,17 +101,20 @@ public class AgentSubsystemExtension implements Extension {
opAdd.get(AGENT_ENABLED).set(agentEnabledValue);
}
- ModelNode pluginsAttributeNode = opAdd.get(PLUGINS_ELEMENT);
-
// Read the children elements
while (reader.hasNext() && reader.nextTag() != END_ELEMENT) {
- if (!reader.getLocalName().equals(PLUGINS_ELEMENT)) {
- throw ParseUtils.unexpectedElement(reader);
- }
- while (reader.hasNext() && reader.nextTag() != END_ELEMENT) {
- if (reader.isStartElement()) {
- readPlugin(reader, pluginsAttributeNode);
+ String elementName = reader.getLocalName();
+ if (elementName.equals(PLUGINS_ELEMENT)) {
+ ModelNode pluginsAttributeNode = opAdd.get(PLUGINS_ELEMENT);
+ while (reader.hasNext() && reader.nextTag() != END_ELEMENT) {
+ if (reader.isStartElement()) {
+ readPlugin(reader, pluginsAttributeNode);
+ }
}
+ } else if (elementName.equals(ATTRIB_AGENT_NAME)) {
+ opAdd.get(ATTRIB_AGENT_NAME).set(reader.getElementText());
+ } else {
+ throw ParseUtils.unexpectedElement(reader);
}
}
@@ -153,6 +160,10 @@ public class AgentSubsystemExtension implements Extension {
writer.writeAttribute(AGENT_ENABLED,
String.valueOf(node.get(AGENT_ENABLED).asBoolean(AGENT_ENABLED_DEFAULT)));
+ writer.writeStartElement(ATTRIB_AGENT_NAME);
+ writer.writeCharacters(node.get(ATTRIB_AGENT_NAME).asString());
+ writer.writeEndElement();
+
// <plugins>
writer.writeStartElement(PLUGINS_ELEMENT);
ModelNode plugins = node.get(PLUGINS_ELEMENT);
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
index 790232a..05bcfce 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
@@ -5,4 +5,5 @@ embeddedagent.restart=Starts the RHQ Agent. If it is already started, it will be
embeddedagent.stop=Stops the RHQ Agent if it is running.
embeddedagent.status=Tells you if the RHQ Agent is currently started or stopped.
embeddedagent.enabled=When true, the RHQ Agent will be deployed and started. Otherwise, it will be disabled.
-embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
\ No newline at end of file
+embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
+embeddedagent.rhq.agent.name=Name to uniquely identify this agent among all other agents in the environment
\ No newline at end of file
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
index 2882729..3e0c546 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
@@ -10,6 +10,7 @@
<xs:complexType name="subsystemType">
<xs:attribute name="enabled" type="xs:boolean" use="required" default="false"/>
<xs:all>
+ <xs:element name="rhq.agent.name" type="xs:string"/>
<xs:element name="plugins" type="pluginsType"/>
</xs:all>
</xs:complexType>
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
index b33fb4f..e857af4 100644
--- a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -14,6 +14,7 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VAL
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.WRITE_ATTRIBUTE_OPERATION;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.testng.Assert;
@@ -132,31 +133,24 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
* operations from its describe action results in the same model
*/
public void testDescribeHandler() throws Exception {
- // test two subsystem xmls - one that is empty of plugins, and the second is our normal test xml
- String subsystemXml1 = "<subsystem xmlns=\"" + AgentSubsystemExtension.NAMESPACE + "\" "
- + AgentSubsystemExtension.AGENT_ENABLED + "=\"true\"" + "></subsystem>";
- String subsystemXml2 = getSubsystemXml();
-
- String[] subsystemXmlAll = new String[] { subsystemXml1, subsystemXml2 };
- for (String subsystemXml : subsystemXmlAll) {
- KernelServices servicesA = super.installInController(subsystemXml);
- // Get the model and the describe operations from the first controller
- ModelNode modelA = servicesA.readWholeModel();
- ModelNode describeOp = new ModelNode();
- describeOp.get(OP).set(DESCRIBE);
- describeOp.get(OP_ADDR).set(
- PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME))
- .toModelNode());
- ModelNode executeOperation = servicesA.executeOperation(describeOp);
- List<ModelNode> operations = super.checkResultAndGetContents(executeOperation).asList();
-
- // Install the describe options from the first controller into a second controller
- KernelServices servicesB = super.installInController(operations);
- ModelNode modelB = servicesB.readWholeModel();
-
- // Make sure the models from the two controllers are identical
- super.compare(modelA, modelB);
- }
+ String subsystemXml = getSubsystemXml();
+ KernelServices servicesA = super.installInController(subsystemXml);
+ // Get the model and the describe operations from the first controller
+ ModelNode modelA = servicesA.readWholeModel();
+ ModelNode describeOp = new ModelNode();
+ describeOp.get(OP).set(DESCRIBE);
+ describeOp.get(OP_ADDR).set(
+ PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME))
+ .toModelNode());
+ ModelNode executeOperation = servicesA.executeOperation(describeOp);
+ List<ModelNode> operations = super.checkResultAndGetContents(executeOperation).asList();
+
+ // Install the describe options from the first controller into a second controller
+ KernelServices servicesB = super.installInController(operations);
+ ModelNode modelB = servicesB.readWholeModel();
+
+ // Make sure the models from the two controllers are identical
+ super.compare(modelA, modelB);
}
/**
@@ -202,9 +196,17 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
// check the attributes
Assert.assertTrue(content.get("attributes").isDefined());
List<Property> attributes = content.get("attributes").asPropertyList();
- Assert.assertEquals(attributes.size(), 2);
- Assert.assertEquals(attributes.get(0).getName(), AgentSubsystemExtension.AGENT_ENABLED);
- Assert.assertEquals(attributes.get(1).getName(), AgentSubsystemExtension.PLUGINS_ELEMENT);
+ Assert.assertEquals(attributes.size(), 3);
+
+ List<String> expectedAttributes = Arrays.asList( //
+ AgentSubsystemExtension.AGENT_ENABLED, //
+ AgentSubsystemExtension.PLUGINS_ELEMENT, //
+ AgentSubsystemExtension.ATTRIB_AGENT_NAME);
+
+ for (int i = 0 ; i < attributes.size(); i++) {
+ String attrib = attributes.get(i).getName();
+ Assert.assertTrue(expectedAttributes.contains(attrib), "missing attrib: " + attrib);
+ }
// check the operations
Assert.assertTrue(content.get("operations").isDefined());
diff --git a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
index 4e4a85d..8d60c99 100644
--- a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
+++ b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
@@ -1,4 +1,5 @@
<subsystem xmlns="urn:org.rhq:embeddedagent:1.0" enabled="true">
+ <rhq.agent.name>embeddedagent-test</rhq.agent.name>
<plugins>
<plugin name="platform" enabled="true" />
<plugin name="blah" enabled="false" />
commit 6bedbd7ba9e001deb5c57e9484995893a63b01e2
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Jan 31 01:06:00 2014 -0500
add source to eclipse classpath
diff --git a/.classpath b/.classpath
index cb9f5bc..455f739 100644
--- a/.classpath
+++ b/.classpath
@@ -329,13 +329,13 @@
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/msc/jboss-msc/1.0.2.GA/jboss-msc-1.0.2.GA.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/jboss-dmr/1.1.1.Final/jboss-dmr-1.1.1.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-naming/7.2.0.Alpha1-redhat-4/jboss-as-naming-7.2.0.Alpha1-redhat-4.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-server/7.2.0.Alpha1-redhat-4/jboss-as-server-7.2.0.Alpha1-redhat-4.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-server/7.2.0.Alpha1-redhat-4/jboss-as-server-7.2.0.Alpha1-redhat-4.jar" sourcepath="/M2_REPO/org/jboss/as/jboss-as-server/7.2.0.Alpha1-redhat-4/jboss-as-server-7.2.0.Alpha1-redhat-4-sources.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-ee/7.2.0.Alpha1-redhat-4/jboss-as-ee-7.2.0.Alpha1-redhat-4.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-ejb3/7.2.0.Alpha1-redhat-4/jboss-as-ejb3-7.2.0.Alpha1-redhat-4.jar" sourcepath="/M2_REPO/org/jboss/as/jboss-as-ejb3/7.2.0.Alpha1-redhat-4/jboss-as-ejb3-7.2.0.Alpha1-redhat-4-sources.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/staxmapper/1.1.0.Final/staxmapper-1.1.0.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/modules/jboss-modules/1.1.1.GA/jboss-modules-1.1.1.GA.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-subsystem-test/7.1.1.Final/jboss-as-subsystem-test-7.1.1.Final.jar"/>
- <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-controller/7.1.1.Final/jboss-as-controller-7.1.1.Final.jar"/>
+ <classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-controller/7.1.1.Final/jboss-as-controller-7.1.1.Final.jar" sourcepath="/M2_REPO/org/jboss/as/jboss-as-controller/7.2.0.Alpha1-redhat-4/jboss-as-controller-7.2.0.Alpha1-redhat-4-sources.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/as/jboss-as-controller-client/7.1.1.Final/jboss-as-controller-client-7.1.1.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/resteasy/resteasy-links/2.3.5.Final/resteasy-links-2.3.5.Final.jar"/>
<classpathentry exported="true" kind="var" path="M2_REPO/org/jboss/resteasy/resteasy-jaxrs/2.3.5.Final/resteasy-jaxrs-2.3.5.Final.jar"/>
commit cbe0f94aa7679fea8e8acf22afb23f05074a0c97
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 30 23:13:16 2014 -0500
trivial - reformat
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentEnabledAttributeHandler.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentEnabledAttributeHandler.java
index a815600..59419c1 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentEnabledAttributeHandler.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentEnabledAttributeHandler.java
@@ -8,28 +8,26 @@ import org.jboss.logging.Logger;
class AgentEnabledAttributeHandler extends AbstractWriteAttributeHandler<Void> {
- public static final AgentEnabledAttributeHandler INSTANCE = new AgentEnabledAttributeHandler();
+ public static final AgentEnabledAttributeHandler INSTANCE = new AgentEnabledAttributeHandler();
private final Logger log = Logger.getLogger(AgentEnabledAttributeHandler.class);
- private AgentEnabledAttributeHandler() {
- super(AgentSubsystemDefinition.AGENT_ENABLED_ATTRIBDEF);
+ private AgentEnabledAttributeHandler() {
+ super(AgentSubsystemDefinition.AGENT_ENABLED_ATTRIBDEF);
}
- @Override
- protected boolean applyUpdateToRuntime(OperationContext context,
- ModelNode operation, String attributeName, ModelNode resolvedValue,
- ModelNode currentValue, HandbackHolder<Void> handbackHolder)
- throws OperationFailedException {
+ @Override
+ protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode resolvedValue, ModelNode currentValue, HandbackHolder<Void> handbackHolder)
+ throws OperationFailedException {
log.info("Embedded agent enabled attribute changed: " + attributeName + "=" + resolvedValue);
// there is nothing for us to do - this only affects us when we are restarted, return true to say we must reload
return true;
}
- @Override
- protected void revertUpdateToRuntime(OperationContext context,
- ModelNode operation, String attributeName,
- ModelNode valueToRestore, ModelNode valueToRevert, Void handback) {
+ @Override
+ protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode valueToRestore, ModelNode valueToRevert, Void handback) {
// no-op
}
}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeHandler.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeHandler.java
index 1d51294..078bf17 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeHandler.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeHandler.java
@@ -13,15 +13,15 @@ import org.jboss.msc.service.ServiceNotFoundException;
class PluginsAttributeHandler extends AbstractWriteAttributeHandler<Void> {
- public static final PluginsAttributeHandler INSTANCE = new PluginsAttributeHandler();
+ public static final PluginsAttributeHandler INSTANCE = new PluginsAttributeHandler();
private final Logger log = Logger.getLogger(PluginsAttributeHandler.class);
- private PluginsAttributeHandler() {
+ private PluginsAttributeHandler() {
super(AgentSubsystemDefinition.PLUGINS_ATTRIBDEF);
}
- @Override
+ @Override
protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
ModelNode resolvedValue, ModelNode currentValue, HandbackHolder<Void> handbackHolder)
throws OperationFailedException {
commit 1a34858e39f0d069d364e7a48f53d8294635be0c
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 30 23:12:44 2014 -0500
dont lose security token on embedded agent restart
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java
index 187527b..24c3d2d 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java
@@ -234,8 +234,11 @@ public class AgentConfigurationSetup {
// store is the default value.
// But first we need to backup these original preferences in case the config file fails to load -
// we'll restore the original values in that case.
+ // Note that we squirrel away any security token we already have - we need to preserve this when we can
+ // because otherwise the agent will not be able to re-register with any previous name is was registered with.
Preferences prefNode = getPreferencesNode();
+ String securityToken = prefNode.get(AgentConfigurationConstants.AGENT_SECURITY_TOKEN, null);
ByteArrayOutputStream backup = new ByteArrayOutputStream();
prefNode.exportSubtree(backup);
prefNode.clear();
@@ -249,9 +252,25 @@ public class AgentConfigurationSetup {
ByteArrayInputStream newConfigInputStream = new ByteArrayInputStream(newConfig.getBytes());
Preferences.importPreferences(newConfigInputStream);
- if (new AgentConfiguration(prefNode).getAgentConfigurationVersion() == 0) {
+ AgentConfiguration newAgentConfig = new AgentConfiguration(prefNode);
+ if (newAgentConfig.getAgentConfigurationVersion() == 0) {
throw new IllegalArgumentException("Bad preferences node");
}
+
+ // If we had a security token, restore it so we can maintain our known registration with the server.
+ // Note that if the configuration file already had a security token defined, it will be used and the old
+ // token we had will be thrown away.
+ if (securityToken != null) {
+ if (newAgentConfig.getAgentSecurityToken() == null) {
+ log.debug("Restoring embedded agent security token");
+ newAgentConfig.setAgentSecurityToken(securityToken);
+ } else {
+ log.debug("Not restoring embedded agent security token, the config file was preconfigured with one");
+ }
+ }
+
+ prefNode.flush();
+
} catch (Exception e) {
// a problem occurred importing the config file; let's restore our original values
try {
commit c4a4b0b9ef3ba69a5102e3f8429ecb5cb545382e
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 30 18:38:55 2014 -0500
embedded agent needs to add a dep on JAXB module as a substitute to the standalone agent's endorsed libs
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
index c818032..56419c3 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
@@ -34,7 +34,7 @@
<resource-root path="rhq-agent/lib/sigar-${sigar.version}.jar" />
<resource-root path="rhq-agent/lib/trove4j-3.0.3.jar" />
</resources>
-
+
<dependencies>
<!-- modules required by any subsystem -->
<module name="javax.api"/>
@@ -45,5 +45,8 @@
<module name="org.jboss.msc"/>
<module name="org.jboss.logging"/>
<module name="org.jboss.vfs"/>
+
+ <!-- the standalone agent had this in its endorsed dir, but the embedded agent adds it as a dependency -->
+ <module name="javax.xml.bind.api"/>
</dependencies>
</module>
commit 39064eb75ca0a34a516bee75fde85260663ca429
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 30 17:37:16 2014 -0500
start the embedded agent in a separate thread so as not to hang the subsystem startup
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
index f4644e1..64d11fd 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
@@ -5,7 +5,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import org.jboss.as.server.ServerEnvironment;
import org.jboss.logging.Logger;
@@ -30,6 +30,7 @@ public class AgentService implements Service<AgentService> {
/**
* Our subsystem add-step handler will inject this as a dependency for us.
* This service gives us information about the server, like the install directory, data directory, etc.
+ * Package-scoped so the add-step handler can access this.
*/
InjectedValue<ServerEnvironment> envServiceValue = new InjectedValue<ServerEnvironment>();
@@ -43,20 +44,15 @@ public class AgentService implements Service<AgentService> {
private Map<String, Boolean> plugins = Collections.synchronizedMap(new HashMap<String, Boolean>());
/**
- * Provides a mechanism to pre-configure the agent.
- */
- private AgentConfigurationSetup configSetup;
-
- /**
* This is the actual embedded agent. This is what handles the plugin container lifecycle
* and communication to/from the server.
*/
- private AgentMain theAgent;
+ private AtomicReference<AgentMain> theAgent = new AtomicReference<AgentMain>();
/**
- * Provides the status flag of the embedded agent itself (not of this service).
+ * This is the daemon thread running the agent.
*/
- private AtomicBoolean agentStarted = new AtomicBoolean(false);
+ private Thread agentThread;
public AgentService() {
}
@@ -108,7 +104,8 @@ public class AgentService implements Service<AgentService> {
}
protected boolean isAgentStarted() {
- return agentStarted.get();
+ AgentMain agent = theAgent.get();
+ return (agent != null && agent.isStarted());
}
protected void startAgent() throws StartException {
@@ -135,23 +132,41 @@ public class AgentService implements Service<AgentService> {
args[1] = "--pref=" + configSetup.getPreferencesNodeName();
args[2] = "--output=" + new File(env.getServerLogDir(), "embedded-agent.out").getAbsolutePath();
- theAgent = new AgentMain(args);
- theAgent.start();
-
- agentStarted.set(true);
+ theAgent.set(new AgentMain(args));
+
+ agentThread = new Thread("Embedded Agent Start Thread") {
+ public void run() {
+ try {
+ theAgent.get().start();
+ } catch (InterruptedException e) {
+ // agent just exited due to being shutdown, die quietly
+ log.debug("Embedded agent has exited.");
+ } catch (Throwable t) {
+ log.error("Embedded agent aborted with exception.", t);
+ }
+ };
+ };
+ agentThread.setDaemon(true);
+ agentThread.start();
} catch (Exception e) {
throw new StartException(e);
}
}
protected void stopAgent() {
- if (!isAgentStarted()) {
- log.info("Embedded agent is already stopped.");
- return;
+ try {
+ if (!isAgentStarted()) {
+ log.info("Embedded agent is already stopped.");
+ } else {
+ log.info("Stopping the embedded agent now");
+ theAgent.get().shutdown();
+ }
+ } finally {
+ if (agentThread != null) {
+ agentThread.interrupt();
+ }
}
-
- log.info("Stopping the embedded agent now");
- agentStarted.set(false);
+ theAgent.set(null);
}
/**
commit 2c74b334468dc74151117b5677db99db2bc43786
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Thu Jan 30 14:05:38 2014 -0500
1) preconfigure the agent prior to starting it
2) get log4j.xml to work but yet not put log files under bin/
3) don't need to put module.xml in the extension jar, just needs to be in module
diff --git a/modules/enterprise/server/embeddedagent/pom.xml b/modules/enterprise/server/embeddedagent/pom.xml
index c6118a6..0196223 100644
--- a/modules/enterprise/server/embeddedagent/pom.xml
+++ b/modules/enterprise/server/embeddedagent/pom.xml
@@ -26,6 +26,10 @@
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
+ <excludes>
+ <!-- this doesn't need to be in the jar, just in our module .zip -->
+ <exclude>module/main/module.xml</exclude>
+ </excludes>
</resource>
</resources>
@@ -89,16 +93,28 @@
<copy tofile="${module.lib}/macosx-x86_64/libsigar.dylib" file="${agent.lib}/libsigar-universal64-macosx.dylib" preservelastmodified="true"/>
<echo>Adjust default configuration</echo>
- <property name="config.xml" location="${project.build.directory}/rhq-agent/conf/agent-configuration.xml"/>
+ <property name="agent.config.dir" location="${project.build.directory}/rhq-agent/conf"/>
+ <property name="agent.config.xml" location="${agent.config.dir}/agent-configuration.xml"/>
<!-- because we are embedded, as can't have a prompt and ask user, so we will ensure the agent is always fully setup -->
- <replaceregexp file="${config.xml}" flags="s"
+ <replaceregexp file="${agent.config.xml}" flags="s"
match='<!--(\s*)<entry key="rhq.agent.configuration-setup-flag" value="false" />(\s*)-->'
- replace='<entry key="rhq.agent.configuration-setup-flag" value="true" /> BOOO' />
+ replace='<entry key="rhq.agent.configuration-setup-flag" value="true" />' />
<!-- we don't support agent auto-update while the agent is embedded -->
- <replaceregexp file="${config.xml}"
+ <replaceregexp file="${agent.config.xml}"
match='<entry key="rhq.agent.agent-update.enabled" value="true" />'
- replace='<entry key="rhq.agent.agent-update.enabled" value="false" /> BOOO' />
-
+ replace='<entry key="rhq.agent.agent-update.enabled" value="false" />' />
+ <!-- because we don't want log4j writing files in places we don't want, don't use file appenders. -->
+ <!-- our WildFly/EAP subsystem extension will turn this back on at runtime after log4j is properly configured. -->
+ <replaceregexp file="${agent.config.dir}/log4j.xml" flags="g"
+ match='<appender-ref ref="FILE".*/>'
+ replace='<!-- <appender-ref ref="FILE"/> -->' />
+ <replaceregexp file="${agent.config.dir}/log4j.xml" flags="g"
+ match='<appender-ref ref="COMMANDTRACE".*/>'
+ replace='<!-- <appender-ref ref="COMMANDTRACE"/> -->' />
+ <jar destfile="${agent.lib}/rhq-enterprise-agent-${project.version}.jar"
+ basedir="${agent.config.dir}"
+ includes="log4j.xml"
+ update="true" />
</target>
</configuration>
<goals>
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java
new file mode 100644
index 0000000..187527b
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java
@@ -0,0 +1,305 @@
+package org.rhq.embeddedagent.extension;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+import java.util.prefs.Preferences;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.xml.DOMConfigurator;
+
+import org.jboss.as.server.ServerEnvironment;
+import org.jboss.logging.Logger;
+import org.jboss.modules.Resource;
+import org.jboss.util.StringPropertyReplacer;
+
+import org.rhq.core.util.stream.StreamUtil;
+import org.rhq.enterprise.agent.AgentConfiguration;
+import org.rhq.enterprise.agent.AgentConfigurationConstants;
+import org.rhq.enterprise.agent.AgentConfigurationUpgrade;
+import org.rhq.enterprise.communications.ServiceContainerConfigurationConstants;
+
+public class AgentConfigurationSetup {
+
+ private final Logger log = Logger.getLogger(AgentConfigurationSetup.class);
+
+ private static final String DATA_DIRECTORY_NAME = "embeddedagent";
+
+ /**
+ * The location of the configuration file - can be a file path or path within classloader.
+ */
+ private final Resource configFile;
+
+ /**
+ * Properties that will be used to override preferences found in the preferences node and the configuration
+ * preferences file.
+ */
+ private final Properties configurationOverrides;
+
+ /**
+ * If <code>true</code>, will revert the agent's configuration back to the original configuration file.
+ * Otherwise, the configuration will be that which is currently persisted in the preferences store.
+ */
+ private final boolean resetConfigurationAtStartup;
+
+ /**
+ * The preferences node name that identifies the configuration set used to configure the services.
+ */
+ private final String preferencesNodeName;
+
+ /**
+ * Provides environment information about the server in which we are embedded.
+ */
+ private final ServerEnvironment serverEnvironment;
+
+ public AgentConfigurationSetup(Resource configFile, boolean resetConfigurationAtStartup,
+ Properties configurationOverrides, ServerEnvironment serverEnv) {
+
+ this.configFile = configFile;
+ this.resetConfigurationAtStartup = resetConfigurationAtStartup;
+ this.serverEnvironment = serverEnv;
+ this.configurationOverrides = prepareConfigurationOverrides(configurationOverrides);
+
+ String agentName = configurationOverrides.getProperty(AgentConfigurationConstants.NAME, "embeddedagent");
+ preferencesNodeName = agentName;
+ System.setProperty("rhq.agent.preferences-node", preferencesNodeName);
+ }
+
+ public String getPreferencesNodeName() {
+ return this.preferencesNodeName;
+ }
+
+ private Properties prepareConfigurationOverrides(Properties overrides) {
+ // perform some checking to setup defaults if need be
+ String agentName = overrides.getProperty(AgentConfigurationConstants.NAME, "");
+ if (agentName.trim().length() == 0 || "-".equals(agentName)) {
+ agentName = "embeddedagent-" + serverEnvironment.getNodeName();
+ }
+
+ agentName = StringPropertyReplacer.replaceProperties(agentName);
+ overrides.put(AgentConfigurationConstants.NAME, agentName);
+
+ File dataDir = getAgentDataDirectory();
+ File pluginsDir = new File(serverEnvironment.getServerDataDir(), "embeddedagent-plugins");
+ overrides.put(AgentConfigurationConstants.DATA_DIRECTORY, dataDir.getAbsolutePath());
+ overrides.put(AgentConfigurationConstants.PLUGINS_DIRECTORY, pluginsDir.getAbsolutePath());
+ overrides.put(ServiceContainerConfigurationConstants.DATA_DIRECTORY, dataDir.getAbsolutePath());
+
+ return overrides;
+ }
+
+ private File getAgentDataDirectory() {
+ File dir = new File(serverEnvironment.getServerDataDir(), DATA_DIRECTORY_NAME);
+ dir.mkdirs();
+ return dir;
+ }
+
+ public void preConfigureAgent() throws Exception {
+
+ // we need to store the preferences prior to starting the agent
+ if (resetConfigurationAtStartup) {
+ log.debug("Resetting the embedded agent's configuration back to its original settings");
+ reloadAgentConfiguration();
+ cleanDataDirectory();
+ } else {
+ log.debug("Loading the embedded agent's pre-existing configuration from preferences");
+ prepareConfigurationPreferences();
+ }
+
+ return;
+ }
+
+ /**
+ * Prepares the log config file so it writes the logs to the server's log directory.
+ * This is needed if we call or use any agent class because it wants to use log4j.
+ * This MUST be called prior to using any class that logs via log4j.
+ *
+ * @param logConfigFile the agent's out-of-box log config file
+ * @return the new log config file that the agent should use
+ * @throws Exception
+ */
+ public void prepareLogConfigFile(Resource logConfigFile) throws Exception {
+ try {
+ File logDir = this.serverEnvironment.getServerLogDir();
+ String agentLogFile = new File(logDir, "embedded-agent.log").getAbsolutePath();
+ String cmdTraceLogFile = new File(logDir, "embedded-agent-command-trace.log").getAbsolutePath();
+
+ String logConfig = new String(StreamUtil.slurp(logConfigFile.openStream()));
+ logConfig = logConfig.replace("\"logs/agent.log\"", "\"" + agentLogFile + "\"");
+ logConfig = logConfig.replace("\"logs/command-trace.log\"", "\"" + cmdTraceLogFile + "\"");
+ for (String app : new String[] { "ref=\"FILE\"", "ref=\"COMMANDTRACE\"" }) {
+ logConfig = logConfig.replace("<!-- <appender-ref " + app + "/> -->", "<appender-ref " + app + "/>");
+ }
+
+ File runtimeLogConfigFile = new File(getAgentDataDirectory(), "/log4j.xml");
+ ByteArrayInputStream in = new ByteArrayInputStream(logConfig.getBytes());
+ StreamUtil.copy(in, new FileOutputStream(runtimeLogConfigFile));
+
+ // this hot deploys the log4j.xml into log4j which is what the agent wants to use
+ LogManager.resetConfiguration();
+ DOMConfigurator.configure(runtimeLogConfigFile.toURI().toURL());
+ } catch (Exception e) {
+ log.error("Cannot tell the agent to put its logs in the logs directory - look elsewhere for the log files");
+ }
+ }
+
+ private Properties getAgentConfigurationProperties() {
+ try {
+ Properties properties = new Properties();
+ Preferences prefs = getPreferencesNode();
+
+ for (String key : prefs.keys()) {
+ properties.setProperty(key, prefs.get(key, "?"));
+ }
+
+ return properties;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void reloadAgentConfiguration() throws Exception {
+ getPreferencesNode().clear();
+ prepareConfigurationPreferences();
+ }
+
+ private void cleanDataDirectory() {
+ AgentConfiguration config = new AgentConfiguration(getPreferencesNode());
+ File dataDir = config.getDataDirectory();
+
+ cleanDataFile(dataDir);
+
+ // it is conceivable the comm services data directory was configured in a different
+ // place than where the agent's data directory is - make sure we clean out that other data dir
+ File commDataDir = config.getServiceContainerPreferences().getDataDirectory();
+ if (!commDataDir.getAbsolutePath().equals(dataDir.getAbsolutePath())) {
+ cleanDataFile(commDataDir);
+ }
+
+ return;
+ }
+
+ /**
+ * This will ensure the agent's configuration preferences are populated. If need be, the configuration file is
+ * loaded and all overrides are overlaid on top of the preferences. The preferences are also upgraded to ensure they
+ * conform to the latest configuration schema version.
+ *
+ * @return the agent configuration
+ *
+ * @throws Exception
+ */
+ private AgentConfiguration prepareConfigurationPreferences() throws Exception {
+ Preferences prefNode = getPreferencesNode();
+ AgentConfiguration config = new AgentConfiguration(prefNode);
+
+ if (config.getAgentConfigurationVersion() == 0) {
+ config = loadConfigurationFile();
+ }
+
+ // now that the configuration preferences are loaded, we need to override them with any bootstrap override properties
+ Properties overrides = configurationOverrides;
+ if (overrides != null) {
+ for (Map.Entry<Object, Object> entry : overrides.entrySet()) {
+ String key = entry.getKey().toString();
+ String value = entry.getValue().toString();
+
+ // allow ${var} notation in the values so we can provide variable replacements in the values
+ value = StringPropertyReplacer.replaceProperties(value);
+
+ prefNode.put(key, value);
+ }
+ }
+
+ // let's make sure our configuration is upgraded to the latest schema
+ AgentConfigurationUpgrade.upgradeToLatest(config.getPreferences());
+
+ return config;
+ }
+
+ /**
+ * Loads the configuration file.
+ *
+ * @return the configuration that was loaded
+ *
+ * @throws Exception on failure
+ */
+ private AgentConfiguration loadConfigurationFile() throws Exception {
+ // We need to clear out any previous configuration in case the current config file doesn't specify a preference
+ // that already exists in the preferences node. In this case, the configuration file wants to fall back on the
+ // default value and if we don't clear the preferences, we aren't guaranteed the value stored in the backing
+ // store is the default value.
+ // But first we need to backup these original preferences in case the config file fails to load -
+ // we'll restore the original values in that case.
+
+ Preferences prefNode = getPreferencesNode();
+ ByteArrayOutputStream backup = new ByteArrayOutputStream();
+ prefNode.exportSubtree(backup);
+ prefNode.clear();
+
+ // now load in the preferences
+ try {
+ ByteArrayOutputStream rawConfigFile = new ByteArrayOutputStream();
+ InputStream rawConfigInputStream = configFile.openStream();
+ StreamUtil.copy(rawConfigInputStream, rawConfigFile, true);
+ String newConfig = StringPropertyReplacer.replaceProperties(rawConfigFile.toString());
+ ByteArrayInputStream newConfigInputStream = new ByteArrayInputStream(newConfig.getBytes());
+ Preferences.importPreferences(newConfigInputStream);
+
+ if (new AgentConfiguration(prefNode).getAgentConfigurationVersion() == 0) {
+ throw new IllegalArgumentException("Bad preferences node");
+ }
+ } catch (Exception e) {
+ // a problem occurred importing the config file; let's restore our original values
+ try {
+ Preferences.importPreferences(new ByteArrayInputStream(backup.toByteArray()));
+ } catch (Exception e1) {
+ // its conceivable the same problem occurred here as with the original exception (backing store problem?)
+ // let's throw the original exception, not this one
+ }
+ throw e;
+ }
+
+ AgentConfiguration agentConfig = new AgentConfiguration(prefNode);
+ return agentConfig;
+ }
+
+ /**
+ * Returns the preferences for this agent. The node returned is where all preferences are to be stored.
+ *
+ * @return the agent preferences
+ */
+ private Preferences getPreferencesNode() {
+ Preferences topNode = Preferences.userRoot().node(AgentConfigurationConstants.PREFERENCE_NODE_PARENT);
+ Preferences prefNode = topNode.node(preferencesNodeName);
+ return prefNode;
+ }
+
+ /**
+ * This will delete the given file and if its a directory, will recursively delete its contents and its
+ * subdirectories.
+ *
+ * @param file the file/directory to delete
+ */
+ private void cleanDataFile(File file) {
+ boolean deleted;
+
+ File[] doomedFiles = file.listFiles();
+ if (doomedFiles != null) {
+ for (File doomedFile : doomedFiles) {
+ cleanDataFile(doomedFile); // call this method recursively
+ }
+ }
+
+ deleted = file.delete();
+
+ if (!deleted) {
+ log.warn("Cannot clean data file [" + file + "]");
+ }
+
+ return;
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
index 7860479..f4644e1 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
@@ -1,8 +1,10 @@
package org.rhq.embeddedagent.extension;
+import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import org.jboss.as.server.ServerEnvironment;
@@ -16,6 +18,8 @@ import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;
+import org.rhq.enterprise.agent.AgentMain;
+
public class AgentService implements Service<AgentService> {
public static final ServiceName SERVICE_NAME = ServiceName.of("org.rhq").append(
@@ -39,6 +43,17 @@ public class AgentService implements Service<AgentService> {
private Map<String, Boolean> plugins = Collections.synchronizedMap(new HashMap<String, Boolean>());
/**
+ * Provides a mechanism to pre-configure the agent.
+ */
+ private AgentConfigurationSetup configSetup;
+
+ /**
+ * This is the actual embedded agent. This is what handles the plugin container lifecycle
+ * and communication to/from the server.
+ */
+ private AgentMain theAgent;
+
+ /**
* Provides the status flag of the embedded agent itself (not of this service).
*/
private AtomicBoolean agentStarted = new AtomicBoolean(false);
@@ -96,12 +111,45 @@ public class AgentService implements Service<AgentService> {
return agentStarted.get();
}
- protected void startAgent() {
+ protected void startAgent() throws StartException {
+ if (isAgentStarted()) {
+ log.info("Embedded agent is already started.");
+ return;
+ }
+
log.info("Starting the embedded agent now");
- agentStarted.set(true);
+ try {
+ // make sure we pre-configure the agent with some settings taken from our runtime environment
+ ServerEnvironment env = envServiceValue.getValue();
+ Properties overrides = new Properties();
+ boolean resetConfigurationAtStartup = true;
+ AgentConfigurationSetup configSetup = new AgentConfigurationSetup(
+ getExportedResource("conf/agent-configuration.xml"), resetConfigurationAtStartup, overrides, env);
+ // prepare the agent logging first thing so the agent logs messages using this config
+ configSetup.prepareLogConfigFile(getExportedResource("conf/log4j.xml"));
+ configSetup.preConfigureAgent();
+
+ // build the startup command line arguments to pass to the agent
+ String[] args = new String[3];
+ args[0] = "--daemon";
+ args[1] = "--pref=" + configSetup.getPreferencesNodeName();
+ args[2] = "--output=" + new File(env.getServerLogDir(), "embedded-agent.out").getAbsolutePath();
+
+ theAgent = new AgentMain(args);
+ theAgent.start();
+
+ agentStarted.set(true);
+ } catch (Exception e) {
+ throw new StartException(e);
+ }
}
protected void stopAgent() {
+ if (!isAgentStarted()) {
+ log.info("Embedded agent is already stopped.");
+ return;
+ }
+
log.info("Stopping the embedded agent now");
agentStarted.set(false);
}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRestart.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRestart.java
index cdb14fd..e4080df 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRestart.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRestart.java
@@ -7,14 +7,15 @@ import org.jboss.dmr.ModelNode;
import org.jboss.logging.Logger;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceNotFoundException;
+import org.jboss.msc.service.StartException;
class AgentSubsystemRestart implements OperationStepHandler {
- static final AgentSubsystemRestart INSTANCE = new AgentSubsystemRestart();
+ static final AgentSubsystemRestart INSTANCE = new AgentSubsystemRestart();
- private final Logger log = Logger.getLogger(AgentSubsystemRestart.class);
+ private final Logger log = Logger.getLogger(AgentSubsystemRestart.class);
- private AgentSubsystemRestart() {
+ private AgentSubsystemRestart() {
}
@Override
@@ -22,15 +23,17 @@ class AgentSubsystemRestart implements OperationStepHandler {
try {
ServiceName name = AgentService.SERVICE_NAME;
AgentService service = (AgentService) opContext.getServiceRegistry(true).getRequiredService(name)
- .getValue();
+ .getValue();
log.info("Asked to restart the embedded agent");
service.stopAgent();
service.startAgent();
} catch (ServiceNotFoundException snfe) {
throw new OperationFailedException("Cannot restart embedded agent - the agent is disabled", snfe);
- }
+ } catch (StartException se) {
+ throw new OperationFailedException("Cannot restart embedded agent", se);
+ }
opContext.completeStep();
return;
- }
+ }
}
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
index 2cc72ef..c818032 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
@@ -5,6 +5,7 @@
<resources>
<resource-root path="${project.build.finalName}.jar"/>
<resource-root path="rhq-agent"/>
+ <resource-root path="rhq-agent/conf"/> <!-- so we pick up the agent's log4j.xml from here -->
<resource-root path="rhq-agent/lib/commons-httpclient-2.0.2.jar" /> <!-- agent seems to want this specific version -->
<resource-root path="rhq-agent/lib/commons-io-${commons-io.version}.jar" />
<resource-root path="rhq-agent/lib/commons-logging-${commons-logging.version}.jar" />
diff --git a/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml b/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
index b9310c4..70d6642 100644
--- a/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
@@ -8,15 +8,18 @@
<includeBaseDirectory>false</includeBaseDirectory>
<baseDirectory>${project.build.finalName}-module</baseDirectory>
<fileSets>
+ <!-- the module.xml which only does in the zip, it is not in the jar -->
<fileSet>
- <directory>${project.build.outputDirectory}/module</directory>
+ <directory>${basedir}/src/main/resources/module</directory>
<outputDirectory>/org/rhq/${artifactId}</outputDirectory>
<includes>
<include>main/module.xml</include>
</includes>
+ <filtered>true</filtered>
<fileMode>0644</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
+ <!-- the extension subsystem jar - this is just the extension classes, not the agent itself -->
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/org/rhq/${artifactId}/main</outputDirectory>
@@ -26,6 +29,7 @@
<fileMode>0644</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
+ <!-- the agent distro itself, inside the module's rhq-agent subdirectory -->
<fileSet>
<directory>${project.build.directory}/rhq-agent</directory>
<outputDirectory>/org/rhq/${artifactId}/main/rhq-agent</outputDirectory>
@@ -35,6 +39,7 @@
<fileMode>0644</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
+ <!-- the agent's native libraries which has to be specially organized for JBoss Modules to find them -->
<fileSet>
<directory>${project.build.directory}/module-lib</directory>
<outputDirectory>/org/rhq/${artifactId}/main/lib</outputDirectory>
commit 59f399485e35c0a163034a61b34b1fd2523b93c2
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jan 28 17:13:02 2014 -0500
inject the server env service into our service so we can get things like data dir, hostname, etc
add the rhq-agent distro to the exported resource roots so we can get the config xml
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
index 383f012..7860479 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
@@ -5,12 +5,16 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
+import org.jboss.as.server.ServerEnvironment;
import org.jboss.logging.Logger;
+import org.jboss.modules.Module;
+import org.jboss.modules.Resource;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
+import org.jboss.msc.value.InjectedValue;
public class AgentService implements Service<AgentService> {
@@ -20,11 +24,17 @@ public class AgentService implements Service<AgentService> {
private final Logger log = Logger.getLogger(AgentService.class);
/**
+ * Our subsystem add-step handler will inject this as a dependency for us.
+ * This service gives us information about the server, like the install directory, data directory, etc.
+ */
+ InjectedValue<ServerEnvironment> envServiceValue = new InjectedValue<ServerEnvironment>();
+
+ /**
* This service can be configured to be told explicitly about certain plugins to be
* enabled or disabled. This map holds that configuration. These aren't necessarily
* all the plugins that will be loaded, but they are those plugins this service was
* explicitly told about and indicates if they should be enabled or disabled.
- * TODO: For any plugin not specified will, by default, be WHAT? Disabled???
+ * TODO: For any plugin not specified will, by default, be WHAT? Disabled???
*/
private Map<String, Boolean> plugins = Collections.synchronizedMap(new HashMap<String, Boolean>());
@@ -95,4 +105,18 @@ public class AgentService implements Service<AgentService> {
log.info("Stopping the embedded agent now");
agentStarted.set(false);
}
+
+ /**
+ * Gets information about a file that is inside our module. Use this to
+ * obtain files locationed in the embedded agent, for example, pass in
+ * "conf/agent-configuration.xml" to get the config file.
+ *
+ * @param name name of the agent file
+ * @return object referencing the file from our module
+ */
+ private Resource getExportedResource(String name) {
+ Module module = Module.forClass(getClass());
+ Resource r = module.getExportedResource("rhq-agent", name);
+ return r;
+ }
}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
index 7541da1..f9d3291 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -7,6 +7,8 @@ import org.jboss.as.controller.AbstractAddStepHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.ServiceVerificationHandler;
+import org.jboss.as.server.ServerEnvironment;
+import org.jboss.as.server.ServerEnvironmentService;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.logging.Logger;
@@ -62,8 +64,12 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
service.setPlugins(pluginsWithEnableFlag);
ServiceName name = AgentService.SERVICE_NAME;
- ServiceController<AgentService> controller = context.getServiceTarget().addService(name, service)
- .addListener(verificationHandler).setInitialMode(Mode.ACTIVE).install();
+ ServiceController<AgentService> controller = context.getServiceTarget() //
+ .addService(name, service) //
+ .addDependency(ServerEnvironmentService.SERVICE_NAME, ServerEnvironment.class, service.envServiceValue) //
+ .addListener(verificationHandler) //
+ .setInitialMode(Mode.ACTIVE) //
+ .install();
newControllers.add(controller);
return;
}
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
index c041115..2cc72ef 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
@@ -4,6 +4,7 @@
<resources>
<resource-root path="${project.build.finalName}.jar"/>
+ <resource-root path="rhq-agent"/>
<resource-root path="rhq-agent/lib/commons-httpclient-2.0.2.jar" /> <!-- agent seems to want this specific version -->
<resource-root path="rhq-agent/lib/commons-io-${commons-io.version}.jar" />
<resource-root path="rhq-agent/lib/commons-logging-${commons-logging.version}.jar" />
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
index 40054b9..b33fb4f 100644
--- a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -16,16 +16,17 @@ import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.WRI
import java.util.ArrayList;
import java.util.List;
+import org.testng.Assert;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.subsystem.test.KernelServices;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.msc.service.ServiceNotFoundException;
-import org.testng.Assert;
-import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
@Test
public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
@@ -291,11 +292,13 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
Assert.assertEquals(plugins.get(2).getName(), "foo"); // foo plugin we added above
Assert.assertEquals(plugins.get(2).getValue().asBoolean(), true);
+ /* TODO: I think we need to mock the ServerEnvironmentService dependency before we can do this
// execute status
ModelNode statusOp = new ModelNode();
statusOp.get(OP).set(AgentSubsystemExtension.AGENT_STATUS_OP);
statusOp.get(OP_ADDR).set(agentSubsystemPath.toModelNode());
result = services.executeOperation(statusOp);
- Assert.assertEquals(checkResultAndGetContents(result).asString(), "STARTED");
+ Assert.assertTrue(checkResultAndGetContents(result).asBoolean());
+ */
}
}
commit ec1b31543c37e31813e2dc8397a8c38ad11754db
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Jan 28 15:29:31 2014 -0500
putting native libs in their proper place for EAP to find them
diff --git a/modules/enterprise/server/embeddedagent/pom.xml b/modules/enterprise/server/embeddedagent/pom.xml
index d20815b..c6118a6 100644
--- a/modules/enterprise/server/embeddedagent/pom.xml
+++ b/modules/enterprise/server/embeddedagent/pom.xml
@@ -54,6 +54,61 @@
</plugin>
<plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>rename-native-libs-and-reconfigure</id>
+ <phase>process-resources</phase>
+ <configuration>
+ <target>
+ <echo>Must move native libraries so JBoss Modules can find them</echo>
+ <property name="agent.lib" location="${project.build.directory}/rhq-agent/lib"/>
+ <property name="module.lib" location="${project.build.directory}/module-lib"/>
+ <!-- Notice that the agent's "augeas" native libs are not copied.
+ I think its only used for some plugins we won't be using in embedded mode anyway. -->
+ <!-- TODO these should probably be "move", I don't think we need dup copies in agent lib anymore -->
+ <copy tofile="${module.lib}/linux-i686/libsigar.so" file="${agent.lib}/libsigar-x86-linux.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/linux-x86_64/libsigar.so" file="${agent.lib}/libsigar-amd64-linux.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/linux-ia64/libsigar.so" file="${agent.lib}/libsigar-ia64-linux.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/linux-ppc64/libsigar.so" file="${agent.lib}/libsigar-ppc64-linux.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/linux-ppc/libsigar.so" file="${agent.lib}/libsigar-ppc-linux.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/linux-s390x/libsigar.so" file="${agent.lib}/libsigar-s390x-linux.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/win-i686/sigar.dll" file="${agent.lib}/sigar-x86-winnt.dll" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/win-x86_64/sigar.dll" file="${agent.lib}/sigar-amd64-winnt.dll" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/hpux-ia64w/libsigar.sl" file="${agent.lib}/libsigar-ia64-hpux-11.sl" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/hpux-parisc/libsigar.sl" file="${agent.lib}/libsigar-pa-hpux-11.sl" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/aix-ppc/libsigar.so" file="${agent.lib}/libsigar-ppc-aix-5.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/aix-ppc64/libsigar.so" file="${agent.lib}/libsigar-ppc64-aix-5.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/solaris-i686/libsigar.so" file="${agent.lib}/libsigar-x86-solaris.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/solaris-x86_64/libsigar.so" file="${agent.lib}/libsigar-amd64-solaris.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/solaris-sparc/libsigar.so" file="${agent.lib}/libsigar-sparc-solaris.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/solaris-sparcv9/libsigar.so" file="${agent.lib}/libsigar-sparc64-solaris.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/freebsd-i686/libsigar.so" file="${agent.lib}/libsigar-x86-freebsd-6.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/freebsd-x86_64/libsigar.so" file="${agent.lib}/libsigar-amd64-freebsd-6.so" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/macosx-i686/libsigar.dylib" file="${agent.lib}/libsigar-universal-macosx.dylib" preservelastmodified="true"/>
+ <copy tofile="${module.lib}/macosx-x86_64/libsigar.dylib" file="${agent.lib}/libsigar-universal64-macosx.dylib" preservelastmodified="true"/>
+
+ <echo>Adjust default configuration</echo>
+ <property name="config.xml" location="${project.build.directory}/rhq-agent/conf/agent-configuration.xml"/>
+ <!-- because we are embedded, as can't have a prompt and ask user, so we will ensure the agent is always fully setup -->
+ <replaceregexp file="${config.xml}" flags="s"
+ match='<!--(\s*)<entry key="rhq.agent.configuration-setup-flag" value="false" />(\s*)-->'
+ replace='<entry key="rhq.agent.configuration-setup-flag" value="true" /> BOOO' />
+ <!-- we don't support agent auto-update while the agent is embedded -->
+ <replaceregexp file="${config.xml}"
+ match='<entry key="rhq.agent.agent-update.enabled" value="true" />'
+ replace='<entry key="rhq.agent.agent-update.enabled" value="false" /> BOOO' />
+
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
diff --git a/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml b/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
index c526e5c..b9310c4 100644
--- a/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
@@ -35,6 +35,12 @@
<fileMode>0644</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
+ <fileSet>
+ <directory>${project.build.directory}/module-lib</directory>
+ <outputDirectory>/org/rhq/${artifactId}/main/lib</outputDirectory>
+ <fileMode>0755</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
</fileSets>
</assembly>
commit e5fdaf12dc7d0622bd2dc6e1031e656b2c0e9b88
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Jan 27 17:28:30 2014 -0500
there is no easy way to build a generated module.xml from the agent distro dependency list, so just put these in directly in the module.xml.
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
index 662dd31..c041115 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
@@ -4,7 +4,33 @@
<resources>
<resource-root path="${project.build.finalName}.jar"/>
- <resource-root path="rhq-agent" />
+ <resource-root path="rhq-agent/lib/commons-httpclient-2.0.2.jar" /> <!-- agent seems to want this specific version -->
+ <resource-root path="rhq-agent/lib/commons-io-${commons-io.version}.jar" />
+ <resource-root path="rhq-agent/lib/commons-logging-${commons-logging.version}.jar" />
+ <resource-root path="rhq-agent/lib/concurrent-${concurrent.version}.jar" />
+ <resource-root path="rhq-agent/lib/dom4j-1.6.jar" /> <!-- agent seems to want this specific version -->
+ <resource-root path="rhq-agent/lib/getopt-${getopt.version}.jar" />
+ <resource-root path="rhq-agent/lib/i18nlog-${i18nlog.version}.jar" />
+ <resource-root path="rhq-agent/lib/jboss-common-core-${jboss-common-core.version}.jar" />
+ <resource-root path="rhq-agent/lib/jboss-jmx-${jboss-jmx.version}.jar" />
+ <resource-root path="rhq-agent/lib/jboss-logging-${jboss-logging.version}.jar" />
+ <resource-root path="rhq-agent/lib/jboss-remoting-${jboss-remoting.version}.jar" />
+ <resource-root path="rhq-agent/lib/jboss-serialization-${jboss-serialization.version}.jar" />
+ <resource-root path="rhq-agent/lib/jline-${jline.version}.jar" />
+ <resource-root path="rhq-agent/lib/log4j-${log4j.version}.jar" />
+ <resource-root path="rhq-agent/lib/persistence-api-1.0.jar" />
+ <resource-root path="rhq-agent/lib/rhq-common-drift-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-core-client-api-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-core-comm-api-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-core-domain-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-core-native-system-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-core-plugin-api-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-core-plugin-container-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-core-util-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-enterprise-agent-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/rhq-enterprise-comm-${project.version}.jar" />
+ <resource-root path="rhq-agent/lib/sigar-${sigar.version}.jar" />
+ <resource-root path="rhq-agent/lib/trove4j-3.0.3.jar" />
</resources>
<dependencies>
commit bc8295387834979dbc87cf448abed87c811a69d7
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Jan 27 10:37:05 2014 -0500
unpack the entire agent zip inside the module.
diff --git a/modules/enterprise/server/embeddedagent/pom.xml b/modules/enterprise/server/embeddedagent/pom.xml
index 70ecea6..d20815b 100644
--- a/modules/enterprise/server/embeddedagent/pom.xml
+++ b/modules/enterprise/server/embeddedagent/pom.xml
@@ -30,13 +30,28 @@
</resources>
<plugins>
- <!-- COPY AGENT BINARIES <plugin> <artifactId>maven-dependency-plugin</artifactId>
- <executions> <execution> <id>copy-agent</id> <phase>process-resources</phase>
- <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem>
- <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-ear</artifactId>
- <type>ear</type> <outputDirectory>${project.build.directory}/agent/</outputDirectory>
- </artifactItem> </artifactItems> </configuration> </execution> </executions>
- </plugin> -->
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-agent</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-agent</artifactId>
+ <type>zip</type>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
@@ -69,6 +84,12 @@
<artifactId>jboss-as-server</artifactId>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-enterprise-agent</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
<!-- test deps -->
<dependency>
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
index 295c78d..662dd31 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
@@ -4,7 +4,7 @@
<resources>
<resource-root path="${project.build.finalName}.jar"/>
- <!-- <resource-root path="agent" /> -->
+ <resource-root path="rhq-agent" />
</resources>
<dependencies>
diff --git a/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml b/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
index a4cab0a..c526e5c 100644
--- a/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
+++ b/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
@@ -27,8 +27,11 @@
<directoryMode>0755</directoryMode>
</fileSet>
<fileSet>
- <directory>${project.build.directory}/agent</directory>
- <outputDirectory>/org/rhq/${artifactId}/main/agent</outputDirectory>
+ <directory>${project.build.directory}/rhq-agent</directory>
+ <outputDirectory>/org/rhq/${artifactId}/main/rhq-agent</outputDirectory>
+ <excludes>
+ <exclude>plugins</exclude>
+ </excludes>
<fileMode>0644</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
commit 6171c6f8d5c6e03d084cf22533d7184296370152
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Jan 24 20:25:13 2014 -0500
initial start of the embedded agent as a WildFly extension subsystem.
right now, this is just the shell service. the agent isn't in here yet. but the service
is fully wired into the AS infrastructure and shows in the AS CLI. has a normal model just like all other subsystems.
Now just have to build the module with the agent inside and have the shell call the AgentMain
diff --git a/.classpath b/.classpath
index 7bd64fe..cb9f5bc 100644
--- a/.classpath
+++ b/.classpath
@@ -77,6 +77,8 @@
<classpathentry kind="src" path="modules/enterprise/server/safe-invoker/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/startup-subsystem/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/startup-subsystem/src/test/java"/>
+ <classpathentry kind="src" path="modules/enterprise/server/embeddedagent/src/main/java"/>
+ <classpathentry kind="src" path="modules/enterprise/server/embeddedagent/src/test/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/ant-bundle/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/filetemplate-bundle/src/main/java"/>
<classpathentry kind="src" path="modules/enterprise/server/plugins/alert-subject/src/main/java"/>
diff --git a/modules/enterprise/server/embeddedagent/pom.xml b/modules/enterprise/server/embeddedagent/pom.xml
new file mode 100644
index 0000000..70ecea6
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/pom.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.rhq</groupId>
+ <artifactId>rhq-parent</artifactId>
+ <version>4.10.0-SNAPSHOT</version>
+ <relativePath>../../../../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>embeddedagent</artifactId>
+
+ <name>RHQ Embedded Agent Subsystem</name>
+
+ <properties>
+ <!-- this is used to replace the variable in module.xml -->
+ <moduleName>${project.groupId}.${project.artifactId}</moduleName>
+ <moduleDir>org/rhq/${project.artifactId}</moduleDir>
+ </properties>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+
+ <plugins>
+ <!-- COPY AGENT BINARIES <plugin> <artifactId>maven-dependency-plugin</artifactId>
+ <executions> <execution> <id>copy-agent</id> <phase>process-resources</phase>
+ <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem>
+ <groupId>org.rhq</groupId> <artifactId>rhq-enterprise-server-ear</artifactId>
+ <type>ear</type> <outputDirectory>${project.build.directory}/agent/</outputDirectory>
+ </artifactItem> </artifactItems> </configuration> </execution> </executions>
+ </plugin> -->
+
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/scripts/module-assembly.xml</descriptor>
+ </descriptors>
+ </configuration>
+ <executions>
+ <execution>
+ <id>module-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-controller</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-server</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <!-- test deps -->
+ <dependency>
+ <groupId>org.jboss.as</groupId>
+ <artifactId>jboss-as-subsystem-test</artifactId>
+ <version>${jboss.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <profile>
+ <id>dev</id>
+
+ <properties>
+ <rhq.rootDir>../../../..</rhq.rootDir>
+ <rhq.containerDir>${rhq.rootDir}/${rhq.devContainerServerPath}</rhq.containerDir>
+ <rhq.deploymentName>${project.build.finalName}.zip</rhq.deploymentName>
+ <rhq.deploymentDir>${rhq.containerDir}/modules/</rhq.deploymentDir>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+
+ <execution>
+ <id>deploy</id>
+ <phase>package</phase>
+ <configuration>
+ <target>
+ <echo>*** Deploying Embedded Agent module to ${rhq.deploymentDir}</echo>
+ <unzip src="target/${rhq.deploymentName}"
+ dest="${rhq.deploymentDir}" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>undeploy</id>
+ <phase>clean</phase>
+ <configuration>
+ <target>
+ <echo>*** Deleting Embedded Agent module ... ${rhq.deploymentDir}/${moduleDir}</echo>
+ <delete dir="${rhq.deploymentDir}/${moduleDir}" />
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentEnabledAttributeHandler.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentEnabledAttributeHandler.java
new file mode 100644
index 0000000..a815600
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentEnabledAttributeHandler.java
@@ -0,0 +1,35 @@
+package org.rhq.embeddedagent.extension;
+
+import org.jboss.as.controller.AbstractWriteAttributeHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+import org.jboss.logging.Logger;
+
+class AgentEnabledAttributeHandler extends AbstractWriteAttributeHandler<Void> {
+
+ public static final AgentEnabledAttributeHandler INSTANCE = new AgentEnabledAttributeHandler();
+
+ private final Logger log = Logger.getLogger(AgentEnabledAttributeHandler.class);
+
+ private AgentEnabledAttributeHandler() {
+ super(AgentSubsystemDefinition.AGENT_ENABLED_ATTRIBDEF);
+ }
+
+ @Override
+ protected boolean applyUpdateToRuntime(OperationContext context,
+ ModelNode operation, String attributeName, ModelNode resolvedValue,
+ ModelNode currentValue, HandbackHolder<Void> handbackHolder)
+ throws OperationFailedException {
+ log.info("Embedded agent enabled attribute changed: " + attributeName + "=" + resolvedValue);
+ // there is nothing for us to do - this only affects us when we are restarted, return true to say we must reload
+ return true;
+ }
+
+ @Override
+ protected void revertUpdateToRuntime(OperationContext context,
+ ModelNode operation, String attributeName,
+ ModelNode valueToRestore, ModelNode valueToRevert, Void handback) {
+ // no-op
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
new file mode 100644
index 0000000..383f012
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java
@@ -0,0 +1,98 @@
+package org.rhq.embeddedagent.extension;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.jboss.logging.Logger;
+import org.jboss.msc.service.Service;
+import org.jboss.msc.service.ServiceName;
+import org.jboss.msc.service.StartContext;
+import org.jboss.msc.service.StartException;
+import org.jboss.msc.service.StopContext;
+
+public class AgentService implements Service<AgentService> {
+
+ public static final ServiceName SERVICE_NAME = ServiceName.of("org.rhq").append(
+ AgentSubsystemExtension.SUBSYSTEM_NAME);
+
+ private final Logger log = Logger.getLogger(AgentService.class);
+
+ /**
+ * This service can be configured to be told explicitly about certain plugins to be
+ * enabled or disabled. This map holds that configuration. These aren't necessarily
+ * all the plugins that will be loaded, but they are those plugins this service was
+ * explicitly told about and indicates if they should be enabled or disabled.
+ * TODO: For any plugin not specified will, by default, be WHAT? Disabled???
+ */
+ private Map<String, Boolean> plugins = Collections.synchronizedMap(new HashMap<String, Boolean>());
+
+ /**
+ * Provides the status flag of the embedded agent itself (not of this service).
+ */
+ private AtomicBoolean agentStarted = new AtomicBoolean(false);
+
+ public AgentService() {
+ }
+
+ @Override
+ public AgentService getValue() throws IllegalStateException, IllegalArgumentException {
+ return this;
+ }
+
+ @Override
+ public void start(StartContext context) throws StartException {
+ log.info("Embedded agent service starting");
+ startAgent();
+ }
+
+ @Override
+ public void stop(StopContext context) {
+ log.info("Embedded agent service stopping");
+ stopAgent();
+ }
+
+ /**
+ * Returns the set of plugins the service knows about and whether
+ * or not those plugins are to be enabled or disabled.
+ * You get back a copy, not the actual map.
+ *
+ * @return plugins and their enable-flag
+ */
+ protected Map<String, Boolean> getPlugins() {
+ synchronized (plugins) {
+ return new HashMap<String, Boolean>(plugins);
+ }
+ }
+
+ /**
+ * Sets the enable flags for plugins.
+ *
+ * @return plugins and their enable-flag (if <code>null</code>, assumes an empty map)
+ */
+ protected void setPlugins(Map<String, Boolean> pluginsWithEnableFlag) {
+ synchronized (plugins) {
+ plugins.clear();
+ if (pluginsWithEnableFlag != null) {
+ plugins.putAll(pluginsWithEnableFlag);
+ }
+ }
+
+ log.info("New plugin definitions: " + pluginsWithEnableFlag);
+ }
+
+ protected boolean isAgentStarted() {
+ return agentStarted.get();
+ }
+
+ protected void startAgent() {
+ log.info("Starting the embedded agent now");
+ agentStarted.set(true);
+ }
+
+ protected void stopAgent() {
+ log.info("Stopping the embedded agent now");
+ agentStarted.set(false);
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
new file mode 100644
index 0000000..7541da1
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -0,0 +1,70 @@
+package org.rhq.embeddedagent.extension;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.jboss.as.controller.AbstractAddStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.ServiceVerificationHandler;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.Property;
+import org.jboss.logging.Logger;
+import org.jboss.msc.service.ServiceController;
+import org.jboss.msc.service.ServiceController.Mode;
+import org.jboss.msc.service.ServiceName;
+
+/**
+ * Handler responsible for adding the subsystem resource to the model
+ */
+class AgentSubsystemAdd extends AbstractAddStepHandler {
+
+ static final AgentSubsystemAdd INSTANCE = new AgentSubsystemAdd();
+
+ private final Logger log = Logger.getLogger(AgentSubsystemAdd.class);
+
+ private AgentSubsystemAdd() {
+ }
+
+ @Override
+ protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
+ AgentSubsystemDefinition.AGENT_ENABLED_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.PLUGINS_ATTRIBDEF.validateAndSet(operation, model);
+ log.info("Populating the embedded agent subsystem model: " + operation + "=" + model);
+ }
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model,
+ ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers)
+ throws OperationFailedException {
+
+ boolean enabled = AgentSubsystemDefinition.AGENT_ENABLED_ATTRIBDEF.resolveModelAttribute(context, model)
+ .asBoolean(AgentSubsystemExtension.AGENT_ENABLED_DEFAULT);
+
+ if (!enabled) {
+ log.info("Embedded agent is not enabled and will not be deployed");
+ return;
+ }
+
+ log.info("Embedded agent is enabled and will be deployed");
+ HashMap<String, Boolean> pluginsWithEnableFlag = new HashMap<String, Boolean>();
+ ModelNode pluginsNode = AgentSubsystemDefinition.PLUGINS_ATTRIBDEF.resolveModelAttribute(context, model);
+ if (pluginsNode != null && pluginsNode.isDefined()) {
+ List<Property> pluginsList = pluginsNode.asPropertyList();
+ for (Property pluginsItem : pluginsList) {
+ String pluginName = pluginsItem.getName();
+ boolean pluginEnabled = pluginsItem.getValue().asBoolean();
+ pluginsWithEnableFlag.put(pluginName, pluginEnabled);
+ }
+ }
+
+ AgentService service = new AgentService();
+ service.setPlugins(pluginsWithEnableFlag);
+
+ ServiceName name = AgentService.SERVICE_NAME;
+ ServiceController<AgentService> controller = context.getServiceTarget().addService(name, service)
+ .addListener(verificationHandler).setInitialMode(Mode.ACTIVE).install();
+ newControllers.add(controller);
+ return;
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
new file mode 100644
index 0000000..e43c6c5
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
@@ -0,0 +1,66 @@
+package org.rhq.embeddedagent.extension;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIBE;
+
+import org.jboss.as.controller.SimpleAttributeDefinition;
+import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
+import org.jboss.as.controller.SimpleResourceDefinition;
+import org.jboss.as.controller.descriptions.DefaultOperationDescriptionProvider;
+import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
+import org.jboss.as.controller.registry.AttributeAccess;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+import org.jboss.as.controller.registry.OperationEntry;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.ModelType;
+
+public class AgentSubsystemDefinition extends SimpleResourceDefinition {
+
+ public static final AgentSubsystemDefinition INSTANCE = new AgentSubsystemDefinition();
+
+ protected static final SimpleAttributeDefinition AGENT_ENABLED_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.AGENT_ENABLED, ModelType.BOOLEAN).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.AGENT_ENABLED).setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode(AgentSubsystemExtension.AGENT_ENABLED_DEFAULT)).setAllowNull(false).build();
+
+ protected static final PluginsAttributeDefinition PLUGINS_ATTRIBDEF = new PluginsAttributeDefinition();
+
+ private AgentSubsystemDefinition() {
+ super(AgentSubsystemExtension.SUBSYSTEM_PATH, AgentSubsystemExtension.getResourceDescriptionResolver(null),
+ AgentSubsystemAdd.INSTANCE, AgentSubsystemRemove.INSTANCE);
+ }
+
+ @Override
+ public void registerAttributes(ManagementResourceRegistration rr) {
+ rr.registerReadWriteAttribute(AGENT_ENABLED_ATTRIBDEF, null, AgentEnabledAttributeHandler.INSTANCE);
+ rr.registerReadWriteAttribute(PLUGINS_ATTRIBDEF, null, PluginsAttributeHandler.INSTANCE);
+ }
+
+ @Override
+ public void registerOperations(ManagementResourceRegistration rr) {
+ super.registerOperations(rr);
+
+ // We always need to add a 'describe' operation
+ rr.registerOperationHandler(DESCRIBE, GenericSubsystemDescribeHandler.INSTANCE,
+ GenericSubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE);
+
+ rr.registerOperationHandler(
+ AgentSubsystemExtension.AGENT_RESTART_OP,
+ AgentSubsystemRestart.INSTANCE,
+ new DefaultOperationDescriptionProvider(AgentSubsystemExtension.AGENT_RESTART_OP, AgentSubsystemExtension
+ .getResourceDescriptionResolver(null)), false, OperationEntry.EntryType.PUBLIC);
+
+ rr.registerOperationHandler(
+ AgentSubsystemExtension.AGENT_STOP_OP,
+ AgentSubsystemStop.INSTANCE,
+ new DefaultOperationDescriptionProvider(AgentSubsystemExtension.AGENT_STOP_OP, AgentSubsystemExtension
+ .getResourceDescriptionResolver(null)), false, OperationEntry.EntryType.PUBLIC);
+
+ rr.registerOperationHandler(
+ AgentSubsystemExtension.AGENT_STATUS_OP,
+ AgentSubsystemStatus.INSTANCE,
+ new DefaultOperationDescriptionProvider(AgentSubsystemExtension.AGENT_STATUS_OP, AgentSubsystemExtension
+ .getResourceDescriptionResolver(null), ModelType.STRING), false, OperationEntry.EntryType.PUBLIC);
+
+ return;
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
new file mode 100644
index 0000000..1ab7a7e
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
@@ -0,0 +1,175 @@
+package org.rhq.embeddedagent.extension;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+
+import org.jboss.as.controller.Extension;
+import org.jboss.as.controller.ExtensionContext;
+import org.jboss.as.controller.PathAddress;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.controller.SubsystemRegistration;
+import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
+import org.jboss.as.controller.parsing.ExtensionParsingContext;
+import org.jboss.as.controller.parsing.ParseUtils;
+import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
+import org.jboss.as.controller.registry.ManagementResourceRegistration;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.Property;
+import org.jboss.logging.Logger;
+import org.jboss.staxmapper.XMLElementReader;
+import org.jboss.staxmapper.XMLElementWriter;
+import org.jboss.staxmapper.XMLExtendedStreamReader;
+import org.jboss.staxmapper.XMLExtendedStreamWriter;
+
+public class AgentSubsystemExtension implements Extension {
+
+ private final Logger log = Logger.getLogger(AgentSubsystemExtension.class);
+
+ public static final String NAMESPACE = "urn:org.rhq:embeddedagent:1.0";
+ public static final String SUBSYSTEM_NAME = "embeddedagent";
+
+ private final SubsystemParser parser = new SubsystemParser();
+
+ private static final String RESOURCE_NAME = AgentSubsystemExtension.class.getPackage().getName()
+ + ".LocalDescriptions";
+
+ protected static final String PLUGINS_ELEMENT = "plugins";
+ protected static final String PLUGIN_ELEMENT = "plugin";
+ protected static final String PLUGIN_NAME = "name";
+ protected static final String PLUGIN_ENABLED = "enabled";
+ protected static final String AGENT_ENABLED = "enabled";
+ protected static final boolean AGENT_ENABLED_DEFAULT = false;
+ protected static final boolean PLUGIN_ENABLED_DEFAULT = true;
+
+ protected static final String AGENT_RESTART_OP = "restart";
+ protected static final String AGENT_STOP_OP = "stop";
+ protected static final String AGENT_STATUS_OP = "status";
+
+ protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+
+ static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) {
+ String prefix = SUBSYSTEM_NAME + (keyPrefix == null ? "" : "." + keyPrefix);
+ return new StandardResourceDescriptionResolver(prefix, RESOURCE_NAME,
+ AgentSubsystemExtension.class.getClassLoader(), true, false);
+ }
+
+ @Override
+ public void initializeParsers(ExtensionParsingContext context) {
+ context.setSubsystemXmlMapping(SUBSYSTEM_NAME, NAMESPACE, parser);
+ }
+
+ @Override
+ public void initialize(ExtensionContext context) {
+ log.info("Initializing embedded agent subsystem");
+
+ final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, 1, 0);
+ final ManagementResourceRegistration registration = subsystem
+ .registerSubsystemModel(AgentSubsystemDefinition.INSTANCE);
+
+ subsystem.registerXMLElementWriter(parser);
+ }
+
+ /**
+ * The subsystem parser, which uses stax to read and write to and from xml
+ */
+ private static class SubsystemParser implements XMLStreamConstants, XMLElementReader<List<ModelNode>>,
+ XMLElementWriter<SubsystemMarshallingContext> {
+
+ @Override
+ public void readElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
+ // The agent "enabled" attribute is required
+ ParseUtils.requireSingleAttribute(reader, AGENT_ENABLED);
+
+ // Add the main subsystem 'add' operation
+ final ModelNode opAdd = new ModelNode();
+ opAdd.get(OP).set(ADD);
+ opAdd.get(OP_ADDR).set(PathAddress.pathAddress(SUBSYSTEM_PATH).toModelNode());
+ String agentEnabledValue = reader.getAttributeValue(null, AGENT_ENABLED);
+ if (agentEnabledValue != null) {
+ opAdd.get(AGENT_ENABLED).set(agentEnabledValue);
+ }
+
+ ModelNode pluginsAttributeNode = opAdd.get(PLUGINS_ELEMENT);
+
+ // Read the children elements
+ while (reader.hasNext() && reader.nextTag() != END_ELEMENT) {
+ if (!reader.getLocalName().equals(PLUGINS_ELEMENT)) {
+ throw ParseUtils.unexpectedElement(reader);
+ }
+ while (reader.hasNext() && reader.nextTag() != END_ELEMENT) {
+ if (reader.isStartElement()) {
+ readPlugin(reader, pluginsAttributeNode);
+ }
+ }
+ }
+
+ list.add(opAdd);
+ }
+
+ private void readPlugin(XMLExtendedStreamReader reader, ModelNode pluginsAttributeNode)
+ throws XMLStreamException {
+
+ if (!reader.getLocalName().equals(PLUGIN_ELEMENT)) {
+ throw ParseUtils.unexpectedElement(reader);
+ }
+
+ String pluginName = null;
+ boolean pluginEnabled = PLUGIN_ENABLED_DEFAULT;
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String attr = reader.getAttributeLocalName(i);
+ String value = reader.getAttributeValue(i);
+ if (attr.equals(PLUGIN_ENABLED)) {
+ pluginEnabled = Boolean.parseBoolean(value);
+ } else if (attr.equals(PLUGIN_NAME)) {
+ pluginName = value;
+ } else {
+ throw ParseUtils.unexpectedAttribute(reader, i);
+ }
+ }
+ ParseUtils.requireNoContent(reader);
+ if (pluginName == null) {
+ throw ParseUtils.missingRequiredElement(reader, Collections.singleton(PLUGIN_NAME));
+ }
+
+ // Add the plugin to the plugins attribute node
+ pluginsAttributeNode.add(pluginName, pluginEnabled);
+ }
+
+ @Override
+ public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context)
+ throws XMLStreamException {
+ ModelNode node = context.getModelNode();
+
+ // <subsystem>
+ context.startSubsystemElement(AgentSubsystemExtension.NAMESPACE, false);
+ writer.writeAttribute(AGENT_ENABLED,
+ String.valueOf(node.get(AGENT_ENABLED).asBoolean(AGENT_ENABLED_DEFAULT)));
+
+ // <plugins>
+ writer.writeStartElement(PLUGINS_ELEMENT);
+ ModelNode plugins = node.get(PLUGINS_ELEMENT);
+ if (plugins != null && plugins.isDefined()) {
+ for (Property property : plugins.asPropertyList()) {
+ // <plugin>
+ writer.writeStartElement(PLUGIN_ELEMENT);
+ writer.writeAttribute(PLUGIN_NAME, property.getName());
+ writer.writeAttribute(PLUGIN_ENABLED, property.getValue().asString());
+ // </plugin>
+ writer.writeEndElement();
+ }
+ }
+ // </plugins>
+ writer.writeEndElement();
+ // </subsystem>
+ writer.writeEndElement();
+ }
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRemove.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRemove.java
new file mode 100644
index 0000000..4f19745
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRemove.java
@@ -0,0 +1,23 @@
+package org.rhq.embeddedagent.extension;
+
+import org.jboss.as.controller.AbstractRemoveStepHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+import org.jboss.msc.service.ServiceName;
+
+class AgentSubsystemRemove extends AbstractRemoveStepHandler {
+
+ static final AgentSubsystemRemove INSTANCE = new AgentSubsystemRemove();
+
+ private AgentSubsystemRemove() {
+ }
+
+ @Override
+ protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model)
+ throws OperationFailedException {
+
+ ServiceName name = AgentService.SERVICE_NAME;
+ context.removeService(name);
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRestart.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRestart.java
new file mode 100644
index 0000000..cdb14fd
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRestart.java
@@ -0,0 +1,36 @@
+package org.rhq.embeddedagent.extension;
+
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.OperationStepHandler;
+import org.jboss.dmr.ModelNode;
+import org.jboss.logging.Logger;
+import org.jboss.msc.service.ServiceName;
+import org.jboss.msc.service.ServiceNotFoundException;
+
+class AgentSubsystemRestart implements OperationStepHandler {
+
+ static final AgentSubsystemRestart INSTANCE = new AgentSubsystemRestart();
+
+ private final Logger log = Logger.getLogger(AgentSubsystemRestart.class);
+
+ private AgentSubsystemRestart() {
+ }
+
+ @Override
+ public void execute(OperationContext opContext, ModelNode model) throws OperationFailedException {
+ try {
+ ServiceName name = AgentService.SERVICE_NAME;
+ AgentService service = (AgentService) opContext.getServiceRegistry(true).getRequiredService(name)
+ .getValue();
+ log.info("Asked to restart the embedded agent");
+ service.stopAgent();
+ service.startAgent();
+ } catch (ServiceNotFoundException snfe) {
+ throw new OperationFailedException("Cannot restart embedded agent - the agent is disabled", snfe);
+ }
+
+ opContext.completeStep();
+ return;
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemStatus.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemStatus.java
new file mode 100644
index 0000000..8b09a21
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemStatus.java
@@ -0,0 +1,32 @@
+package org.rhq.embeddedagent.extension;
+
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.OperationStepHandler;
+import org.jboss.dmr.ModelNode;
+import org.jboss.msc.service.ServiceName;
+import org.jboss.msc.service.ServiceNotFoundException;
+
+class AgentSubsystemStatus implements OperationStepHandler {
+
+ static final AgentSubsystemStatus INSTANCE = new AgentSubsystemStatus();
+
+ private AgentSubsystemStatus() {
+ }
+
+ @Override
+ public void execute(OperationContext opContext, ModelNode model) throws OperationFailedException {
+ boolean isStarted = false;
+ try {
+ ServiceName name = AgentService.SERVICE_NAME;
+ AgentService service = (AgentService) opContext.getServiceRegistry(true).getRequiredService(name)
+ .getValue();
+ isStarted = service.isAgentStarted();
+ } catch (ServiceNotFoundException snfe) {
+ // the agent just isn't deployed, so obviously, is isn't started
+ isStarted = false;
+ }
+ opContext.getResult().set(isStarted ? "STARTED" : "STOPPED");
+ opContext.completeStep();
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemStop.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemStop.java
new file mode 100644
index 0000000..62e7307
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemStop.java
@@ -0,0 +1,34 @@
+package org.rhq.embeddedagent.extension;
+
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.as.controller.OperationStepHandler;
+import org.jboss.dmr.ModelNode;
+import org.jboss.logging.Logger;
+import org.jboss.msc.service.ServiceName;
+
+class AgentSubsystemStop implements OperationStepHandler {
+
+ static final AgentSubsystemStop INSTANCE = new AgentSubsystemStop();
+
+ private final Logger log = Logger.getLogger(AgentSubsystemStop.class);
+
+ private AgentSubsystemStop() {
+ }
+
+ @Override
+ public void execute(OperationContext opContext, ModelNode model) throws OperationFailedException {
+ try {
+ ServiceName name = AgentService.SERVICE_NAME;
+ AgentService service = (AgentService) opContext.getServiceRegistry(true).getRequiredService(name)
+ .getValue();
+ log.info("Asked to stop the embedded agent");
+ service.stopAgent();
+ } catch (Exception e) {
+ // the agent service isn't deployed, so obviously, the agent is already stopped. just keep going
+ }
+
+ opContext.completeStep();
+ return;
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeDefinition.java
new file mode 100644
index 0000000..b925c79
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeDefinition.java
@@ -0,0 +1,56 @@
+package org.rhq.embeddedagent.extension;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.jboss.as.controller.MapAttributeDefinition;
+import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
+import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
+import org.jboss.as.controller.operations.validation.ModelTypeValidator;
+import org.jboss.as.controller.parsing.Attribute;
+import org.jboss.as.controller.registry.AttributeAccess.Flag;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.ModelType;
+
+public class PluginsAttributeDefinition extends MapAttributeDefinition {
+
+ public PluginsAttributeDefinition() {
+ super(AgentSubsystemExtension.PLUGINS_ELEMENT, AgentSubsystemExtension.PLUGINS_ELEMENT, true,
+ 0, Integer.MAX_VALUE, new ModelTypeValidator(ModelType.STRING), null, null, Flag.RESTART_RESOURCE_SERVICES);
+ }
+
+ @Override
+ protected void addValueTypeDescription(ModelNode node, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ protected void addAttributeValueTypeDescription(ModelNode node, ResourceDescriptionResolver resolver,
+ Locale locale, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ protected void addOperationParameterValueTypeDescription(ModelNode node, String operationName,
+ ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ public void marshallAsElement(ModelNode resourceModel, XMLStreamWriter writer) throws XMLStreamException {
+ if (!isMarshallable(resourceModel))
+ return;
+
+ resourceModel = resourceModel.get(getName());
+ writer.writeStartElement(getName());
+ for (ModelNode property : resourceModel.asList()) {
+ writer.writeEmptyElement(getXmlName());
+ writer.writeAttribute(Attribute.NAME.getLocalName(), property.asProperty().getName());
+ writer.writeAttribute(Attribute.VALUE.getLocalName(), property.asProperty().getValue().asString());
+ }
+ writer.writeEndElement();
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeHandler.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeHandler.java
new file mode 100644
index 0000000..1d51294
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeHandler.java
@@ -0,0 +1,62 @@
+package org.rhq.embeddedagent.extension;
+
+import java.util.HashMap;
+import java.util.List;
+
+import org.jboss.as.controller.AbstractWriteAttributeHandler;
+import org.jboss.as.controller.OperationContext;
+import org.jboss.as.controller.OperationFailedException;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.Property;
+import org.jboss.logging.Logger;
+import org.jboss.msc.service.ServiceNotFoundException;
+
+class PluginsAttributeHandler extends AbstractWriteAttributeHandler<Void> {
+
+ public static final PluginsAttributeHandler INSTANCE = new PluginsAttributeHandler();
+
+ private final Logger log = Logger.getLogger(PluginsAttributeHandler.class);
+
+ private PluginsAttributeHandler() {
+ super(AgentSubsystemDefinition.PLUGINS_ATTRIBDEF);
+ }
+
+ @Override
+ protected boolean applyUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode resolvedValue, ModelNode currentValue, HandbackHolder<Void> handbackHolder)
+ throws OperationFailedException {
+
+ log.info("Embedded agent plugins attribute changed: " + attributeName + "=" + resolvedValue);
+ setPluginsWithEnabledFlag(context, resolvedValue);
+ return true; // the service must be restarted to really pick up the change at runtime
+ }
+
+ @Override
+ protected void revertUpdateToRuntime(OperationContext context, ModelNode operation, String attributeName,
+ ModelNode valueToRestore, ModelNode valueToRevert, Void handback) {
+
+ log.info("Reverting embedded agent plugins attribute: " + attributeName + "=" + valueToRestore);
+ setPluginsWithEnabledFlag(context, valueToRestore);
+ }
+
+ private void setPluginsWithEnabledFlag(OperationContext context, ModelNode newValue) {
+
+ try {
+ AgentService service = (AgentService) context.getServiceRegistry(true)
+ .getRequiredService(AgentService.SERVICE_NAME).getValue();
+
+ HashMap<String, Boolean> pluginsWithEnableFlag = new HashMap<String, Boolean>();
+ if (newValue != null && newValue.isDefined()) {
+ List<Property> pluginsList = newValue.asPropertyList();
+ for (Property pluginsItem : pluginsList) {
+ String pluginName = pluginsItem.getName();
+ boolean pluginEnabled = pluginsItem.getValue().asBoolean();
+ pluginsWithEnableFlag.put(pluginName, pluginEnabled);
+ }
+ }
+ service.setPlugins(pluginsWithEnableFlag);
+ } catch (ServiceNotFoundException snfe) {
+ // the agent is probably disabled or undeployed, don't bother doing anything
+ }
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/META-INF/services/org.jboss.as.controller.Extension b/modules/enterprise/server/embeddedagent/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
new file mode 100644
index 0000000..d8addaa
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/META-INF/services/org.jboss.as.controller.Extension
@@ -0,0 +1 @@
+org.rhq.embeddedagent.extension.AgentSubsystemExtension
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
new file mode 100644
index 0000000..295c78d
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<module xmlns="urn:jboss:module:1.0" name="${moduleName}">
+
+ <resources>
+ <resource-root path="${project.build.finalName}.jar"/>
+ <!-- <resource-root path="agent" /> -->
+ </resources>
+
+ <dependencies>
+ <!-- modules required by any subsystem -->
+ <module name="javax.api"/>
+ <module name="org.jboss.staxmapper"/>
+ <module name="org.jboss.as.controller"/>
+ <module name="org.jboss.as.server"/>
+ <module name="org.jboss.modules"/>
+ <module name="org.jboss.msc"/>
+ <module name="org.jboss.logging"/>
+ <module name="org.jboss.vfs"/>
+ </dependencies>
+</module>
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
new file mode 100644
index 0000000..790232a
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
@@ -0,0 +1,8 @@
+embeddedagent=RHQ Agent
+embeddedagent.add=Adds the RHQ Agent subsystem
+embeddedagent.remove=Removes the RHQ Agent subsystem
+embeddedagent.restart=Starts the RHQ Agent. If it is already started, it will be stopped, then started again.
+embeddedagent.stop=Stops the RHQ Agent if it is running.
+embeddedagent.status=Tells you if the RHQ Agent is currently started or stopped.
+embeddedagent.enabled=When true, the RHQ Agent will be deployed and started. Otherwise, it will be disabled.
+embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
\ No newline at end of file
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
new file mode 100644
index 0000000..2882729
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
@@ -0,0 +1,26 @@
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="urn:org.rhq:embeddedagent:1.0"
+ xmlns="urn:org.rhq.embeddedagent:1.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ version="1.0">
+
+ <xs:element name="subsystem" type="subsystemType"/>
+
+ <xs:complexType name="subsystemType">
+ <xs:attribute name="enabled" type="xs:boolean" use="required" default="false"/>
+ <xs:all>
+ <xs:element name="plugins" type="pluginsType"/>
+ </xs:all>
+ </xs:complexType>
+
+ <xs:complexType name="pluginsType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="plugin" type="pluginType"/>
+ </xs:choice>
+ </xs:complexType>
+ <xs:complexType name="pluginType">
+ <xs:attribute name="name" use="required"/>
+ <xs:attribute name="enabled" type="xs:boolean" use="required" default="true"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml b/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
new file mode 100644
index 0000000..a4cab0a
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<assembly>
+ <id>module-assembly</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <baseDirectory>${project.build.finalName}-module</baseDirectory>
+ <fileSets>
+ <fileSet>
+ <directory>${project.build.outputDirectory}/module</directory>
+ <outputDirectory>/org/rhq/${artifactId}</outputDirectory>
+ <includes>
+ <include>main/module.xml</include>
+ </includes>
+ <fileMode>0644</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ <fileSet>
+ <directory>${project.build.directory}</directory>
+ <outputDirectory>/org/rhq/${artifactId}/main</outputDirectory>
+ <includes>
+ <include>${project.build.finalName}.jar</include>
+ </includes>
+ <fileMode>0644</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ <fileSet>
+ <directory>${project.build.directory}/agent</directory>
+ <outputDirectory>/org/rhq/${artifactId}/main/agent</outputDirectory>
+ <fileMode>0644</fileMode>
+ <directoryMode>0755</directoryMode>
+ </fileSet>
+ </fileSets>
+</assembly>
+
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemBaseParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemBaseParsingTestCase.java
new file mode 100644
index 0000000..2d5b3a5
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemBaseParsingTestCase.java
@@ -0,0 +1,17 @@
+package org.rhq.embeddedagent.extension;
+
+import java.io.IOException;
+
+import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest;
+
+public class SubsystemBaseParsingTestCase extends AbstractSubsystemBaseTest {
+
+ public SubsystemBaseParsingTestCase() {
+ super(AgentSubsystemExtension.SUBSYSTEM_NAME, new AgentSubsystemExtension());
+ }
+
+ @Override
+ protected String getSubsystemXml() throws IOException {
+ return readResource("subsystem.xml");
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
new file mode 100644
index 0000000..40054b9
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -0,0 +1,301 @@
+package org.rhq.embeddedagent.extension;
+
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIBE;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NAME;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_ATTRIBUTE_OPERATION;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_RESOURCE_DESCRIPTION_OPERATION;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE;
+import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.WRITE_ATTRIBUTE_OPERATION;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.as.controller.PathAddress;
+import org.jboss.as.controller.PathElement;
+import org.jboss.as.subsystem.test.KernelServices;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.Property;
+import org.jboss.msc.service.ServiceNotFoundException;
+import org.testng.Assert;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+@Test
+public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
+
+ @Override
+ @BeforeTest
+ public void initializeParser() throws Exception {
+ super.initializeParser();
+ }
+
+ @Override
+ @AfterTest
+ public void cleanup() throws Exception {
+ super.cleanup();
+ }
+
+ /**
+ * Tests that the xml is parsed into the correct operations
+ */
+ public void testParseSubsystem() throws Exception {
+ // Parse the subsystem xml into operations
+ String subsystemXml = getSubsystemXml();
+ List<ModelNode> operations = super.parse(subsystemXml);
+
+ // /Check that we have the expected number of operations
+ Assert.assertEquals(operations.size(), 1);
+
+ // Check that each operation has the correct content
+ // The add subsystem operation will happen first
+ ModelNode addSubsystem = operations.get(0);
+ Assert.assertEquals(addSubsystem.get(OP).asString(), ADD);
+ PathAddress addr = PathAddress.pathAddress(addSubsystem.get(OP_ADDR));
+ Assert.assertEquals(addr.size(), 1);
+ PathElement element = addr.getElement(0);
+ Assert.assertEquals(element.getKey(), SUBSYSTEM);
+ Assert.assertEquals(element.getValue(), AgentSubsystemExtension.SUBSYSTEM_NAME);
+ Assert.assertEquals(addSubsystem.get(AgentSubsystemExtension.AGENT_ENABLED).asBoolean(), true);
+ List<Property> plugins = addSubsystem.get(AgentSubsystemExtension.PLUGINS_ELEMENT).asPropertyList();
+ Assert.assertEquals(plugins.size(), 2);
+ Assert.assertEquals(plugins.get(0).getName(), "platform"); // platform plugin is first in the xml
+ Assert.assertEquals(plugins.get(0).getValue().asBoolean(), true);
+ Assert.assertEquals(plugins.get(1).getName(), "blah"); // blah plugin is first in the xml
+ Assert.assertEquals(plugins.get(1).getValue().asBoolean(), false);
+ }
+
+ /**
+ * Test that the model created from the xml looks as expected
+ */
+ public void testInstallIntoController() throws Exception {
+ // Parse the subsystem xml and install into the controller
+ String subsystemXml = getSubsystemXml();
+ KernelServices services = super.installInController(subsystemXml);
+
+ // Read the whole model and make sure it looks as expected
+ ModelNode model = services.readWholeModel();
+ // System.out.println(model);
+ Assert.assertTrue(model.get(SUBSYSTEM).hasDefined(AgentSubsystemExtension.SUBSYSTEM_NAME));
+ Assert.assertTrue(model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME).hasDefined(
+ AgentSubsystemExtension.AGENT_ENABLED));
+ Assert.assertTrue(model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME,
+ AgentSubsystemExtension.AGENT_ENABLED).asBoolean());
+ Assert.assertTrue(model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME).hasDefined(
+ AgentSubsystemExtension.PLUGINS_ELEMENT));
+
+ List<Property> plugins = model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME)
+ .get(AgentSubsystemExtension.PLUGINS_ELEMENT).asPropertyList();
+ Assert.assertEquals(plugins.size(), 2);
+ Assert.assertEquals(plugins.get(0).getName(), "platform"); // platform plugin is first in the xml
+ Assert.assertEquals(plugins.get(0).getValue().asBoolean(), true);
+ Assert.assertEquals(plugins.get(1).getName(), "blah"); // blah plugin is first in the xml
+ Assert.assertEquals(plugins.get(1).getValue().asBoolean(), false);
+
+ // Sanity check to test the service was there
+ AgentService agent = (AgentService) services.getContainer().getRequiredService(AgentService.SERVICE_NAME)
+ .getValue();
+ assert 2 == agent.getPlugins().size();
+ Assert.assertTrue(agent.getPlugins().get("platform"));
+ Assert.assertFalse(agent.getPlugins().get("blah"));
+ }
+
+ /**
+ * Starts a controller with a given subsystem xml and then checks that a second controller started with the xml
+ * marshalled from the first one results in the same model
+ */
+ public void testParseAndMarshalModel() throws Exception {
+ // Parse the subsystem xml and install into the first controller
+ String subsystemXml = getSubsystemXml();
+ KernelServices servicesA = super.installInController(subsystemXml);
+ // Get the model and the persisted xml from the first controller
+ ModelNode modelA = servicesA.readWholeModel();
+ String marshalled = servicesA.getPersistedSubsystemXml();
+
+ // Install the persisted xml from the first controller into a second controller
+ KernelServices servicesB = super.installInController(marshalled);
+ ModelNode modelB = servicesB.readWholeModel();
+
+ // Make sure the models from the two controllers are identical
+ super.compare(modelA, modelB);
+ }
+
+ /**
+ * Starts a controller with the given subsystem xml and then checks that a second controller started with the
+ * operations from its describe action results in the same model
+ */
+ public void testDescribeHandler() throws Exception {
+ // test two subsystem xmls - one that is empty of plugins, and the second is our normal test xml
+ String subsystemXml1 = "<subsystem xmlns=\"" + AgentSubsystemExtension.NAMESPACE + "\" "
+ + AgentSubsystemExtension.AGENT_ENABLED + "=\"true\"" + "></subsystem>";
+ String subsystemXml2 = getSubsystemXml();
+
+ String[] subsystemXmlAll = new String[] { subsystemXml1, subsystemXml2 };
+ for (String subsystemXml : subsystemXmlAll) {
+ KernelServices servicesA = super.installInController(subsystemXml);
+ // Get the model and the describe operations from the first controller
+ ModelNode modelA = servicesA.readWholeModel();
+ ModelNode describeOp = new ModelNode();
+ describeOp.get(OP).set(DESCRIBE);
+ describeOp.get(OP_ADDR).set(
+ PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME))
+ .toModelNode());
+ ModelNode executeOperation = servicesA.executeOperation(describeOp);
+ List<ModelNode> operations = super.checkResultAndGetContents(executeOperation).asList();
+
+ // Install the describe options from the first controller into a second controller
+ KernelServices servicesB = super.installInController(operations);
+ ModelNode modelB = servicesB.readWholeModel();
+
+ // Make sure the models from the two controllers are identical
+ super.compare(modelA, modelB);
+ }
+ }
+
+ /**
+ * Tests that the subsystem can be removed
+ */
+ public void testSubsystemRemoval() throws Exception {
+ // Parse the subsystem xml and install into the first controller
+ String subsystemXml = getSubsystemXml();
+ KernelServices services = super.installInController(subsystemXml);
+
+ // Sanity check to test the service was there
+ AgentService agent = (AgentService) services.getContainer().getRequiredService(AgentService.SERVICE_NAME)
+ .getValue();
+ Assert.assertEquals(agent.getPlugins().size(), 2);
+
+ // Checks that the subsystem was removed from the model
+ super.assertRemoveSubsystemResources(services);
+
+ // Check that the services that was installed was removed
+ try {
+ services.getContainer().getRequiredService(AgentService.SERVICE_NAME);
+ assert false : "The service should have been removed along with the subsystem";
+ } catch (ServiceNotFoundException expected) {
+ // test passed!
+ }
+ }
+
+ public void testResourceDescription() throws Exception {
+ String subsystemXml = getSubsystemXml();
+ KernelServices services = super.installInController(subsystemXml);
+
+ PathAddress agentSubsystemPath = PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM,
+ AgentSubsystemExtension.SUBSYSTEM_NAME));
+
+ // ask for resource description: /subsystem=embeddedagent:read-resource-description
+ ModelNode resourceDescriptionOp = new ModelNode();
+ resourceDescriptionOp.get(OP).set(READ_RESOURCE_DESCRIPTION_OPERATION);
+ resourceDescriptionOp.get(OP_ADDR).set(agentSubsystemPath.toModelNode());
+ resourceDescriptionOp.get("operations").set(true); // we want to see the operations also
+ ModelNode result = services.executeOperation(resourceDescriptionOp);
+ ModelNode content = checkResultAndGetContents(result);
+
+ // check the attributes
+ Assert.assertTrue(content.get("attributes").isDefined());
+ List<Property> attributes = content.get("attributes").asPropertyList();
+ Assert.assertEquals(attributes.size(), 2);
+ Assert.assertEquals(attributes.get(0).getName(), AgentSubsystemExtension.AGENT_ENABLED);
+ Assert.assertEquals(attributes.get(1).getName(), AgentSubsystemExtension.PLUGINS_ELEMENT);
+
+ // check the operations
+ Assert.assertTrue(content.get("operations").isDefined());
+ List<Property> operations = content.get("operations").asPropertyList();
+ List<String> operationNames = new ArrayList<String>();
+ for (Property op : operations) {
+ operationNames.add(op.getName());
+ }
+ Assert.assertTrue(operationNames.contains(AgentSubsystemExtension.AGENT_RESTART_OP));
+ Assert.assertTrue(operationNames.contains(AgentSubsystemExtension.AGENT_STOP_OP));
+ Assert.assertTrue(operationNames.contains(AgentSubsystemExtension.AGENT_STATUS_OP));
+ }
+
+ public void testExecuteOperations() throws Exception {
+ String subsystemXml = getSubsystemXml();
+ KernelServices services = super.installInController(subsystemXml);
+
+ // status check - our service should be available and have 2 plugin definitions
+ AgentService service = (AgentService) services.getContainer().getService(AgentService.SERVICE_NAME).getValue();
+ Assert.assertEquals(service.getPlugins().size(), 2);
+
+ PathAddress agentSubsystemPath = PathAddress.pathAddress(PathElement.pathElement(SUBSYSTEM,
+ AgentSubsystemExtension.SUBSYSTEM_NAME));
+
+ // get the startup model from subsystem xml
+ ModelNode model = services.readWholeModel();
+
+ // current list of plugins from the attribute
+ ModelNode pluginsNode = model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME).get(
+ AgentSubsystemExtension.PLUGINS_ELEMENT);
+
+ // Add another plugin
+ pluginsNode.add("foo", true);
+ ModelNode addOp = new ModelNode();
+ addOp.get(OP).set(WRITE_ATTRIBUTE_OPERATION);
+ addOp.get(OP_ADDR).set(agentSubsystemPath.toModelNode());
+ addOp.get(NAME).set(AgentSubsystemExtension.PLUGINS_ELEMENT);
+ addOp.get(VALUE).set(pluginsNode);
+ ModelNode result = services.executeOperation(addOp);
+ Assert.assertEquals(result.get(OUTCOME).asString(), SUCCESS);
+
+ // now test that things are as they should be
+ model = services.readWholeModel();
+ Assert.assertTrue(model.get(SUBSYSTEM).hasDefined(AgentSubsystemExtension.SUBSYSTEM_NAME));
+ Assert.assertTrue(model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME).hasDefined(
+ AgentSubsystemExtension.AGENT_ENABLED));
+ Assert.assertTrue(model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME,
+ AgentSubsystemExtension.AGENT_ENABLED).asBoolean());
+ Assert.assertTrue(model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME).hasDefined(
+ AgentSubsystemExtension.PLUGINS_ELEMENT));
+
+ List<Property> plugins = model.get(SUBSYSTEM, AgentSubsystemExtension.SUBSYSTEM_NAME)
+ .get(AgentSubsystemExtension.PLUGINS_ELEMENT).asPropertyList();
+ Assert.assertEquals(plugins.size(), 3); // there were 2, but we added "foo" above
+ Assert.assertEquals(plugins.get(0).getName(), "platform"); // platform plugin is first in the xml
+ Assert.assertEquals(plugins.get(0).getValue().asBoolean(), true);
+ Assert.assertEquals(plugins.get(1).getName(), "blah"); // blah plugin is first in the xml
+ Assert.assertEquals(plugins.get(1).getValue().asBoolean(), false);
+ Assert.assertEquals(plugins.get(2).getName(), "foo"); // foo plugin we added above
+ Assert.assertEquals(plugins.get(2).getValue().asBoolean(), true);
+
+ // we enabled a new plugin - now should have 3 now
+ Assert.assertEquals(service.getPlugins().size(), 3);
+ Assert.assertTrue(service.getPlugins().get("platform"));
+ Assert.assertFalse(service.getPlugins().get("blah"));
+ Assert.assertTrue(service.getPlugins().get("foo"));
+
+ // Use read-attribute instead of reading the whole model to get an attribute value
+ ModelNode readOp = new ModelNode();
+ readOp.get(OP).set(READ_ATTRIBUTE_OPERATION);
+ readOp.get(OP_ADDR).set(agentSubsystemPath.toModelNode());
+ readOp.get(NAME).set(AgentSubsystemExtension.AGENT_ENABLED);
+ result = services.executeOperation(readOp);
+ Assert.assertTrue(checkResultAndGetContents(result).asBoolean());
+
+ readOp.get(NAME).set(AgentSubsystemExtension.PLUGINS_ELEMENT);
+ result = services.executeOperation(readOp);
+ ModelNode content = checkResultAndGetContents(result);
+ plugins = content.asPropertyList();
+ Assert.assertEquals(plugins.size(), 3); // there were 2, but we added "foo" above
+ Assert.assertEquals(plugins.get(0).getName(), "platform"); // platform plugin is first in the xml
+ Assert.assertEquals(plugins.get(0).getValue().asBoolean(), true);
+ Assert.assertEquals(plugins.get(1).getName(), "blah"); // blah plugin is first in the xml
+ Assert.assertEquals(plugins.get(1).getValue().asBoolean(), false);
+ Assert.assertEquals(plugins.get(2).getName(), "foo"); // foo plugin we added above
+ Assert.assertEquals(plugins.get(2).getValue().asBoolean(), true);
+
+ // execute status
+ ModelNode statusOp = new ModelNode();
+ statusOp.get(OP).set(AgentSubsystemExtension.AGENT_STATUS_OP);
+ statusOp.get(OP_ADDR).set(agentSubsystemPath.toModelNode());
+ result = services.executeOperation(statusOp);
+ Assert.assertEquals(checkResultAndGetContents(result).asString(), "STARTED");
+ }
+}
diff --git a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
new file mode 100644
index 0000000..4e4a85d
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
@@ -0,0 +1,6 @@
+<subsystem xmlns="urn:org.rhq:embeddedagent:1.0" enabled="true">
+ <plugins>
+ <plugin name="platform" enabled="true" />
+ <plugin name="blah" enabled="false" />
+ </plugins>
+</subsystem>
\ No newline at end of file
commit 56f372fca0ff1c299ed206c6d387d7d6517209c7
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 3 16:28:42 2014 -0500
disable the hibernate.query.factory_class override in persistence.xml now
that the feature has stabilized.
diff --git a/modules/core/domain/src/main/resources/META-INF/persistence.xml b/modules/core/domain/src/main/resources/META-INF/persistence.xml
index 1bbd8c2..a15fd2e 100644
--- a/modules/core/domain/src/main/resources/META-INF/persistence.xml
+++ b/modules/core/domain/src/main/resources/META-INF/persistence.xml
@@ -21,7 +21,9 @@
<!--<property name="com.intellij.javaee.persistence.datasource" value="rhq-oracle" />-->
<property name="com.intellij.javaee.persistence.datasource" value="rhq-postgres" />
+ <!-- Used only for debugging the usages of JOIN FETCHes
<property name="hibernate.query.factory_class" value="org.rhq.core.domain.util.JoinFetchReportingQueryTranslatorFactory" />
+ -->
<!-- This value doesn't have any theoretical grounds and is purely based on experiments. Value of 32 gives
the best compromise between the quick load of queries with low and high limits (i.e. page size in tens vs.
commit 6b3d68b582f2ac263e5c1074facaecd6e9f84b55
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 3 16:14:27 2014 -0500
Fix test failure due to new compacted resource config files being under
the agent datadir.
diff --git a/modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java b/modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java
index 60cd53d..0511a39 100644
--- a/modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java
+++ b/modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java
@@ -151,6 +151,9 @@ public class CleanUpTest extends Arquillian {
//the "changesets" directory is going to always be there because it is eagerly created during PC startup.
sExpected.add("changesets");
+ //the "rc" directory is probably going to be there because it contains compacted resource configs
+ sActual.remove("rc");
+
assertEquals(sActual, sExpected, message);
}
}
commit ea1f3b883340dd4db2724f01e80484a497c4f048
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 3 12:29:48 2014 -0500
[1059932] PC classes must use data directory configured in PC, not just use "data"
Change things around to us the proper data directory, as configured for the
plugin container (via InventoryManager)
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationCheckExecutor.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationCheckExecutor.java
index da70b18..666281f 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationCheckExecutor.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationCheckExecutor.java
@@ -39,6 +39,7 @@ import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.inventory.ResourceContainer;
import org.rhq.core.pc.util.FacetLockType;
@@ -52,13 +53,10 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
private static final Log log = LogFactory.getLog(ConfigurationCheckExecutor.class);
private ConfigurationServerService configurationServerService;
- private InventoryManager inventoryManager;
private static final long CONFIGURATION_CHECK_TIMEOUT = 30000L;
- public ConfigurationCheckExecutor(ConfigurationServerService configurationServerService,
- InventoryManager inventoryManager) {
+ public ConfigurationCheckExecutor(ConfigurationServerService configurationServerService) {
this.configurationServerService = configurationServerService;
- this.inventoryManager = inventoryManager;
}
public void run() {
@@ -70,14 +68,16 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
long start = System.currentTimeMillis();
CountTime countTime;
- countTime = checkConfigurations(this.inventoryManager.getPlatform(), true);
- log.info("Configuration update check for [" + countTime.count + "] resources completed in " +
- (System.currentTimeMillis() - start)/1000 + "s wall time, " + countTime.time + "ms check time");
+ InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager();
+ Resource platform = inventoryManager.getPlatform();
+ countTime = checkConfigurations(inventoryManager, platform, true);
+ log.info("Configuration update check for [" + countTime.count + "] resources completed in "
+ + (System.currentTimeMillis() - start) / 1000 + "s wall time, " + countTime.time + "ms check time");
return null;
}
- public CountTime checkConfigurations(Resource resource, boolean checkChildren) {
- ResourceContainer resourceContainer = this.inventoryManager.getResourceContainer(resource.getId());
+ public CountTime checkConfigurations(InventoryManager inventoryManager, Resource resource, boolean checkChildren) {
+ ResourceContainer resourceContainer = inventoryManager.getResourceContainer(resource.getId());
ConfigurationFacet resourceComponent = null;
ResourceType resourceType = resource.getResourceType();
@@ -93,7 +93,7 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
FacetLockType.NONE, CONFIGURATION_CHECK_TIMEOUT, true, false, true);
} catch (PluginContainerException e) {
// Expecting when the resource does not support configuration management
- // Should never happen after above check
+ // Should never happen after above check
}
}
@@ -104,7 +104,6 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
long t1 = System.currentTimeMillis();
-
if (debugEnabled) {
log.debug("Checking for updated Resource configuration for " + resource + "...");
}
@@ -117,7 +116,8 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
.getResourceConfigurationDefinition();
// Normalize and validate the config.
- ConfigurationUtility.normalizeConfiguration(liveConfiguration, configurationDefinition,true,true);
+ ConfigurationUtility.normalizeConfiguration(liveConfiguration, configurationDefinition,
+ true, true);
List<String> errorMessages = ConfigurationUtility.validateConfiguration(liveConfiguration,
configurationDefinition);
for (String errorMessage : errorMessages) {
@@ -126,10 +126,10 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
+ errorMessage);
}
- Configuration original = getResourceConfiguration(resource);
+ Configuration original = getResourceConfiguration(inventoryManager, resource);
- if (original==null) {
- original = loadConfigurationFromFile(resource.getId());
+ if (original == null) {
+ original = loadConfigurationFromFile(inventoryManager, resource.getId());
}
if (!liveConfiguration.equals(original)) {
@@ -138,8 +138,9 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
}
this.configurationServerService.persistUpdatedResourceConfiguration(resource.getId(),
liveConfiguration);
-// resource.setResourceConfiguration(liveConfiguration);
- boolean persisted = persistConfigurationToFile(resource.getId(),liveConfiguration, log);
+ // resource.setResourceConfiguration(liveConfiguration);
+ boolean persisted = persistConfigurationToFile(inventoryManager, resource.getId(),
+ liveConfiguration, log);
if (persisted) {
resource.setResourceConfiguration(null);
}
@@ -151,22 +152,22 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
}
long now = System.currentTimeMillis();
- countTime.add(1,(now-t1));
+ countTime.add(1, (now - t1));
// Give the agent some time to breathe
try {
Thread.sleep(750);
} catch (InterruptedException e) {
; // We don't care
+ }
}
}
- }
if (checkChildren) {
- for (Resource child : this.inventoryManager.getContainerChildren(resource, resourceContainer)) {
+ for (Resource child : inventoryManager.getContainerChildren(resource, resourceContainer)) {
try {
- CountTime inner = checkConfigurations(child, true);
- countTime.add(inner.count,inner.time);
+ CountTime inner = checkConfigurations(inventoryManager, child, true);
+ countTime.add(inner.count, inner.time);
} catch (Exception e) {
log.error("Failed to check Resource configuration for " + child + ".", e);
}
@@ -176,20 +177,22 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
return countTime;
}
- public static Configuration getResourceConfiguration(Resource resource) {
+ static public Configuration getResourceConfiguration(InventoryManager inventoryManager, Resource resource) {
Configuration result = resource.getResourceConfiguration();
if (null == result) {
- result = loadConfigurationFromFile(resource.getId());
+ result = loadConfigurationFromFile(inventoryManager, resource.getId());
}
return result;
}
- public static boolean persistConfigurationToFile(int resourceId, Configuration liveConfiguration, Log log) {
+ static public boolean persistConfigurationToFile(InventoryManager inventoryManager, int resourceId,
+ Configuration liveConfiguration, Log log) {
boolean success = true;
try {
- String pathname = "data/rc/" + String.valueOf(resourceId/1000); // Don't put too many files into one data dir
- File dataDir = new File(pathname);
+ File baseDataDir = inventoryManager.getDataDirectory();
+ String pathname = "rc/" + String.valueOf(resourceId / 1000); // Don't put too many files into one data dir
+ File dataDir = new File(baseDataDir, pathname);
if (!dataDir.exists()) {
success = dataDir.mkdirs();
if (!success) {
@@ -213,9 +216,10 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
}
- static private Configuration loadConfigurationFromFile(int resourceId) {
- String pathname = "data/rc/" + String.valueOf(resourceId/1000); // Don't put too many files into one data dir
- File dataDir = new File(pathname);
+ static private Configuration loadConfigurationFromFile(InventoryManager inventoryManager, int resourceId) {
+ File baseDataDir = inventoryManager.getDataDirectory();
+ String pathname = "rc/" + String.valueOf(resourceId / 1000); // Don't put too many files into one data dir
+ File dataDir = new File(baseDataDir, pathname);
File file = new File(dataDir, String.valueOf(resourceId));
if (!file.exists()) {
log.error("File " + file.getAbsolutePath() + " does not exist");
@@ -239,21 +243,18 @@ public class ConfigurationCheckExecutor implements Runnable, Callable {
}
private static class CountTime {
- private long count=0;
- private long time=0;
+ private long count = 0L;
+ private long time = 0L;
private void add(long count, long time) {
- this.count +=count;
- this.time +=time;
+ this.count += count;
+ this.time += time;
}
@Override
public String toString() {
- return "CountTime{" +
- "count=" + count +
- ", time=" + time +
- '}';
+ return "CountTime{" + "count=" + count + ", time=" + time + '}';
}
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
index 393d392..dfb6412 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/configuration/ConfigurationManager.java
@@ -81,13 +81,13 @@ public class ConfigurationManager extends AgentService implements ContainerServi
threadPool = new ScheduledThreadPoolExecutor(1, threadFactory);
ConfigurationCheckExecutor configurationChecker = new ConfigurationCheckExecutor(
- getConfigurationServerService(), PluginContainer.getInstance().getInventoryManager());
+ getConfigurationServerService());
if (pluginContainerConfiguration.getConfigurationDiscoveryPeriod() > 0
&& pluginContainerConfiguration.isInsideAgent()) {
- threadPool.scheduleAtFixedRate(configurationChecker, pluginContainerConfiguration
- .getConfigurationDiscoveryInitialDelay(), pluginContainerConfiguration
- .getConfigurationDiscoveryPeriod(), TimeUnit.SECONDS);
+ threadPool.scheduleAtFixedRate(configurationChecker,
+ pluginContainerConfiguration.getConfigurationDiscoveryInitialDelay(),
+ pluginContainerConfiguration.getConfigurationDiscoveryPeriod(), TimeUnit.SECONDS);
}
}
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
index ca940cb..aed76d9 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/inventory/InventoryManager.java
@@ -1864,6 +1864,10 @@ public class InventoryManager extends AgentService implements ContainerService,
+ "] as it is already in the process of starting.");
return false;
+ default:
+ log.error("Unexpected state [" + state.name() + "], returning false...");
+
+ return false;
}
} else {
if (log.isTraceEnabled()) {
@@ -2038,6 +2042,13 @@ public class InventoryManager extends AgentService implements ContainerService,
}
}
+ /**
+ * @return The location for [plugins] to write data files
+ */
+ public File getDataDirectory() {
+ return this.configuration.getDataDirectory();
+ }
+
private <T extends ResourceComponent<?>> ResourceContext<T> createResourceContext(Resource resource,
T parentComponent, ResourceContext<?> parentResourceContext, ResourceDiscoveryComponent<T> discoveryComponent) {
@@ -2047,7 +2058,7 @@ public class InventoryManager extends AgentService implements ContainerService,
discoveryComponent, // the discovery component (this is actually the proxy to it)
SystemInfoFactory.createSystemInfo(), // for native access
this.configuration.getTemporaryDirectory(), // location for plugin to write temp files
- this.configuration.getDataDirectory(), // location for plugin to write data files
+ this.configuration.getDataDirectory(), // base location for plugin to write data files
this.configuration.getContainerName(), // the name of the agent/PC
getEventContext(resource), // for event access
getOperationContext(resource), // for operation manager access
@@ -3073,7 +3084,7 @@ public class InventoryManager extends AgentService implements ContainerService,
if (resourceConfiguration != null) {
resourceConfiguration.cleanoutRawConfiguration();
- boolean persisted = ConfigurationCheckExecutor.persistConfigurationToFile(resource.getId(),
+ boolean persisted = ConfigurationCheckExecutor.persistConfigurationToFile(this, resource.getId(),
resourceConfiguration, log);
if (persisted) {
resource.setResourceConfiguration(null);
@@ -3082,7 +3093,8 @@ public class InventoryManager extends AgentService implements ContainerService,
}
public static Configuration getResourceConfiguration(Resource agentSideResource) {
- return ConfigurationCheckExecutor.getResourceConfiguration(agentSideResource);
+ return ConfigurationCheckExecutor.getResourceConfiguration(PluginContainer.getInstance().getInventoryManager(),
+ agentSideResource);
}
private void compactConfiguration(Configuration config) {
@@ -3487,6 +3499,9 @@ public class InventoryManager extends AgentService implements ContainerService,
}
break;
}
+ default:
+ // nothing to do for other states
+ break;
}
container.setSynchronizationState(ResourceContainer.SynchronizationState.SYNCHRONIZED);
commit 5bd9673b5d08f51e933438132e63d7620354de9c
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 3 12:00:11 2014 -0500
Fix: was logging as the wrong class.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/SnapshotGenerator.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/SnapshotGenerator.java
index e6c4d07..bdc84f4 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/SnapshotGenerator.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/drift/SnapshotGenerator.java
@@ -1,10 +1,6 @@
package org.rhq.core.pc.drift;
-import org.apache.commons.io.DirectoryWalker;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import static java.io.File.separator;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@@ -21,14 +17,17 @@ import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
-import org.rhq.core.pc.configuration.ConfigurationCheckExecutor;
-import org.rhq.core.util.MessageDigestGenerator;
+import org.apache.commons.io.DirectoryWalker;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
-import static java.io.File.separator;
+import org.rhq.core.util.MessageDigestGenerator;
public class SnapshotGenerator extends DirectoryWalker {
- private final Log log = LogFactory.getLog(ConfigurationCheckExecutor.class);
+ private final Log log = LogFactory.getLog(SnapshotGenerator.class);
private MessageDigestGenerator digestGenerator = new MessageDigestGenerator(MessageDigestGenerator.SHA_256);
commit b5a6da4f2560725799fde0e033cf51e424bc9e5d
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Feb 3 09:38:57 2014 +0100
BZ 1039188 - fix a typo.
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
index 686b9bb..6be2e1b 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
@@ -749,14 +749,14 @@ view_adminTopology_storageNodes_clusterSettings_deployments = New Deployment Set
view_adminTopology_storageNodes_clusterSettings_deployments_autoDeploy = If this is set, the newly installed Storage Nodes will be automatically deployed to the Storage Cluster. It only applies to new installations.
view_adminTopology_storageNodes_clusterSettings_deployments_autoDeploy_title = Automatic Deployment
view_adminTopology_storageNodes_clusterSettings_deployments_desc = Only applies to new installations.
-view_adminTopology_storageNodes_clusterSettings_message_cantLoad = Unable to load common Storage Cluster configuration:
+view_adminTopology_storageNodes_clusterSettings_message_cantLoad = Unable to load common Storage Cluster configuration:
view_adminTopology_storageNodes_clusterSettings_message_confirmation = Changing the cluster wide configuration will eventually affect all the Storage Nodes. Do you want to continue?
view_adminTopology_storageNodes_clusterSettings_message_updateFail = Unable to update the Storage Node settings.
view_adminTopology_storageNodes_clusterSettings_message_updateSuccess = Storage Cluster settings were successfully updated.
view_adminTopology_storageNodes_detail_associatedResource = Associated Resource
view_adminTopology_storageNodes_detail_chart = Chart
view_adminTopology_storageNodes_detail_configuration = Configuration
-view_adminTopology_storageNodes_detail_errorAlertFetch = Unable to fetch alerts for storage node with id {0}. Caused by:
+view_adminTopology_storageNodes_detail_errorAlertFetch = Unable to fetch alerts for storage node with id {0}. Caused by:
view_adminTopology_storageNodes_detail_errorDeployment = Deployment error
view_adminTopology_storageNodes_detail_errorFailedDeployOp = Failed deployment operation
view_adminTopology_storageNodes_detail_errorFailedUneployOp = Failed undeployment operation
@@ -1338,7 +1338,7 @@ view_bundle_createWizard_groupsStep_assigned = The new bundle version is for an
view_bundle_createWizard_groupsStep_failedAssign = Failed to assigned initial bundle groups to a bundle named [{0}] with a version of [{1}]. Please cancel the create wizard and notify your administrator.
view_bundle_createWizard_groupsStep_failedGetAssignable = Failed to determine assignable bundle groups. Please cancel the create wizard and notify your administrator.
view_bundle_createWizard_groupsStep_help = A new bundle is created when uploading the first version for that bundle. The new bundle is then assigned to its initial bundle groups. A user can only assign the new bundle to bundle groups for which he has Create Bundles permission, either global or at the bundle group level. At least one bundle group must be assigned unless the user has global Create and global View Bundles permission, in which case it can be left unassigned.
-view_bundle_createWizard_groupsStep_leaveUnassigned = Leave the new bundle unsassigned.
+view_bundle_createWizard_groupsStep_leaveUnassigned = Leave the new bundle unassigned.
view_bundle_createWizard_groupsStep_noAssignable = Unable to create initial bundle version because the user has no bundle groups to which it can be assigned. Please cancel the create wizard and notify your administrator.
view_bundle_createWizard_groupsStep_noneAssigned = The new bundle version must be assigned to at least one bundle group!
view_bundle_createWizard_groupsStep_radioTitle = Initial bundle group assignment for the new bundle
commit 746acfd0473f74a33f47b734f036a76659f1ee65
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Jan 31 19:50:23 2014 -0500
AS7 i-test work, continued...
- break up the test runs into a few different executions, deployment tests
seem to benefit from running independently
- add new waitForAsyncDiscoveryToStabilize() mechanism which is based on
tree size stabilizing as opposed to tree depth being reached. For large
discoveries (like an AS-7) tree depth is reached well before the whole
tree is discovered. Started using this as needed.
- fix various tests in various ways, see diffs
diff --git a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
index a553a5d..36fb392 100644
--- a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
+++ b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
@@ -99,12 +99,12 @@ public class FakeServerInventory {
synchronized (sync) {
if (!depthReached) {
if (LOG.isDebugEnabled()) {
- LOG.debug("Waiting for the discovery to complete on " + this);
+ LOG.debug("Waiting for the discovery depth to be reached on " + this);
}
sync.wait(timeoutMillis);
} else {
if (LOG.isDebugEnabled()) {
- LOG.debug("Discovery already complete... no need to wait on " + this);
+ LOG.debug("Discovery depth already reached... no need to wait on " + this);
}
}
@@ -112,6 +112,10 @@ public class FakeServerInventory {
}
}
+ public int getExpectedDepth() {
+ return expectedDepth;
+ }
+
private void setDepth(int resourceTreeDepth) {
synchronized (sync) {
if (LOG.isDebugEnabled()) {
diff --git a/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java b/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
index c7a2333..e904c56 100644
--- a/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
+++ b/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
@@ -194,20 +194,89 @@ public abstract class AbstractAgentPluginTest extends Arquillian {
protected abstract int getTypeHierarchyDepth();
+ /**
+ * Note - this is still a bit weak. Waiting for a discovery depth to be reached does not mean that discovery
+ * is actually complete. For many simple test hierarchies it is sufficient, but for a large scale integration
+ * test, requiring full discovery of an AS-7 server (for example), it can reach the target depth well before
+ * the entire tree is discovered and populated. In cases where you want to better ensure complete discovery,
+ * try making a call to {@link #waitForAsyncDiscoveryToStabilize(Resource)}.
+ *
+ * @throws Exception
+ */
@AfterDiscovery
protected void waitForAsyncDiscoveries() throws Exception {
try {
+ System.out.println("\n====== Waiting for Discovery Depth [" + discoveryCompleteChecker.getExpectedDepth()
+ + "] to be Reached...");
discoveryCompleteChecker.waitForDiscoveryComplete(12000);
- System.out.println("\n====== Discovery completed.");
+ System.out.println("\n====== Discovery Depth Reached.");
} catch (InterruptedException e) {
- throw new RuntimeException("Discovery did not complete within 12 seconds.");
+ throw new RuntimeException("Discovery depth not reached within 12 seconds.");
}
+
// Wait a while longer to give all Resource components a chance to start.
// TODO: Do this more intelligently so we don't sleep longer than needed.
Thread.sleep(10000);
}
/**
+ * Note - this is stronger than {@link #waitForAsyncDiscoveries()} but can be slower. It waits until the
+ * discovered tree size stabilizes, which may take longer than hitting a target tree depth.
+ * Tree depth may be sufficient for many simple test hierarchies but for a large scale integration
+ * test, requiring full discovery of an AS-7 server (for example), it can reach the target depth well before
+ * the entire tree is discovered and populated.
+ * </p>
+ * This is equivalent to {{waitForAsyncDiscoveryToStabilize(root, 5000L, 5)}}.
+ *
+ * @throws Exception
+ */
+ protected void waitForAsyncDiscoveryToStabilize(Resource root) throws Exception {
+ waitForAsyncDiscoveryToStabilize(root, 5000L, 5);
+ }
+
+ /**
+ * @param root
+ * @param checkInterval how long between checks of the tree size
+ * @param stableCount how many checks must be the same before we're convinced we're stable
+ * @throws Exception
+ */
+ protected void waitForAsyncDiscoveryToStabilize(Resource root, long checkInterval, int stableCount)
+ throws Exception {
+ int startResCount = 0;
+ int endResCount = getResCount(root);
+ int numStableChecks = 0;
+ log.info("waitForAsyncDiscoveryToStabilize: ResourceCount Start=" + endResCount);
+ do {
+ startResCount = endResCount;
+ try {
+ Thread.sleep(checkInterval);
+ } catch (InterruptedException e) {
+ //
+ }
+ endResCount = getResCount(root);
+
+ if (startResCount == endResCount) {
+ ++numStableChecks;
+ } else {
+ numStableChecks = 0;
+ }
+ } while (startResCount < endResCount || numStableChecks < stableCount);
+ log.info("waitForAsyncDiscoveryToStabilize: ResourceCount Stable at=" + endResCount);
+ }
+
+ private int getResCount(Resource resource) {
+ int size = 1;
+ Set<Resource> children = resource.getChildResources();
+ if (null != children && !children.isEmpty()) {
+ HashSet<Resource> safeChildren = new HashSet<Resource>(children);
+ for (Resource r : safeChildren) {
+ size += getResCount(r);
+ }
+ }
+ return size;
+ }
+
+ /**
* Get availability for a Resource synchronously, with a 5 second timeout.
*
* @param resource the Resource
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml
index 7827000..401f21c 100644
--- a/modules/plugins/jboss-as-7/pom.xml
+++ b/modules/plugins/jboss-as-7/pom.xml
@@ -625,19 +625,6 @@
<configuration>
<skipTests>false</skipTests>
<skipITs>false</skipITs>
- <includes>
- <!-- 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/standalone/DeploymentTest.java</include>-->
- <!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java</include>-->
- <!--<include>org/rhq/modules/plugins/jbossas7/itest/standalone/WebConnectorComponentTest.java</include>-->
- <!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java</include>-->
- <!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/ManagedServerTest.java</include>-->
- <!--<include>org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java</include>-->
- <!--<include>org/rhq/modules/plugins/jbossas7/itest/nonpc/ManagementConnectionPersistenceTest.java</include>-->
- </includes>
<properties>
<property>
<name>listener</name>
@@ -658,7 +645,41 @@
</systemPropertyVariables>
</configuration>
<executions>
+ <!-- Some of these test classes seem to do better when run by themseleves. So, use different executions... -->
<execution>
+ <id>DeploymentRuntimeResourcesTest</id>
+ <configuration>
+ <includes>
+ <include>org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java</include>
+ </includes>
+ </configuration>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>DeploymentTest</id>
+ <configuration>
+ <includes>
+ <include>org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java</include>
+ </includes>
+ </configuration>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>everything-else</id>
+ <configuration>
+ <includes>
+ <include>org/rhq/modules/plugins/jbossas7/itest/**/*Test.java</include>
+ </includes>
+ <excludes>
+ <exclude>org/rhq/modules/plugins/jbossas7/itest/standalone/Deployment*Test.java</exclude>
+ </excludes>
+ </configuration>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
index 780d398..db7e35a 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
@@ -72,7 +72,6 @@ public abstract class AbstractJBossAS7PluginTest extends AbstractAgentPluginTest
protected void installManagementUsers() throws PluginContainerException, Exception {
waitForAsyncDiscoveries();
- System.out.println("\n=== Discovery scan completed.");
if (!createdManagementUsers) {
System.out.println("====== Installing management users...");
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java
index 182ef36..ead0224 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/SecurityModuleOptionsTest.java
@@ -79,6 +79,9 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
private static String SECURITY_RESOURCE_TYPE = "Security";
private static String SECURITY_RESOURCE_KEY = "subsystem=security";
private static String SECURITY_DOMAIN_RESOURCE_KEY = "security-domain";
+ // Out of box:
+ // The full-ha profile is associated with other-server-group
+ // server-three is in other-server-group and not started
private static String PROFILE = "profile=full-ha";
private static String SECURITY_DOMAIN_RESOURCE_TYPE = "Security Domain";
private static String AUTH_CLASSIC_RESOURCE_TYPE = "Authentication (Classic)";
@@ -119,9 +122,10 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
"[{\"code\":\"Test\", \"type\":\"attribute\", \"module-options\":{\"mapping\":\"module\", \"mapping1\":\"module1\"}}]");
jsonMap.put("provider-modules",
"[{\"code\":\"Providers\", \"module-options\":{\"provider\":\"module\", \"provider1\":\"module1\"}}]");
- jsonMap
- .put("acl-modules",
- "[{\"flag\":\"sufficient\", \"code\":\"ACL\", \"module-options\":{\"acl\":\"module\", \"acl1\":\"module1\"}}]");
+ // (jshaughn) commenting out, this caused an NPE (EAP 6.0.1), not sure why...
+ //jsonMap
+ // .put("acl-modules",
+ // "[{\"flag\":\"sufficient\", \"code\":\"ACL\", \"module-options\":{\"acl\":\"module\", \"acl1\":\"module1\"}}]");
jsonMap
.put("trust-modules",
"[{\"flag\":\"optional\", \"code\":\"TRUST\", \"module-options\":{\"trust\":\"module\", \"trust1\":\"module1\"}}]");
@@ -156,9 +160,6 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- //Adjust discovery depth to support deeper hierarchy depth of Module Option elements
- setMaxDiscoveryDepthOverride(12);
-
//create new Security Domain
Address destination = new Address(PROFILE);
destination.addSegment(SECURITY_RESOURCE_KEY);
@@ -200,6 +201,7 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
assert false : "An unknown attribute '" + attribute
+ "' was found. Is there a new type to be supported?";
}
+
//build the operation to add the component
////Load json map into ModuleOptionType
List<Value> moduleTypeValue = new ArrayList<Value>();
@@ -222,6 +224,8 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
moduleTypeValue);
//submit the command
result = connection.execute(op);
+ assert result.getOutcome().equals("success") : "Add ModuleOptionType has failed: "
+ + result.getFailureDescription();
}
}
@@ -236,9 +240,8 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
assertNotNull(platform);
assertEquals(platform.getInventoryStatus(), InventoryStatus.COMMITTED);
- //Have thread sleep longer to discover deeper resource types.
- //spinder 6/29/12: up this number if the resources are not being discovered.
- Thread.sleep(240 * 1000L); // delay so that PC gets a chance to scan for resources
+ // ensure the entire EAP inventory is discovered before continuing, we need deep resources in inventory
+ waitForAsyncDiscoveryToStabilize(platform);
}
/** This test method exercises a number of things:
@@ -273,8 +276,7 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
//check the configuration for the Module Option Type Ex. 'Acl (Profile)' Resource. Should be able to verify components
Resource moduleOptionsTypeResource = getModuleOptionTypeResource(attribute);
//assert non-zero id returned
- assert moduleOptionsTypeResource.getId() > 0 : "The resource was not properly initialized. Expected id >0 but got:"
- + moduleOptionsTypeResource.getId();
+ assert moduleOptionsTypeResource.getId() != 0 : "The resource was not properly initialized. Expected id != 0";
//Now request the resource complete with resource config
Configuration loadedConfiguration = testConfigurationManager
@@ -331,8 +333,7 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
//Ex. Module Options for (Acl Modules - Profile)
Resource moduleOptionsResource = getModuleOptionsResource(moduleOptionsTypeResource, attribute);
//assert non-zero id returned
- assert moduleOptionsResource.getId() > 0 : "The resource was not properly initialized. Expected id > 0 but got:"
- + moduleOptionsResource.getId();
+ assert moduleOptionsResource.getId() != 0 : "The resource was not properly initialized. Expected id != 0";
//fetch configuration for module options
//Now request the resource complete with resource config
Configuration loadedOptionsConfiguration = testConfigurationManager
@@ -487,19 +488,28 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
if (testSecurityDomain == null) {
InventoryManager im = pluginContainer.getInventoryManager();
Resource platform = im.getPlatform();
+ if (platform != null)
+ System.out.println("*** Found Platform [" + platform.getResourceKey() + "]");
//host controller
Resource hostController = getResourceByTypeAndKey(platform, DomainServerComponentTest.RESOURCE_TYPE,
DomainServerComponentTest.RESOURCE_KEY);
+ if (hostController != null)
+ System.out.println("*** Found Host Controller [" + hostController.getResourceKey() + "]");
+
//profile=full-ha
ResourceType profileType = new ResourceType("Profile", PLUGIN_NAME, ResourceCategory.SERVICE, null);
String key = PROFILE;
Resource profile = getResourceByTypeAndKey(hostController, profileType, key);
+ if (profile != null)
+ System.out.println("*** Found Profile [" + platform.getResourceKey() + "]");
//Security (Profile)
ResourceType securityType = new ResourceType("Security (Profile)", PLUGIN_NAME, ResourceCategory.SERVICE,
null);
key += "," + SECURITY_RESOURCE_KEY;
Resource security = getResourceByTypeAndKey(profile, securityType, key);
+ if (security != null)
+ System.out.println("*** Found Security [" + security.getResourceKey() + "]");
//Security Domain (Profile)
ResourceType domainType = new ResourceType("Security Domain (Profile)", PLUGIN_NAME,
@@ -507,6 +517,8 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
key += "," + securityDomainId;
testSecurityDomainKey = key;
testSecurityDomain = getResourceByTypeAndKey(security, domainType, key);
+ if (testSecurityDomain != null)
+ System.out.println("*** Found Domain [" + testSecurityDomain.getResourceKey() + "]");
}
//acl=classic
@@ -546,8 +558,11 @@ public class SecurityModuleOptionsTest extends AbstractJBossAS7PluginTest {
}
moduleOptionResource = getResourceByTypeAndKey(testSecurityDomain, moduleOptionType, moduleOptionTypeKey);
+ if (moduleOptionResource != null)
+ System.out.println("*** Found ModuleOption [" + moduleOptionResource.getResourceKey() + "]");
return moduleOptionResource;
+
}
/** Automates hierarchy creation for Module Option type resources and their parents
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java
index 3747821..1f915d5 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java
@@ -65,7 +65,7 @@ import org.rhq.test.arquillian.RunDiscovery;
*
* @author Thomas Segismont
*/
-@Test
+@Test(groups = { "integration", "pc", "standalone" }, singleThreaded = true)
public class DeploymentRuntimeResourcesTest extends AbstractJBossAS7PluginTest {
private static final Log LOG = LogFactory.getLog(DeploymentRuntimeResourcesTest.class);
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java
index fbdc02b..c3a8ec4 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java
@@ -127,7 +127,6 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest {
serverResource = standaloneResources.iterator().next();
}
- //(dependsOnMethods = "assignServerResource")
@Test(priority = 11)
public void testDeploy() throws Exception {
ResourcePackageDetails packageDetails = getTestDeploymentPackageDetails(TestDeployments.DEPLOYMENT_1);
@@ -215,7 +214,6 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest {
}
@Test(priority = 15)
- @RunDiscovery
public void testWebRuntimeMetricsHaveNonNullValues() throws Exception {
assertTrue(webRuntimeResources != null && !webRuntimeResources.isEmpty(),
"Web Runtime resource should have been discovered");
@@ -237,7 +235,6 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest {
}
@Test(priority = 16)
- @RunDiscovery
public void testUndeploy() throws Exception {
Resource deployment = deploymentResources.iterator().next();
DeleteResourceRequest request = new DeleteResourceRequest(0, deployment.getId());
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java
index 8d391a1..e918d50 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/ResourcesStandaloneServerTest.java
@@ -55,16 +55,35 @@ public class ResourcesStandaloneServerTest extends AbstractJBossAS7PluginTest {
assertNotNull(platform);
assertEquals(platform.getInventoryStatus(), InventoryStatus.COMMITTED);
- Thread.sleep(20 * 1000L);
-
ResourceContainer platformContainer = inventoryManager.getResourceContainer(platform);
Resource server = getResourceByTypeAndKey(platform, StandaloneServerComponentTest.RESOURCE_TYPE,
StandaloneServerComponentTest.RESOURCE_KEY);
inventoryManager.activateResource(server, platformContainer, false);
-
- Thread.sleep(40 * 1000L);
}
+ @Test(priority = 11)
+ public void standaloneExecuteNoArgOperations() throws Exception {
+ List<String> ignoredSubsystems = new ArrayList<String>();
+
+ //ignored because mod_cluster is not setup in default server configuration
+ //to be more specific, there is no server to fail-over to
+ ignoredSubsystems.add("ModCluster Standalone Service");
+
+ List<String> ignoredOperations = new ArrayList<String>();
+ //ignored because there is no other server to fail-over to
+ ignoredOperations.add("subsystem:force-failover");
+ //ignored because this is not a true operation, it is handled
+ //internally by a configuration property change
+ ignoredOperations.add("enable");
+ //ignored because the Osgi subsystem not configured out of box
+ ignoredOperations.add("subsystem:activate");
+
+ Resource platform = this.pluginContainer.getInventoryManager().getPlatform();
+ Resource server = getResourceByTypeAndKey(platform, StandaloneServerComponentTest.RESOURCE_TYPE,
+ StandaloneServerComponentTest.RESOURCE_KEY);
+
+ executeNoArgOperations(server, ignoredSubsystems, ignoredOperations);
+ }
@Test(priority = 12)
public void loadUpdateResourceConfiguration() throws Exception {
@@ -89,6 +108,13 @@ public class ResourcesStandaloneServerTest extends AbstractJBossAS7PluginTest {
ignoredResources.add("Memory Pool");
ignoredResources.add("Periodic Rotating File Handler");
+ //created BZ 1059882 for failures related to:
+ // attribute discovery-group-name (mutually exclusive issue?)
+ ignoredResources.add("Pooled Connection Factory");
+ ignoredResources.add("Connection Factory");
+ // attribute static-connectors (nullable list issue?)
+ ignoredResources.add("Cluster Connection");
+
Resource platform = this.pluginContainer.getInventoryManager().getPlatform();
Resource server = getResourceByTypeAndKey(platform, StandaloneServerComponentTest.RESOURCE_TYPE,
StandaloneServerComponentTest.RESOURCE_KEY);
@@ -97,28 +123,5 @@ public class ResourcesStandaloneServerTest extends AbstractJBossAS7PluginTest {
Assert.assertEquals(errorCount, 0);
}
- @Test(priority = 11)
- public void standaloneExecuteNoArgOperations() throws Exception {
- List<String> ignoredSubsystems = new ArrayList<String>();
-
- //ignored because mod_cluster is not setup in default server configuration
- //to be more specific, there is no server to fail-over to
- ignoredSubsystems.add("ModCluster Standalone Service");
-
- List<String> ignoredOperations = new ArrayList<String>();
- //ignored because there is no other server to fail-over to
- ignoredOperations.add("subsystem:force-failover");
- //ignored because this is not a true operation, it is handled
- //internally by a configuration property change
- ignoredOperations.add("enable");
- //ignored because the Osgi subsystem not configured out of box
- ignoredOperations.add("subsystem:activate");
-
- Resource platform = this.pluginContainer.getInventoryManager().getPlatform();
- Resource server = getResourceByTypeAndKey(platform, StandaloneServerComponentTest.RESOURCE_TYPE,
- StandaloneServerComponentTest.RESOURCE_KEY);
-
- executeNoArgOperations(server, ignoredSubsystems, ignoredOperations);
- }
}
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/TemplatedResourcesTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/TemplatedResourcesTest.java
index 908faff..cbd5ef8 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/TemplatedResourcesTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/TemplatedResourcesTest.java
@@ -58,7 +58,7 @@ public class TemplatedResourcesTest extends AbstractJBossAS7PluginTest {
assertNotNull(platform);
assertEquals(platform.getInventoryStatus(), InventoryStatus.COMMITTED);
- Thread.sleep(40 * 1000L);
+ //Thread.sleep(40 * 1000L);
}
@Test(priority = 11)
@@ -73,7 +73,7 @@ public class TemplatedResourcesTest extends AbstractJBossAS7PluginTest {
StandaloneServerComponentTest.RESOURCE_KEY);
inventoryManager.activateResource(server, platformContainer, false);
- Thread.sleep(30 * 1000L);
+ //Thread.sleep(30 * 1000L);
for (ResourceData resourceData : testResourceData) {
ResourceType resourceType = new ResourceType(resourceData.resourceTypeName, PLUGIN_NAME,
@@ -100,7 +100,7 @@ public class TemplatedResourcesTest extends AbstractJBossAS7PluginTest {
for (Resource resourceUnderTest : foundResources) {
log.info(foundResources);
- assert resourceUnderTest.getId() > 0 : "Resource not properly initialized. Id = 0. Try extending sleep after discovery.";
+ assert resourceUnderTest.getId() != 0 : "Resource not properly initialized. Id = 0. Try extending sleep after discovery.";
Configuration resourceUnderTestConfig = configurationManager
.loadResourceConfiguration(resourceUnderTest.getId());
commit bdf2623b4f28660bbb3a443b5f33d4a25bb381d7
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Fri Jan 31 13:59:34 2014 +0100
Sprinkling rhq-bot with some love. (Jira bug resolving, fancy colors)
diff --git a/etc/rhq-ircBot/pom.xml b/etc/rhq-ircBot/pom.xml
index 75c9249..b7ea145 100644
--- a/etc/rhq-ircBot/pom.xml
+++ b/etc/rhq-ircBot/pom.xml
@@ -67,6 +67,12 @@
<artifactId>commons-codec</artifactId>
<version>1.4</version>
</dependency>
+
+ <dependency>
+ <groupId>com.atlassian.jira</groupId>
+ <artifactId>jira-rest-java-client</artifactId>
+ <version>2.0.0-m2</version>
+ </dependency>
</dependencies>
<build>
@@ -127,6 +133,22 @@
</build>
+ <repositories>
+ <repository>
+ <id>atlassian-public</id>
+ <url>https://m2proxy.atlassian.com/repository/public</url>
+ <snapshots>
+ <enabled>true</enabled>
+ <updatePolicy>daily</updatePolicy>
+ <checksumPolicy>warn</checksumPolicy>
+ </snapshots>
+ <releases>
+ <enabled>true</enabled>
+ <checksumPolicy>warn</checksumPolicy>
+ </releases>
+ </repository>
+ </repositories>
+
<distributionManagement>
<snapshotRepository>
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/BugResolver.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/BugResolver.java
new file mode 100644
index 0000000..6312c31
--- /dev/null
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/BugResolver.java
@@ -0,0 +1,27 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.etc.ircbot;
+
+/**
+ * @author Jirka Kremser
+ *
+ */
+public interface BugResolver {
+ String resolve(String bugIdentifier);
+}
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/BugzillaResolver.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/BugzillaResolver.java
new file mode 100644
index 0000000..0e5e8e7
--- /dev/null
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/BugzillaResolver.java
@@ -0,0 +1,75 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.etc.ircbot;
+
+import com.j2bugzilla.base.Bug;
+import com.j2bugzilla.base.BugzillaConnector;
+import com.j2bugzilla.base.BugzillaException;
+import com.j2bugzilla.base.ConnectionException;
+import com.j2bugzilla.rpc.GetBug;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/**
+ * @author Jirka Kremser
+ *
+ */
+public class BugzillaResolver implements BugResolver {
+
+ private BugzillaConnector bzConnector = new BugzillaConnector();
+
+ @Override
+ public String resolve(String bugIdentifier) {
+ int bugId = Integer.valueOf(bugIdentifier);
+ GetBug getBug = new GetBug(bugId);
+ try {
+ bzConnector.executeMethod(getBug);
+ } catch (Exception e) {
+ bzConnector = new BugzillaConnector();
+ try {
+ bzConnector.connectTo("https://bugzilla.redhat.com");
+ } catch (ConnectionException e2) {
+ e2.printStackTrace();
+ return "Failed to access BZ " + bugId + ": " + e2.getMessage();
+ }
+ try {
+ bzConnector.executeMethod(getBug);
+ } catch (BugzillaException e1) {
+ //e1.printStackTrace();
+ Throwable cause = e1.getCause();
+ String details = (cause instanceof XmlRpcException) ? cause.getMessage() : e1.getMessage();
+ return "Failed to access BZ " + bugId + ": " + details;
+ }
+ }
+ Bug bug = getBug.getBug();
+ if (bug != null) {
+ String product = bug.getProduct();
+ if (product.equals("RHQ Project")) {
+ product = "RHQ";
+ } else if (product.equals("JBoss Operations Network")) {
+ product = "JON";
+ }
+ return "BZ " + bugId + " [product=" + product + ", priority=" + Color.GREEN + bug.getPriority()
+ + Color.NORMAL + ", status=" + bug.getStatus() + "] " + Color.RED + bug.getSummary() + Color.NORMAL
+ + " [ https://bugzilla.redhat.com/" + bugId + " ]";
+ } else {
+ return ("BZ " + bugId + " does not exist.");
+ }
+ }
+}
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/Color.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/Color.java
new file mode 100644
index 0000000..6f419ea
--- /dev/null
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/Color.java
@@ -0,0 +1,46 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.etc.ircbot;
+
+/**
+ * @author Jirka Kremser
+ *
+ */
+public interface Color {
+ String NORMAL = "\u000f";
+ String BOLD = "\u0002";
+ String UNDERLINE = "\u001f";
+ String REVERSE = "\u0016";
+ String WHITE = "\u000300";
+ String BLACK = "\u000301";
+ String DARK_BLUE = "\u000302";
+ String DARK_GREEN = "\u000303";
+ String RED = "\u000304";
+ String BROWN = "\u000305";
+ String PURPLE = "\u000306";
+ String OLIVE = "\u000307";
+ String YELLOW = "\u000308";
+ String GREEN = "\u000309";
+ String TEAL = "\u000310";
+ String CYAN = "\u000311";
+ String BLUE = "\u000312";
+ String MAGENTA = "\u000313";
+ String DARK_GRAY = "\u000314";
+ String LIGHT_GRAY = "\u000315";
+}
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/JiraResolver.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/JiraResolver.java
new file mode 100644
index 0000000..69a7efc
--- /dev/null
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/JiraResolver.java
@@ -0,0 +1,67 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.etc.ircbot;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import com.atlassian.jira.rest.client.JiraRestClient;
+import com.atlassian.jira.rest.client.JiraRestClientFactory;
+import com.atlassian.jira.rest.client.domain.Issue;
+import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory;
+import com.atlassian.util.concurrent.Promise;
+
+/**
+ * @author Jirka Kremser
+ *
+ */
+public class JiraResolver implements BugResolver {
+
+ public final static String JIRA_URL = "https://issues.jboss.org";
+ private JiraRestClient restClient;
+
+ @Override
+ public String resolve(String bugIdentifier) {
+ Promise<Issue> issuePromise = getRestClient().getIssueClient().getIssue(bugIdentifier);
+ return issuePromise.claim().getSummary();
+ }
+
+ public Promise<Issue> resolveAsync(String bugIdentifier) {
+ return getRestClient().getIssueClient().getIssue(bugIdentifier);
+ }
+
+
+ private JiraRestClient setupJiraClient(String url) throws URISyntaxException {
+ JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
+ final JiraRestClient restClient = factory.createWithBasicHttpAuthentication(new URI(url), "rhq-bot", "123456");
+ return restClient;
+ }
+
+ private JiraRestClient getRestClient() {
+ if (restClient == null) {
+ try {
+ restClient = setupJiraClient(JIRA_URL);
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ }
+ return restClient;
+ }
+
+}
diff --git a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
index 1a70c3f..d56e7f3 100644
--- a/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
+++ b/etc/rhq-ircBot/src/main/java/org/rhq/etc/ircbot/RhqIrcBotListener.java
@@ -11,12 +11,10 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import com.j2bugzilla.base.Bug;
-import com.j2bugzilla.base.BugzillaConnector;
-import com.j2bugzilla.base.BugzillaException;
-import com.j2bugzilla.rpc.GetBug;
+import com.atlassian.jira.rest.client.domain.Issue;
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promise;
-import org.apache.xmlrpc.XmlRpcException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
@@ -38,7 +36,9 @@ import org.pircbotx.hooks.events.PrivateMessageEvent;
*/
public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
- private static final Pattern BUG_PATTERN = Pattern.compile("(?i)(bz|bug)[ ]*(\\d{6,7})");
+ private static final Pattern BZ_PATTERN = Pattern.compile("(?i)(bz|bug)[ ]*(\\d{6,7})");
+ private static final String JIRA_PROJECT = "JON3-";
+ private static final Pattern JIRA_PATTERN = Pattern.compile("(?i)(" + JIRA_PROJECT + "\\d{1,5})");
private static final Pattern COMMIT_PATTERN = Pattern.compile("(?i)(\\!commit|cm)[ ]*([0-9a-f]{3,40})");
private static final Pattern ECHO_PATTERN = Pattern.compile("(?i)echo[ ]+(.+)");
private static final String COMMIT_LINK = "https://git.fedorahosted.org/cgit/rhq/rhq.git/commit/?id=%s";
@@ -48,15 +48,13 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
private static enum Command {
- FORUM("Our forum is available from https://community.jboss.org/en/rhq?view=discussions", true),
- HELP("You can use one of the following commands: ", true),
- LISTS("Feel free to enroll to the user list https://lists.fedorahosted.org/mailman/listinfo/rhq-users"
- + " or the devel list https://lists.fedorahosted.org/mailman/listinfo/rhq-devel", true),
- LOGS("IRC logs are available from http://transcripts.jboss.org/channel/irc.freenode.org/%23rhq/index.html", true),
- PTO,
- SOURCE("The code could be viewed/cloned on https://github.com/rhq-project or https://git.fedorahosted.org/cgit/rhq/rhq.git/", true),
- SUPPORT,
- WIKI("Our wiki is available from https://docs.jboss.org/author/display/RHQ/Home", true);
+ FORUM("Our forum is available from https://community.jboss.org/en/rhq?view=discussions", true), HELP(
+ "You can use one of the following commands: ", true), LISTS(
+ "Feel free to enroll to the user list https://lists.fedorahosted.org/mailman/listinfo/rhq-users"
+ + " or the devel list https://lists.fedorahosted.org/mailman/listinfo/rhq-devel", true), LOGS(
+ "IRC logs are available from http://transcripts.jboss.org/channel/irc.freenode.org/%23rhq/index.html", true), PTO, SOURCE(
+ "The code could be viewed/cloned on https://github.com/rhq-project or https://git.fedorahosted.org/cgit/rhq/rhq.git/",
+ true), SUPPORT, WIKI("Our wiki is available from https://docs.jboss.org/author/display/RHQ/Home", true);
public static final String PREFIX = "!";
private final String staticRespond;
@@ -89,9 +87,9 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
private final String server;
private final String channel;
+ private final BugResolver bzResolver = new BugzillaResolver();
+ private final JiraResolver jiraResolver = new JiraResolver();
private final boolean isRedHatChannel;
- private BugzillaConnector bzConnector = new BugzillaConnector();
- private final Map<Integer, Long> bugLogTimestamps = new HashMap<Integer, Long>();
private final Map<String, String> names = new HashMap<String, String>();
private final Map<String, String> ptoCache = new HashMap<String, String>();
private final Map<String, String> supportCache = new HashMap<String, String>();
@@ -101,7 +99,8 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
this.server = server;
this.channel = channel;
isRedHatChannel = "irc.devel.redhat.com".equals(server);
- if (isRedHatChannel) System.out.print("Red Hat channel");
+ if (isRedHatChannel)
+ System.out.print("Red Hat channel");
StringBuilder commandRegExp = new StringBuilder();
commandRegExp.append("^(?i)[ ]*").append(Command.PREFIX).append("(");
for (Command command : Command.values()) {
@@ -113,57 +112,47 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
}
@Override
- public void onMessage(MessageEvent<RhqIrcBot> event) throws Exception {
+ public void onMessage(final MessageEvent<RhqIrcBot> event) throws Exception {
if (event.getUser().getNick().toLowerCase().contains("bot")) {
return; // never talk with artificial forms of life
}
-
- PircBotX bot = event.getBot();
+
+ final PircBotX bot = event.getBot();
if (!bot.getNick().equals(bot.getName())) {
bot.changeNick(bot.getName());
}
+ String message = event.getMessage();
// react to BZs in the messages
- String message = event.getMessage();
- Matcher bugMatcher = BUG_PATTERN.matcher(message);
- while (bugMatcher.find()) {
- int bugId = Integer.valueOf(bugMatcher.group(2));
- GetBug getBug = new GetBug(bugId);
- try {
- bzConnector.executeMethod(getBug);
- } catch (Exception e) {
- bzConnector = new BugzillaConnector();
- bzConnector.connectTo("https://bugzilla.redhat.com");
- try {
- bzConnector.executeMethod(getBug);
- } catch (BugzillaException e1) {
- //e1.printStackTrace();
- Throwable cause = e1.getCause();
- String details = (cause instanceof XmlRpcException) ? cause.getMessage() : e1.getMessage();
- bot.sendMessage(event.getChannel(), "Failed to access BZ " + bugId + ": " + details);
- continue;
- }
- }
- Bug bug = getBug.getBug();
- if (bug != null) {
- String product = bug.getProduct();
- if (product.equals("RHQ Project")) {
- product = "RHQ";
- } else if (product.equals("JBoss Operations Network")) {
- product = "JON";
+ Matcher bzMatcher = BZ_PATTERN.matcher(message);
+ while (bzMatcher.find()) {
+ final String response = bzResolver.resolve(bzMatcher.group(2));
+ bot.sendMessage(event.getChannel(), response);
+ }
+
+ // react to Jira bugs in the messages
+ Matcher jiraMatcher = JIRA_PATTERN.matcher(message);
+ while (jiraMatcher.find()) {
+ // final String response = jiraResolver.resolve(bzMatcher.group(1));
+ // bot.sendMessage(event.getChannel(), response);
+ final String bugId = jiraMatcher.group(1);
+ final Promise<Issue> issuePromise = jiraResolver.resolveAsync(bugId);
+ issuePromise.done(new Effect<Issue>() {
+ @Override
+ public void apply(Issue a) {
+ bot.sendMessage(event.getChannel(), bugId + ": " + Color.RED + a.getSummary() + Color.NORMAL
+ + ", priority: " + Color.GREEN + a.getPriority().getName() + Color.NORMAL + ", created: "
+ + a.getCreationDate().toString("YYYY-MM-DD") + " [ " + JiraResolver.JIRA_URL + "/browse/"
+ + bugId + " ]");
}
- Long timestamp = bugLogTimestamps.get(bugId);
- if ((timestamp == null) || ((System.currentTimeMillis() - timestamp) > (5 * 60 * 1000L))) {
- bot.sendMessage(
- event.getChannel(),
- "BZ " + bugId + " [product=" + product + ", priority=" + bug.getPriority() + ", status="
- + bug.getStatus() + "] " + bug.getSummary() + " [ https://bugzilla.redhat.com/" + bugId
- + " ]");
+ });
+ issuePromise.fail(new Effect<Throwable>() {
+ @Override
+ public void apply(Throwable e) {
+ bot.sendMessage(event.getChannel(),
+ "Failed to access bug " + bugId + " Cause: " + shorten(e.getMessage()));
}
- bugLogTimestamps.put(bugId, System.currentTimeMillis());
- } else {
- bot.sendMessage(event.getChannel(), "BZ " + bugId + " does not exist.");
- }
+ });
}
// react to the commit hashs included in the messages
@@ -173,11 +162,11 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
String response = String.format(COMMIT_LINK, shaHash);
bot.sendMessage(event.getChannel(), event.getUser().getNick() + ": " + response);
}
-
+
if (message.startsWith(event.getBot().getNick())) {
- // someone asked bot directly, we have to remove that from message
- message = message.substring(event.getBot().getNick().length());
- message = message.replaceFirst("[^ ]*", "");
+ // someone asked bot directly, we have to remove that from message
+ message = message.substring(event.getBot().getNick().length());
+ message = message.replaceFirst("[^ ]*", "");
}
// react to commands included in the messages
Matcher commandMatcher = commandPattern.matcher(message);
@@ -185,7 +174,7 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
Command command = Command.valueOf(commandMatcher.group(1).toUpperCase());
String response = prepareResponseForCommand(command);
if (response != null) {
- bot.sendMessage(event.getChannel(), event.getUser().getNick() + ": " + response);
+ bot.sendMessage(event.getChannel(), event.getUser().getNick() + ": " + shorten(response));
}
}
@@ -210,12 +199,12 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
String message = privateMessageEvent.getMessage();
Matcher echoMatcher = ECHO_PATTERN.matcher(message);
if (echoMatcher.matches()) {
- if (!JON_DEVS.contains(privateMessageEvent.getUser().getNick())) {
- privateMessageEvent.respond("You're not my master, I am your master, go away");
- } else {
- String echoMessage = echoMatcher.group(1);
- bot.sendMessage(this.channel, echoMessage);
- }
+ if (!JON_DEVS.contains(privateMessageEvent.getUser().getNick())) {
+ privateMessageEvent.respond("You're not my master, I am your master, go away");
+ } else {
+ String echoMessage = echoMatcher.group(1);
+ bot.sendMessage(this.channel, echoMessage);
+ }
} else if (message.equalsIgnoreCase(Command.PREFIX + "listrenames")) {
//Generate a list of renames in the form of old1 changed to new1, old2 changed to new2, etc
StringBuilder users = new StringBuilder();
@@ -289,10 +278,10 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
switch (command) {
case SUPPORT:
if (isRedHatChannel)
- return whoIsOnSupport();
+ return whoIsOnSupport();
case PTO:
if (isRedHatChannel)
- return whoIsOnPto(PTO_LINK);
+ return whoIsOnPto(PTO_LINK);
default:
System.err.println("Unknown command:" + command);
break;
@@ -312,7 +301,7 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
supportCache.put(month + "#" + dayInMonth, value);
return value;
}
-
+
private String whoIsOnPto(String link) {
String month = monthFormat.format(new Date());
String dayInMonth = dayInMonthFormat.format(new Date());
@@ -340,6 +329,14 @@ public class RhqIrcBotListener extends ListenerAdapter<RhqIrcBot> {
private String doNotNotify(String nick) {
//replace all vowels with unicode chars that look same not to spam users with notifications
- return nick.toLowerCase().replaceFirst("a", "\u0430").replaceFirst("e", "\u0435").replaceFirst("i", "\u0456").replaceFirst("o", "\u043E").replaceFirst("u", "\u222A").replaceFirst("y", "\u028F");
+ return nick.toLowerCase().replaceFirst("a", "\u0430").replaceFirst("e", "\u0435").replaceFirst("i", "\u0456")
+ .replaceFirst("o", "\u043E").replaceFirst("u", "\u222A").replaceFirst("y", "\u028F");
+ }
+
+ private String shorten(String message) {
+ if (message != null && message.length() > 300) {
+ return message.substring(0, 300) + "...";
+ } else
+ return message;
}
}
commit dfc792f515525c337650a692fb80f13b986fdc10
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Thu Jan 30 18:56:02 2014 +0100
Do not catch an exception just thrown
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 bc7112a..7654c62 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
@@ -181,20 +181,21 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend
// Validate the product type (e.g. AS or EAP).
String expectedRuntimeProductName = pluginConfiguration.getSimpleValue("expectedRuntimeProductName");
+ String runtimeProductName;
try {
- String runtimeProductName = readAttribute(getHostAddress(), "product-name");
- if (runtimeProductName == null || runtimeProductName.trim().isEmpty()) {
- runtimeProductName = JBossProductType.AS.PRODUCT_NAME;
- }
- if (!runtimeProductName.equals(expectedRuntimeProductName)) {
- throw new InvalidPluginConfigurationException(
- "The original product type discovered for this server was " + expectedRuntimeProductName
- + ", but the server is now reporting its product type is [" + runtimeProductName + "]");
- }
+ runtimeProductName = readAttribute(getHostAddress(), "product-name");
} catch (Exception e) {
throw new InvalidPluginConfigurationException("Failed to validate product type for "
+ getResourceDescription(), e);
}
+ if (runtimeProductName == null || runtimeProductName.trim().isEmpty()) {
+ runtimeProductName = JBossProductType.AS.PRODUCT_NAME;
+ }
+ if (!runtimeProductName.equals(expectedRuntimeProductName)) {
+ throw new InvalidPluginConfigurationException(
+ "The original product type discovered for this server was " + expectedRuntimeProductName
+ + ", but the server is now reporting its product type is [" + runtimeProductName + "]");
+ }
}
public ServerPluginConfiguration getServerPluginConfiguration() {
commit b4c048f8dfe3aab6f4c8347e856b80f40e66f29a
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Thu Jan 30 18:15:50 2014 +0100
Bug 977350 - Log events will not be collected if target log file doesn't exist at the time the resource is started by the plug-in container
Changed the warning message to indicate that the poller will be started even if the file does not exist
Changed the poller implementation to support "bad" files (non existing or file is a directory): event polling will start as soon as a regular file is found
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventPoller.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventPoller.java
index b4e19c4..6a2c774 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventPoller.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventPoller.java
@@ -1,25 +1,22 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2012 Red Hat, Inc.
+ * Copyright (C) 2005-2014 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, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
+ * 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 and the GNU Lesser General Public License
- * for more details.
+ * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * and the GNU Lesser 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.
+ * 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.core.pluginapi.event.log;
import java.io.BufferedReader;
@@ -47,7 +44,7 @@ import org.rhq.core.pluginapi.event.EventPoller;
* @author Ian Springer
*/
public class LogFileEventPoller implements EventPoller {
- private final Log log = LogFactory.getLog(this.getClass());
+ private static final Log LOG = LogFactory.getLog(LogFileEventPoller.class);
private String eventType;
private File logFile;
@@ -76,24 +73,27 @@ public class LogFileEventPoller implements EventPoller {
@Nullable
public Set<Event> poll() {
- if (!this.initialized) {
- init();
- }
- if (this.logFileInfo == null) {
- // This means SIGAR, which we require, is unavailable, so just return null.
- return null;
- }
-
if (!this.logFile.exists()) {
- log.warn("Log file [" + this.logFile + "] being polled does not exist.");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Log file [" + this.logFile + "] being polled does not exist.");
+ }
return null;
}
if (this.logFile.isDirectory()) {
- log.error("Log file [" + this.logFile + "] being polled is a directory, not a regular file.");
+ LOG.error("Log file [" + this.logFile + "] being polled is a directory, not a regular file.");
return null;
}
-
- try {
+ if (!this.initialized) {
+ init();
+ }
+ if (this.logFileInfo == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Cannot poll log file [" + this.logFile
+ + "] because native integration is either disabled or unavailable.");
+ }
+ return null;
+ }
+ try {
if (!this.logFileInfo.changed()) {
return null;
}
@@ -118,7 +118,7 @@ public class LogFileEventPoller implements EventPoller {
throw new RuntimeException("Failed to obtain file info for log file [" + this.logFile + "].", e);
}
} else {
- log.warn("SIGAR is unavailable - cannot poll log file [" + this.logFile + "] for events.");
+ LOG.warn("SIGAR is unavailable - cannot poll log file [" + this.logFile + "] for events.");
}
this.initialized = true;
@@ -138,7 +138,7 @@ public class LogFileEventPoller implements EventPoller {
BufferedReader bufferedReader = new BufferedReader(reader);
events = this.entryProcessor.processLines(bufferedReader);
} catch (IOException e) {
- log.error("Failed to read log file being tailed: " + this.logFile, e);
+ LOG.error("Failed to read log file being tailed: " + this.logFile, e);
} finally {
if (reader != null) {
//noinspection EmptyCatchBlock
@@ -155,29 +155,29 @@ public class LogFileEventPoller implements EventPoller {
FileInfo previousFileInfo = fileInfo.getPreviousInfo();
if (previousFileInfo == null) {
- if (log.isDebugEnabled()) {
- log.debug(this.logFile + ": first stat");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(this.logFile + ": first stat");
}
return fileInfo.getSize();
}
if (fileInfo.getInode() != previousFileInfo.getInode()) {
- if (log.isDebugEnabled()) {
- log.debug(this.logFile + ": file inode changed");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(this.logFile + ": file inode changed");
}
return -1;
}
if (fileInfo.getSize() < previousFileInfo.getSize()) {
- if (log.isDebugEnabled()) {
- log.debug(this.logFile + ": file truncated");
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(this.logFile + ": file truncated");
}
return -1;
}
- if (log.isDebugEnabled()) {
+ if (LOG.isDebugEnabled()) {
long diff = fileInfo.getSize() - previousFileInfo.getSize();
- log.debug(this.logFile + ": " + diff + " new bytes");
+ LOG.debug(this.logFile + ": " + diff + " new bytes");
}
return previousFileInfo.getSize();
diff --git a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventResourceComponentHelper.java b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventResourceComponentHelper.java
index 37a99eb..147b423 100644
--- a/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventResourceComponentHelper.java
+++ b/modules/core/plugin-api/src/main/java/org/rhq/core/pluginapi/event/log/LogFileEventResourceComponentHelper.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2012 Red Hat, Inc.
+ * Copyright (C) 2005-2014 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.core.pluginapi.event.log;
import java.io.File;
@@ -49,6 +50,8 @@ import org.rhq.core.system.SystemInfoFactory;
* @author Ian Springer
*/
public class LogFileEventResourceComponentHelper {
+ private static final Log LOG = LogFactory.getLog(LogFileEventResourceComponentHelper.class);
+
public static final String LOG_ENTRY_EVENT_TYPE = "logEntry";
public static final String LOG_EVENT_SOURCES_CONFIG_PROP = "logEventSources";
@@ -65,8 +68,6 @@ public class LogFileEventResourceComponentHelper {
// TODO: Make this configurable via a plugin config prop.
private static final int POLLING_INTERVAL_IN_SECONDS = 60;
- private final Log log = LogFactory.getLog(this.getClass());
-
private ResourceContext<?> resourceContext;
private List<PropertyMap> startedEventSources = new ArrayList<PropertyMap>();
@@ -105,7 +106,7 @@ public class LogFileEventResourceComponentHelper {
boolean nativeSystemInfoDisabled = SystemInfoFactory.isNativeSystemInfoDisabled();
ResourceType resourceType = this.resourceContext.getResourceType();
List<String> logFilePaths = getLogFilePaths(enabledEventSources);
- log.warn("Log files " + logFilePaths + " for [" + resourceType.getPlugin() + ":"
+ LOG.warn("Log files " + logFilePaths + " for [" + resourceType.getPlugin() + ":"
+ resourceType.getName() + "] Resource with key [" + this.resourceContext.getResourceKey()
+ "] cannot be polled, because log file polling requires RHQ native support, which "
+ ((nativeSystemInfoDisabled) ? "has been disabled for this Agent" : "is not available on this platform") + ".");
@@ -121,9 +122,8 @@ public class LogFileEventResourceComponentHelper {
}
File logFile = new File(logFilePath);
if (!logFile.canRead()) {
- log.error("LOGFILE: Logfile at location " + logFilePath
- + " does not exist or is not readable. Can not start watching the event log.");
- continue;
+ LOG.warn("LOGFILE: Logfile at location " + logFilePath + " does not exist or is not readable. "
+ + "The poller will be started but no events will be polled until the file is created.");
}
Log4JLogEntryProcessor processor = new Log4JLogEntryProcessor(LOG_ENTRY_EVENT_TYPE, logFile);
commit 3cbe934a3b7f986ca816744bb2578bdfbad23e56
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Thu Jan 30 18:04:52 2014 +0100
[BZ 1031200] - Don't assume unique display names of metrics
While having unique names generally is true and even desirable, we were
throwing NPE's in the UI due to that assumption.
Now the UI will just correctly show 2 metrics with the same name which will
hint the user correctly that there's something wrong with the plugin,
not with RHQ itself.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/groups/detail/monitoring/metric/MetricsGroupViewDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/groups/detail/monitoring/metric/MetricsGroupViewDataSource.java
index a5f1353..dd67500 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/groups/detail/monitoring/metric/MetricsGroupViewDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/groups/detail/monitoring/metric/MetricsGroupViewDataSource.java
@@ -21,6 +21,8 @@ package org.rhq.coregui.client.inventory.groups.detail.monitoring.metric;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -256,24 +258,23 @@ public class MetricsGroupViewDataSource extends RPCDataSource<MetricDisplaySumma
}
private void organizeMeasurementDefinitionOrder(ResourceGroup resourceGroup) {
- Set<MeasurementDefinition> definitions = getMetricDefinitions(resourceGroup);
+ List<MeasurementDefinition> definitions = getMetricDefinitions(resourceGroup);
- //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
- final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
- for (MeasurementDefinition definition : definitions) {
- measurementDefMap.put(definition.getDisplayName(), definition);
- }
//bundle definition ids for asynch call.
definitionArrayIds = new int[definitions.size()];
- final String[] displayOrder = new String[definitions.size()];
- measurementDefMap.keySet().toArray(displayOrder);
+
//sort the charting data ex. Free Memory, Free Swap Space,..System Load
- Arrays.sort(displayOrder);
+ Collections.sort(definitions, new Comparator<MeasurementDefinition>() {
+ @Override
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return o1.getDisplayName().compareTo(o2.getDisplayName());
+ }
+ });
//organize definitionArrayIds for ordered request on server.
int index = 0;
- for (String definitionToDisplay : displayOrder) {
- definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay).getId();
+ for (MeasurementDefinition definitionToDisplay : definitions) {
+ definitionArrayIds[index++] = definitionToDisplay.getId();
}
}
@@ -302,8 +303,8 @@ public class MetricsGroupViewDataSource extends RPCDataSource<MetricDisplaySumma
this.metricDisplaySummaries = metricDisplaySummaries;
}
- private Set<MeasurementDefinition> getMetricDefinitions(ResourceGroup resourceGroup) {
- Set<MeasurementDefinition> definitions = new HashSet<MeasurementDefinition>();
+ private List<MeasurementDefinition> getMetricDefinitions(ResourceGroup resourceGroup) {
+ List<MeasurementDefinition> definitions = new ArrayList<MeasurementDefinition>();
for (MeasurementDefinition measurementDefinition : resourceGroup.getResourceType().getMetricDefinitions()) {
if (measurementDefinition.getDataType() == MEASUREMENT || measurementDefinition.getDataType() == COMPLEX) {
definitions.add(measurementDefinition);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/resource/detail/monitoring/table/MetricsViewDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/resource/detail/monitoring/table/MetricsViewDataSource.java
index 248eee0..db79dc0 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/resource/detail/monitoring/table/MetricsViewDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/resource/detail/monitoring/table/MetricsViewDataSource.java
@@ -24,6 +24,8 @@ import static org.rhq.core.domain.measurement.DataType.MEASUREMENT;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -351,7 +353,7 @@ public class MetricsViewDataSource extends RPCDataSource<MetricDisplaySummary, C
private void queryResourceMetrics(final Resource resource, final Long startTime, final Long endTime,
final CountDownLatch countDownLatch) {
- HashSet<MeasurementDefinition> definitions = getMetricDefinitions(resource);
+ List<MeasurementDefinition> definitions = getMetricDefinitions(resource);
if (definitions.size() == 0) {
countDownLatch.countDown();
return;
@@ -366,22 +368,21 @@ public class MetricsViewDataSource extends RPCDataSource<MetricDisplaySummary, C
}
}
- //build id mapping for measurementDefinition instances Ex. Free Memory -> MeasurementDefinition[100071]
- final HashMap<String, MeasurementDefinition> measurementDefMap = new HashMap<String, MeasurementDefinition>();
- for (MeasurementDefinition definition : definitions) {
- measurementDefMap.put(definition.getDisplayName(), definition);
- }
//bundle definition ids for asynch call.
definitionArrayIds = new int[definitions.size()];
- final String[] displayOrder = new String[definitions.size()];
- measurementDefMap.keySet().toArray(displayOrder);
+
//sort the charting data ex. Free Memory, Free Swap Space,..System Load
- Arrays.sort(displayOrder);
+ Collections.sort(definitions, new Comparator<MeasurementDefinition>() {
+ @Override
+ public int compare(MeasurementDefinition o1, MeasurementDefinition o2) {
+ return o1.getDisplayName().compareTo(o2.getDisplayName());
+ }
+ });
//organize definitionArrayIds for ordered request on server.
int index = 0;
- for (String definitionToDisplay : displayOrder) {
- definitionArrayIds[index++] = measurementDefMap.get(definitionToDisplay).getId();
+ for (MeasurementDefinition definitionToDisplay : definitions) {
+ definitionArrayIds[index++] = definitionToDisplay.getId();
}
GWTServiceLookup.getMeasurementDataService().findDataForResource(resource.getId(), definitionArrayIds,
@@ -405,8 +406,8 @@ public class MetricsViewDataSource extends RPCDataSource<MetricDisplaySummary, C
}
- private HashSet<MeasurementDefinition> getMetricDefinitions(Resource resource) {
- HashSet<MeasurementDefinition> definitions = new HashSet<MeasurementDefinition>();
+ private List<MeasurementDefinition> getMetricDefinitions(Resource resource) {
+ List<MeasurementDefinition> definitions = new ArrayList<MeasurementDefinition>();
for (MeasurementDefinition measurementDefinition : resource.getResourceType().getMetricDefinitions()) {
if (measurementDefinition.getDataType() == MEASUREMENT || measurementDefinition.getDataType() == COMPLEX) {
definitions.add(measurementDefinition);
commit 7f08f14c4c8a025b169e32e0378335cf9a243c36
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Jan 30 11:55:47 2014 -0500
Fix iPC -tests, allow negative resource ids; now possible for tests based
on FakeServerInventpory.
diff --git a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/avail/AvailTest.java b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/avail/AvailTest.java
index 5c9a5ca..85e1ec2 100644
--- a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/avail/AvailTest.java
+++ b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/avail/AvailTest.java
@@ -195,7 +195,7 @@ public class AvailTest extends Arquillian {
Assert.assertEquals(report.isChangesOnlyReport(), false, "First report should have been a full report");
List<Datum> availData = report.getResourceAvailability();
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource ID should be != zero since it should be committed";
Assert.assertEquals(datum.getAvailabilityType(), AvailabilityType.UP, "should be UP at the start");
}
AvailabilityExecutor.Scan scan = executor.getMostRecentScanHistory();
@@ -238,7 +238,7 @@ public class AvailTest extends Arquillian {
Assert.assertEquals(report.isChangesOnlyReport(), false, "First report should have been a full report");
List<Datum> availData = report.getResourceAvailability();
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be != zero since it should be committed";
Assert.assertEquals(datum.getAvailabilityType(), AvailabilityType.UP, "should be UP at the start");
}
AvailabilityExecutor.Scan scan = executor.getMostRecentScanHistory();
@@ -297,7 +297,7 @@ public class AvailTest extends Arquillian {
List<Datum> availData = report.getResourceAvailability();
int numUp = 0;
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be != zero since it should be committed";
if (datum.getAvailabilityType() == AvailabilityType.UP) {
++numUp;
}
@@ -342,7 +342,7 @@ public class AvailTest extends Arquillian {
Assert.assertEquals(report.getResourceAvailability().size(), 14, "should report half the resources");
availData = report.getResourceAvailability();
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be != zero since it should be committed";
Assert.assertEquals(datum.getAvailabilityType(), AvailabilityType.UP, "should be UP at the start");
}
scan = executor.getMostRecentScanHistory();
@@ -362,7 +362,7 @@ public class AvailTest extends Arquillian {
List<Datum> availData = report.getResourceAvailability();
int numUp = 0;
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be > zero since it should be committed";
if (datum.getAvailabilityType() == AvailabilityType.UP) {
++numUp;
}
@@ -414,7 +414,7 @@ public class AvailTest extends Arquillian {
Assert.assertEquals(report.getResourceAvailability().size(), 14, "should report half the resources");
availData = report.getResourceAvailability();
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be != zero since it should be committed";
Assert.assertEquals(datum.getAvailabilityType(), AvailabilityType.DOWN, "should be DOWN");
}
scan = executor.getMostRecentScanHistory();
@@ -433,7 +433,7 @@ public class AvailTest extends Arquillian {
Assert.assertEquals(report.isChangesOnlyReport(), false, "First report should have been a full report");
List<Datum> availData = report.getResourceAvailability();
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be != zero since it should be committed";
Assert.assertEquals(datum.getAvailabilityType(), AvailabilityType.UP, "should be UP at the start");
}
AvailabilityExecutor.Scan scan = executor.getMostRecentScanHistory();
@@ -474,7 +474,7 @@ public class AvailTest extends Arquillian {
Assert.assertEquals(report.getResourceAvailability().size(), 0, "no changes, everything was already up");
availData = report.getResourceAvailability();
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be != zero since it should be committed";
Assert.assertEquals(datum.getAvailabilityType(), AvailabilityType.UP, "should be UP at the start");
}
scan = executor.getMostRecentScanHistory();
@@ -499,7 +499,7 @@ public class AvailTest extends Arquillian {
Assert.assertEquals(report.isChangesOnlyReport(), false, "First report should have been a full report");
List<Datum> availData = report.getResourceAvailability();
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be != zero since it should be committed";
Assert.assertEquals(datum.getAvailabilityType(), AvailabilityType.UP, "should be UP at the start");
}
AvailabilityExecutor.Scan scan = executor.getMostRecentScanHistory();
@@ -525,7 +525,7 @@ public class AvailTest extends Arquillian {
Assert.assertEquals(report.getResourceAvailability().size(), 0, "no changes, everything was already up");
availData = report.getResourceAvailability();
for (Datum datum : availData) {
- assert datum.getResourceId() > 0 : "resource IDs should be > zero since it should be committed";
+ assert datum.getResourceId() != 0 : "resource IDs should be != zero since it should be committed";
Assert.assertEquals(datum.getAvailabilityType(), AvailabilityType.UP, "should be UP at the start");
}
scan = executor.getMostRecentScanHistory();
commit 37263f7ece17f28541702666009fe057a28452c1
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Jan 30 11:11:46 2014 -0500
BZ 1052390 - Clean up remoting wrapper to avoid race conditions if possible
Some unused or rarely constructors and methods were dropped.
The biggest change is in the client caching. The cache code is guaranteed to
call disconnect when a client is 'thrown away'. There is still a possibility
disconnect can happen in the middle of an invoke.
Original Author: Elias Ross <elias_ross(a)apple.com>
Signed-off-by: Jay Shaughnessy <jshaughn(a)redhat.com>
Applying this patch as-is, I see no issues with it and it cleans some
things up. Relevant tests are passing.
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/CmdlineClient.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/CmdlineClient.java
index 5e42cc2..a2186d0 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/CmdlineClient.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/CmdlineClient.java
@@ -20,6 +20,7 @@ package org.rhq.enterprise.communications.command.client;
import gnu.getopt.Getopt;
import gnu.getopt.LongOpt;
+
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
@@ -27,7 +28,10 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
+
import mazz.i18n.Logger;
+
+import org.jboss.remoting.InvokerLocator;
import org.rhq.enterprise.communications.command.Command;
import org.rhq.enterprise.communications.command.CommandResponse;
import org.rhq.enterprise.communications.command.CommandType;
@@ -212,7 +216,8 @@ public class CmdlineClient {
throw new MalformedURLException(LOG.getMsgString(CommI18NResourceKeys.CMDLINE_CLIENT_NULL_URI));
}
- JBossRemotingRemoteCommunicator communicator = new JBossRemotingRemoteCommunicator(m_locatorUri, m_subsystem);
+ InvokerLocator invokerLocator = new InvokerLocator(m_locatorUri);
+ JBossRemotingRemoteCommunicator communicator = new JBossRemotingRemoteCommunicator(invokerLocator, m_subsystem, null);
commandClient.setRemoteCommunicator(communicator);
// tell the concrete command client instance to invoke the command on the remote server
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 0acc1c7..9bcf181 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -22,6 +22,7 @@ import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
@@ -30,7 +31,6 @@ import mazz.i18n.Logger;
import org.jboss.remoting.Client;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.ServerInvoker;
-
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.enterprise.communications.command.Command;
import org.rhq.enterprise.communications.command.CommandResponse;
@@ -47,12 +47,11 @@ import org.rhq.enterprise.communications.util.NotPermittedException;
* where the command is to be invoked.</p>
*
* <p>Under the covers, a {@link org.jboss.remoting.Client remoting client} is created and maintained by this object.
- * The users of this object may manually {@link #connect() connect} and {@link #disconnect() disconnect} that remoting
- * client. Typically, there will not be a need to connect since it will be done automatically when appropriate; however,
- * it is good practice to tell this object to disconnect its remoting client when this object is no longer needed to
+ * There is no need to call {@link #connect()} since it will be done automatically when appropriate; however,
+ * it is good practice to tell this object to {@link #disconnect()} its client when no longer necessary to
* issue commands to the remote server.</p>
*
- * <p>All subclasses should include a no-arg constructor so they can be built dynamically by the cmdline client.</p>
+ * <p>All subclasses should include a no-arg constructor so they can be built dynamically by the command line client.</p>
*
* @author John Mazzitelli
*/
@@ -67,41 +66,40 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
/**
* the JBoss/Remoting locator that this client will use to remotely connect to the command server
*/
- private InvokerLocator m_invokerLocator;
+ private volatile InvokerLocator m_invokerLocator;
/**
* The subsystem to target when invoking commands. The subsystem is defined by the JBoss/Remoting API - it specifies
* the actual invoker handler to target. The Command framework uses the subsystem to organize command processors
* into different domains.
*/
- private String m_subsystem;
+ private final String m_subsystem;
/**
* The configuration to send to the client - used to configure things like the SSL setup.
*/
- private Map<String, String> m_clientConfiguration;
+ private final Map<String, String> m_clientConfiguration;
/**
* the actual JBoss/Remoting client object that will be used to transport the commands to the server
*/
- private Client m_remotingClient;
+ private volatile AtomicReference<Client> m_client = new AtomicReference<Client>();
/**
- * Optionally-defined callback that will be called when a failure is detected when sending a message.
+ * Optionally-defined callback that will be called when a failure is detected when sending a message.
*/
- private FailureCallback m_failureCallback;
+ private volatile FailureCallback m_failureCallback;
/**
- * Optionally-defined callback that will be called when this communicator sends its first command
- * after it has been {@link #connect() connected}.
+ * Optionally-defined callback that will be called when this communicator sends its first command.
*/
- private InitializeCallback m_initializeCallback;
+ private volatile InitializeCallback m_initializeCallback;
/**
* When <code>true</code>, the initialize callback will need to be called prior
* to sending any commands. Used in conjunection with its associated RW lock.
*/
- private boolean m_needToCallInitializeCallback;
+ private volatile boolean m_needToCallInitializeCallback;
/**
* RW lock when needing to access its associated atomic boolean flag.
@@ -109,25 +107,13 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private final ReentrantReadWriteLock m_needToCallInitializeCallbackLock;
/**
- * Number of minutes to wait while attempting to aquire a lock before attempting
+ * Number of minutes to wait while attempting to acquire a lock before attempting
* to invoke the initialize callback. If this amount of minutes expires before the lock
* is acquired, an error will occur and the initialize callback will have to be attempted later.
*/
private final long m_initializeCallbackLockAcquisitionTimeoutMins;
/**
- * Constructor for {@link JBossRemotingRemoteCommunicator} that initializes the client with no invoker locator
- * defined. It must later be specified through {@link #setInvokerLocator(InvokerLocator)} before any client commands
- * can be issued. In addition, the {@link #getSubsystem()} will be set to the {@link #DEFAULT_SUBSYSTEM}.
- *
- * <p>Note that all subclasses are strongly urged to include this no-arg constructor so it can plug into the cmdline
- * client seamlessly.</p>
- */
- public JBossRemotingRemoteCommunicator() {
- this((InvokerLocator) null, DEFAULT_SUBSYSTEM);
- }
-
- /**
* Constructor for {@link JBossRemotingRemoteCommunicator} that allows you to indicate the
* {@link InvokerLocator invoker locator} to use by specifying the locator's URI. The subsystem will be set to the
* {@link #DEFAULT_SUBSYSTEM}.
@@ -137,7 +123,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
* @throws MalformedURLException if failed to create the locator (see {@link InvokerLocator#InvokerLocator(String)})
*/
public JBossRemotingRemoteCommunicator(String locatorUri) throws MalformedURLException {
- this(new InvokerLocator(locatorUri), DEFAULT_SUBSYSTEM);
+ this(new InvokerLocator(locatorUri), DEFAULT_SUBSYSTEM, null);
}
/**
@@ -160,45 +146,6 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
* Constructor for {@link JBossRemotingRemoteCommunicator} that allows you to specify the
* {@link InvokerLocator invoker locator} to use. <code>locator</code> may be <code>null</code>, in which case, it
* must later be specified through {@link #setInvokerLocator(InvokerLocator)} before any client commands can be
- * issued. The subsystem will be set to the {@link #DEFAULT_SUBSYSTEM}.
- *
- * @param locator the locator to use (may be <code>null</code>)
- */
- public JBossRemotingRemoteCommunicator(InvokerLocator locator) {
- this(locator, DEFAULT_SUBSYSTEM);
- }
-
- /**
- * Constructor for {@link JBossRemotingRemoteCommunicator} that allows you to specify the
- * {@link InvokerLocator invoker locator} to use. <code>locator</code> may be <code>null</code>, in which case, it
- * must later be specified through {@link #setInvokerLocator(InvokerLocator)} before any client commands can be
- * issued.The subsystem will be set to the {@link #DEFAULT_SUBSYSTEM}. The given <code>Map</code> should contain
- * <code>Client</code> configuration attributes.
- *
- * @param locator the locator to use (may be <code>null</code>)
- * @param client_config the client configuration (may be <code>null</code> or empty)
- */
- public JBossRemotingRemoteCommunicator(InvokerLocator locator, Map<String, String> client_config) {
- this(locator, DEFAULT_SUBSYSTEM, client_config);
- }
-
- /**
- * Constructor for {@link JBossRemotingRemoteCommunicator} that allows you to specify the
- * {@link InvokerLocator invoker locator} to use. <code>locator</code> may be <code>null</code>, in which case, it
- * must later be specified through {@link #setInvokerLocator(InvokerLocator)} before any client commands can be
- * issued.
- *
- * @param locator the locator to use (may be <code>null</code>)
- * @param subsystem the subsystem (or command domain) in which commands will be invoked (may be <code>null</code>)
- */
- public JBossRemotingRemoteCommunicator(InvokerLocator locator, String subsystem) {
- this(locator, subsystem, null);
- }
-
- /**
- * Constructor for {@link JBossRemotingRemoteCommunicator} that allows you to specify the
- * {@link InvokerLocator invoker locator} to use. <code>locator</code> may be <code>null</code>, in which case, it
- * must later be specified through {@link #setInvokerLocator(InvokerLocator)} before any client commands can be
* issued.
*
* @param locator the locator to use (may be <code>null</code>)
@@ -222,7 +169,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
try {
String minsStr = System.getProperty("rhq.communications.initial-callback-lock-wait-mins", "60");
mins = Long.parseLong(minsStr);
- } catch (Throwable t) {
+ } catch (Exception e) {
mins = 60L;
}
m_initializeCallbackLockAcquisitionTimeoutMins = mins;
@@ -231,36 +178,6 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
}
/**
- * Constructor for {@link JBossRemotingRemoteCommunicator} that allows you to indicate the
- * {@link InvokerLocator invoker locator} to use by specifying the locator's URI.
- *
- * @param locatorUri the locator's URI (must not be <code>null</code>)
- * @param subsystem the subsystem (or command domain) in which commands will be invoked (may be <code>null</code>)
- *
- * @throws MalformedURLException if failed to create the locator (see {@link InvokerLocator#InvokerLocator(String)})
- */
- public JBossRemotingRemoteCommunicator(String locatorUri, String subsystem) throws MalformedURLException {
- this(new InvokerLocator(locatorUri), subsystem);
- }
-
- /**
- * Constructor for {@link JBossRemotingRemoteCommunicator} that allows you to indicate the
- * {@link InvokerLocator invoker locator} to use by specifying the locator's URI. The given <code>Map</code> should
- * contain <code>Client</code> configuration attributes.
- *
- * @param locatorUri the locator's URI (must not be <code>null</code>)
- * @param subsystem the subsystem (or command domain) in which commands will be invoked (may be <code>
- * null</code>)
- * @param client_config the client configuration (may be <code>null</code> or empty)
- *
- * @throws MalformedURLException if failed to create the locator (see {@link InvokerLocator#InvokerLocator(String)})
- */
- public JBossRemotingRemoteCommunicator(String locatorUri, String subsystem, Map<String, String> client_config)
- throws MalformedURLException {
- this(new InvokerLocator(locatorUri), subsystem, client_config);
- }
-
- /**
* Returns the invoker locator that is to be used to find the remote JBoss/Remoting server. If <code>null</code> is
* returned, this communicator will not be able to issue commands.
*
@@ -281,81 +198,14 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
* null</code>)
*
* @throws MalformedURLException if failed to create the locator (see {@link InvokerLocator#InvokerLocator(String)})
- *
- * @see #setInvokerLocator(InvokerLocator)
- */
- public void setInvokerLocator(String locatorUri) throws MalformedURLException {
- setInvokerLocator(new InvokerLocator(locatorUri));
- }
-
- /**
- * Sets the invoker locator URI and creates a new locator that is to be used to find the remote JBoss/Remoting
- * server for its subsequent command client invocations. Any existing remoting client is automatically disconnected.
- * New remoting clients will also be configured with the new set of configuration properties - thus allowing you to
- * configure the client to be able to handle the new locator.
- *
- * @param locatorUri the new invoker locator's URI to use for future command client invocations (must not be
- * <code>null</code>)
- * @param client_config the client configuration for any new remoting clients that are created (may be <code>
- * null</code> or empty)
- *
- * @throws MalformedURLException if failed to create the locator (see {@link InvokerLocator#InvokerLocator(String)})
- *
- * @see #setInvokerLocator(InvokerLocator)
- */
- public void setInvokerLocator(String locatorUri, Map<String, String> client_config) throws MalformedURLException {
- setInvokerLocator(new InvokerLocator(locatorUri), client_config);
- }
-
- /**
- * Sets the invoker locator that this communicator should use for its subsequent command client invocations. Any
- * existing remoting client is automatically disconnected.The client configuration properties will, however, remain
- * the same as before - so the new clients that are created will have the same configuration attributes. See
- * {@link #setInvokerLocator(InvokerLocator, Map)} if you want to reconfigure the client with different properties
- * that are more appropriate for the new locator.
- *
- * @param locator the new invoker locator to use for future command client invocations (must not be <code>
- * null</code>)
- *
- * @throws IllegalArgumentException if locator is <code>null</code>
- */
- public void setInvokerLocator(InvokerLocator locator) {
- setInvokerLocator(locator, null);
- }
-
- /**
- * Sets the invoker locator that this communicator should use for its subsequent command client invocations. Any
- * existing remoting client is automatically disconnected. New remoting clients will also be configured with the new
- * set of configuration properties - thus allowing you to configure the client to be able to handle the new locator.
- *
- * @param locator the new invoker locator to use for future command client invocations (must not be <code>
- * null</code>)
- * @param client_config the client configuration for any new remoting clients that are created (may be <code>
- * null</code> or empty)
- *
- * @throws IllegalArgumentException if locator is <code>null</code>
*/
- public void setInvokerLocator(InvokerLocator locator, Map<String, String> client_config) {
- if (locator == null) {
- throw new IllegalArgumentException("locator=null");
- }
-
- // since a new invoker locator is being specified, disconnect any old client that already exists
- if (m_remotingClient != null) {
- m_remotingClient.disconnect();
- m_remotingClient = null;
- m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
- }
-
+ public void setRemoteEndpoint(String endpoint) throws Exception {
+ InvokerLocator locator = new InvokerLocator(endpoint);
LOG.info(CommI18NResourceKeys.COMMUNICATOR_CHANGING_ENDPOINT, m_invokerLocator, locator);
m_invokerLocator = locator;
- if (client_config != null) {
- m_clientConfiguration.clear();
- m_clientConfiguration.putAll(client_config);
- }
-
- return;
+ // since a new invoker locator is being specified, disconnect any old client that already exists
+ disconnect();
}
/**
@@ -369,25 +219,6 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
return m_subsystem;
}
- /**
- * Sets the value of the subsystem that will be used to target command invocations. The subsystem is defined by the
- * JBoss/Remoting API and can be used by the Command Framework to organize command processors into different
- * domains.
- *
- * <p>If a remoting client already exists, its subsystem will be changed to the given subsystem.</p>
- *
- * @param subsystem the new value of subsystem (may be <code>null</code>)
- */
- public void setSubsystem(String subsystem) {
- m_subsystem = subsystem;
-
- if (m_remotingClient != null) {
- m_remotingClient.setSubsystem(subsystem);
- }
-
- return;
- }
-
public FailureCallback getFailureCallback() {
return m_failureCallback;
}
@@ -402,17 +233,13 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void setInitializeCallback(InitializeCallback callback) {
m_initializeCallback = callback;
- m_needToCallInitializeCallback = (callback != null); // specifically do not synchrononize by using lock, just set it
+ m_needToCallInitializeCallback = (callback != null); // specifically do not synchronize by using lock, just set it
}
public String getRemoteEndpoint() {
return (m_invokerLocator != null) ? m_invokerLocator.getLocatorURI() : "<null>";
}
- public void setRemoteEndpoint(String endpoint) throws Exception {
- setInvokerLocator(endpoint);
- }
-
/**
* Returns the map of name/value pairs of client configuration settings used when creating the client. The returned
* map is a copy - changing its contents has no effect on the clients that already have been or will be created by
@@ -425,26 +252,31 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
return new HashMap<String, String>(m_clientConfiguration);
}
+ /**
+ * Does nothing; send a request to connect.
+ */
public void connect() throws Exception {
- if ((m_remotingClient != null) && !m_remotingClient.isConnected()) {
- m_remotingClient.connect();
- m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
+ /*
+ * For the HTTP invoker, simply calling connect() doesn't do anything. It makes
+ * sense to at least send something to test connectivity. However, the code doesn't
+ * make use of this method.
+ try {
+ send(new EchoCommand());
+ } catch (Exception e) {
+ throw e;
+ } catch (Throwable t) {
+ throw new Error(t);
}
-
- return;
+ */
}
public void disconnect() {
- if (m_remotingClient != null) {
- m_remotingClient.disconnect();
- m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
- }
-
- return;
+ cacheClient(null);
}
public boolean isConnected() {
- return (m_remotingClient != null) && m_remotingClient.isConnected();
+ Client client = m_client.get();
+ return (client != null) && client.isConnected();
}
public CommandResponse sendWithoutCallbacks(Command command) throws Throwable {
@@ -455,7 +287,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
retry = false;
ret_response = rawSend(command);
Throwable exception = ret_response.getException();
- if ((exception != null) && (exception instanceof NotPermittedException)) {
+ if (exception instanceof NotPermittedException) {
long pause = ((NotPermittedException) exception).getSleepBeforeRetry();
LOG.debug(CommI18NResourceKeys.COMMAND_NOT_PERMITTED, command, pause);
retry = true;
@@ -498,11 +330,11 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
/**
* The code that sends the command via the remote client.
- *
+ *
* @param command the command to send
- *
+ *
* @return the command response
- *
+ *
* @throws Throwable if a low-level, unhandled exception occurred
*/
private CommandResponse rawSend(Command command) throws Throwable {
@@ -511,13 +343,13 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
try {
try {
OutgoingCommandTrace.start(command);
- ret_response = getRemotingClient().invoke(command, null);
+ ret_response = invoke(command);
OutgoingCommandTrace.finish(command, ret_response);
} catch (ServerInvoker.InvalidStateException serverDown) {
// under rare condition, a bug in remoting 2.2 causes this when the server restarted
// try it one more time, this will get a new server thread on the server side (JBREM-745)
// once JBREM-745 is fixed, we can probably get rid of this catch block
- ret_response = getRemotingClient().invoke(command, null);
+ ret_response = invoke(command);
OutgoingCommandTrace.finish(command, ret_response);
}
} catch (Throwable t) {
@@ -548,12 +380,12 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
* call it. The initialize callback has the responsibility to handle calling
* {@link #sendWithoutInitializeCallback(Command)} if it wants to send its own commands to the server
* but wants failover to happen when appropriate for those commands.
- *
+ *
* If there is an initialize callback set, this method will block all callers until
* the callback has been invoked.
*
* @param command the command that it going to be sent after the callback is invoked
- *
+ *
* @return if the initialize callback had an error, this response will be non-<code>null</code> and
* will indicate that the sending of <code>command</code> should be aborted.
*/
@@ -600,14 +432,14 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
/**
* This will invoke the failure callback when necessary. It is necessary to call the callback
* when the throwable is not <code>null</code> or the command response has a non-<code>null</code> exception.
- *
+ *
* This method will force a retry by returning <code>true</code>. If <code>false</code> is returned,
* the request need not be retried.
- *
+ *
* @param command the command that was sent (or attempted to be sent)
* @param response the response of the command (may be <code>null</code>)
* @param throwable the exception that was thrown when the command was sent (may be <code>null</code>)
- *
+ *
* @return <code>true</code> if the command should be retried, <code>false</code> otherwise
*/
private boolean invokeFailureCallbackIfNeeded(Command command, CommandResponse response, Throwable throwable) {
@@ -615,7 +447,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
FailureCallback callback = getFailureCallback(); // get a local reference to avoid this being changed underneath us
boolean retry = false;
- // only do something if there is a callback defined
+ // only do something if there is a callback defined
if (callback != null) {
// only do something if the command resulted in an exception
if (throwable != null || ((response != null) && (response.getException() != null))) {
@@ -638,28 +470,48 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
}
/**
- * Returns the remoting client that is to be used to transport the command request to the server. If for any reason
- * the client cannot be created, an exception is thrown. This will happen if the invoker locator has not been
- * specified (see {@link #setInvokerLocator(InvokerLocator)}).
- *
- * <p>This method will cache the client and connect to the server automatically. Note that the client will be
- * disconnected whenever the invoker is reset via {@link #setInvokerLocator(InvokerLocator)}. Therefore, callers
- * should never cache the returned object themselves - always call this method to obtain a reference to the
- * client.</p>
- *
- * @return the client to be used to transport the command request to the server
+ * Invokes JBoss Remoting using the given command.
+ * Attempts to cache the client if sending the message was successful.
*
- * @throws Exception if failed to create the client for whatever reason
+ * @return object as a result of this call
*/
- protected Client getRemotingClient() throws Exception {
- if (m_remotingClient == null) {
- m_remotingClient = new Client(getInvokerLocator(), getSubsystem(), m_clientConfiguration);
+ private Object invoke(Command command) throws Throwable {
+ InvokerLocator locator = m_invokerLocator;
+ if (locator == null) {
+ throw new IllegalStateException("m_invokerLocator is null");
}
- if (!m_remotingClient.isConnected()) {
- m_remotingClient.connect();
+ Client client = m_client.get();
+ if (client != null && client.getInvoker() == null) {
+ client.disconnect();
+ }
+ if (client == null || !client.isConnected()) {
+ client = new Client(locator, getSubsystem(), m_clientConfiguration);
+ client.connect();
+ try {
+ return client.invoke(command);
+ } finally {
+ cacheClient(client);
+ }
}
- return m_remotingClient;
+ // Note: Despite all the checks above, the client might have been
+ // disconnected before invoke is reached. Let's hope that doesn't happen.
+
+ return client.invoke(command);
+ }
+
+ /**
+ * Cache the client, disconnecting the old client.
+ *
+ * @param client optionally null; new client to cache
+ */
+ private void cacheClient(Client client) {
+ Client old = m_client.getAndSet(client);
+ if (old != null) {
+ old.disconnect();
+ m_needToCallInitializeCallback = (getInitializeCallback() != null);
+ }
}
+
}
commit c9ea7f80a610d0ce22376f76723f8445c6d9cfd7
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Thu Jan 30 14:37:33 2014 +0100
Bug 1026513 - File systems that are offline or not available are still being reported as UP
Return AvailabilityType.UP only if the directory name of the FileSystem is the same as the resource key.
diff --git a/modules/core/native-system/src/main/java/org/rhq/core/system/FileSystemInfo.java b/modules/core/native-system/src/main/java/org/rhq/core/system/FileSystemInfo.java
index 6d5ada6..372b434 100644
--- a/modules/core/native-system/src/main/java/org/rhq/core/system/FileSystemInfo.java
+++ b/modules/core/native-system/src/main/java/org/rhq/core/system/FileSystemInfo.java
@@ -1,25 +1,21 @@
/*
-* RHQ Management Platform
-* Copyright (C) 2005-2012 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, version 2, as
-* published by the Free Software Foundation, and/or the GNU Lesser
-* General Public License, version 2.1, also as published by the Free
-* Software Foundation.
-*
-* 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 and the GNU Lesser General Public License
-* for more details.
-*
-* You should have received a copy of the GNU General Public License
-* and the GNU Lesser 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.
-*/
+ * RHQ Management Platform
+ * Copyright (C) 2005-2014 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.core.system;
import org.apache.commons.logging.Log;
@@ -36,7 +32,7 @@ import org.hyperic.sigar.SigarProxy;
* @author John Mazzitelli
*/
public class FileSystemInfo {
- private final Log log = LogFactory.getLog(this.getClass());
+ private static final Log LOG = LogFactory.getLog(FileSystemInfo.class);
private final String mountPoint;
private FileSystem fs;
@@ -66,14 +62,14 @@ public class FileSystemInfo {
// this happens when the file system is not available (e.g. if it's a CD-ROM without a CD loaded in it) or
// if we don't have permission to access the filesystem. we can ignore it and set the usage data to null.
this.fsUsage = null;
- if (log.isTraceEnabled()) {
- log.trace("Cannot refresh the usage data for file system mounted at [" + this.mountPoint + "].", e);
- } else {
- log.debug("Cannot refresh the usage data for file system mounted at [" + this.mountPoint + "]: " + e);
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Cannot refresh the usage data for file system mounted at [" + this.mountPoint + "].", e);
+ } else if (LOG.isDebugEnabled()) {
+ LOG.debug("Cannot refresh the usage data for file system mounted at [" + this.mountPoint + "]: " + e);
}
} catch (RuntimeException e) {
this.fsUsage = null;
- log.error("An error occurred while refreshing the usage data for file system mounted at [" + this.mountPoint
+ LOG.error("An error occurred while refreshing the usage data for file system mounted at [" + this.mountPoint
+ "].", e);
}
}
@@ -110,4 +106,4 @@ public class FileSystemInfo {
", fsUsage=" + fsUsage +
']';
}
-}
\ No newline at end of file
+}
diff --git a/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemComponent.java b/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemComponent.java
index 5eae991..02d0b68 100644
--- a/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemComponent.java
+++ b/modules/plugins/platform/src/main/java/org/rhq/plugins/platform/FileSystemComponent.java
@@ -59,8 +59,8 @@ public class FileSystemComponent implements ResourceComponent<PlatformComponent>
public AvailabilityType getAvailability() {
FileSystemInfo fileSystemInfo = getFileSystemInfo();
- // fileSystemInfo can be != null even if the fs is unmounted.
- if (fileSystemInfo != null && fileSystemInfo.getFileSystem() != null) {
+ if (fileSystemInfo != null && fileSystemInfo.getFileSystem() != null
+ && this.resourceContext.getResourceKey().equals(fileSystemInfo.getFileSystem().getDirName())) {
return AvailabilityType.UP;
} else {
return AvailabilityType.DOWN;
@@ -94,5 +94,4 @@ public class FileSystemComponent implements ResourceComponent<PlatformComponent>
SystemInfo systemInfo = resourceContext.getSystemInformation();
return systemInfo.getFileSystem(resourceContext.getResourceKey());
}
-
-}
\ No newline at end of file
+}
commit 6785f80b99a4def0128939113fd5af7d3b4ebee5
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Thu Jan 30 12:30:48 2014 +0100
Bug 1025050 - EAP 6 plug-in should not require start script environment variables to be set
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 000d08c..bda2e5e 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -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 org.rhq.modules.plugins.jbossas7.ASConnection.verbose;
@@ -361,7 +362,9 @@ public class BaseComponent<T extends ResourceComponent<?>> implements AS7Compone
@Override
public void deleteResource() throws Exception {
- getLog().info("Removing AS7 resource [" + path + "]...");
+ if (getLog().isDebugEnabled()) {
+ getLog().debug("Removing AS7 resource [" + path + "]...");
+ }
if (context.getResourceType().getName().equals(MANAGED_SERVER)) {
// We need to do two steps because of AS7-4032
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 5e2f272..bc7112a 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
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -121,7 +121,9 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend
try {
if ((availabilityType == AvailabilityType.UP) && (previousAvailabilityType != AvailabilityType.UP)) {
validateServerAttributes();
- log.info(getResourceDescription() + " has just come UP.");
+ if (log.isDebugEnabled()) {
+ log.debug(getResourceDescription() + " has just come UP.");
+ }
}
} finally {
previousAvailabilityType = availabilityType;
@@ -423,13 +425,6 @@ public abstract class BaseServerComponent<T extends ResourceComponent<?>> extend
}
}
- Map<String, String> startScriptEnv = startScriptConfig.getStartScriptEnv();
- if (startScriptEnv.isEmpty()) {
- errors.add("No start script environment variables are set. At a minimum, PATH should be set "
- + "(on UNIX, it should contain at least /bin and /usr/bin). It is recommended that "
- + "JAVA_HOME also be set, otherwise the PATH will be used to find java.");
- }
-
return errors;
}
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java
index d0f023a..1fd155c 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -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.itest;
import static org.testng.Assert.assertEquals;
@@ -199,17 +200,17 @@ public abstract class AbstractServerComponentTest extends AbstractJBossAS7Plugin
}
protected void validateStartScriptEnv(Map<String, String> env) {
- Assert.assertTrue(env.size() <= 4, env.toString());
-
String javaHome = env.get("JAVA_HOME");
- Assert.assertNotNull(javaHome);
- Assert.assertTrue(new File(javaHome).isDirectory());
+ if (javaHome != null) {
+ Assert.assertTrue(new File(javaHome).isDirectory());
+ }
String path = env.get("PATH");
- Assert.assertNotNull(path);
- String[] pathElements = path.split(File.pathSeparator);
- Assert.assertTrue(pathElements.length >= 1);
- Assert.assertTrue(new File(pathElements[0]).isDirectory());
+ if (path != null) {
+ String[] pathElements = path.split(File.pathSeparator);
+ Assert.assertTrue(pathElements.length >= 1);
+ Assert.assertTrue(new File(pathElements[0]).isDirectory());
+ }
}
protected abstract String getBindAddressSystemPropertyName();
commit 5df3797396c237111cfcbd14dbf8c27e078384b1
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Thu Jan 30 11:41:44 2014 +0100
Fix UnsupportedOperationException @ ContentManager.handleDiscoveredContent
This was due to org.rhq.core.pc.inventory.ResourceContainer#getInstalledPackages, which used to create a new empty set, and now returns Collections#emptySet, which is immutable.
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
index 853d3b1..464978d 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/content/ContentManager.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -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.core.pc.content;
import static org.rhq.core.domain.resource.InventoryStatus.COMMITTED;
@@ -588,10 +589,8 @@ public class ContentManager extends AgentService implements ContainerService, Co
ResourceContainer container = inventoryManager.getResourceContainer(resourceId);
Set<ResourcePackageDetails> updatedPackageSet = new HashSet<ResourcePackageDetails>(details);
- Set<ResourcePackageDetails> existingInstalledPackagesSet = container.getInstalledPackages();
- if (existingInstalledPackagesSet == null) {
- existingInstalledPackagesSet = new HashSet<ResourcePackageDetails>();
- }
+ Set<ResourcePackageDetails> existingInstalledPackagesSet = new HashSet<ResourcePackageDetails>(
+ container.getInstalledPackages());
// Strip out content that have been removed (i.e. not returned on the latest discovery)
int originalPackageCount = existingInstalledPackagesSet.size();
diff --git a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/InventoryPrinter.java b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/InventoryPrinter.java
index bcaa45d..9f667a4 100644
--- a/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/InventoryPrinter.java
+++ b/modules/core/plugin-container/src/main/java/org/rhq/core/pc/util/InventoryPrinter.java
@@ -1,25 +1,22 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2012 Red Hat, Inc.
+ * Copyright (C) 2005-2014 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, version 2, as
- * published by the Free Software Foundation, and/or the GNU Lesser
- * General Public License, version 2.1, also as published by the Free
- * Software Foundation.
+ * 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 and the GNU Lesser General Public License
- * for more details.
+ * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * and the GNU Lesser 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.
+ * 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.core.pc.util;
import java.io.PrintWriter;
@@ -32,6 +29,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.drift.DriftDefinition;
import org.rhq.core.domain.measurement.Availability;
import org.rhq.core.domain.measurement.AvailabilityType;
@@ -223,10 +221,8 @@ public class InventoryPrinter {
}
String availString = (availType == null) ? "UNKNOWN" : availType.toString();
- int installedPackageCount = 0;
- if (resourceContainer.getInstalledPackages() != null) {
- installedPackageCount = resourceContainer.getInstalledPackages().size();
- }
+ Set<ResourcePackageDetails> installedPackages = resourceContainer.getInstalledPackages();
+ int installedPackageCount = installedPackages == null ? 0 : installedPackages.size();
if (dumpXml) {
exportWriter.printf("%s<resource>\n", indent);
@@ -434,4 +430,4 @@ public class InventoryPrinter {
return serviceCount;
}
}
-}
\ No newline at end of file
+}
commit 6a73a05d0513170a7bf8d1bc80110694b9f942e8
Author: Mike Thompson <mithomps(a)redhat.com>
Date: Wed Jan 29 15:14:46 2014 -0800
[BZ 909155] Error message when setting start date = 00:00 and end date = 24:00.
Changed to individual spinnerItem controls that limit the hours to 23 so valid dates are enforced by the choice up front.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/common/graph/ButtonBarDateTimeRangeEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/common/graph/ButtonBarDateTimeRangeEditor.java
index 89869eb..8281a24 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/common/graph/ButtonBarDateTimeRangeEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/inventory/common/graph/ButtonBarDateTimeRangeEditor.java
@@ -33,7 +33,7 @@ import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.DateItem;
import com.smartgwt.client.widgets.form.fields.RowSpacerItem;
-import com.smartgwt.client.widgets.form.fields.TimeItem;
+import com.smartgwt.client.widgets.form.fields.SpinnerItem;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
@@ -257,18 +257,21 @@ public class ButtonBarDateTimeRangeEditor extends EnhancedVLayout {
public CustomDateRangeWindow(String title, String windowTitle,
final ButtonBarDateTimeRangeEditor buttonBarDateTimeRangeEditor, Date startTime, Date endTime) {
super();
- setTitle(windowTitle + ": " + title);
+ setTitle("");
setShowMinimizeButton(false);
setShowMaximizeButton(false);
setShowCloseButton(true);
setIsModal(true);
setShowModalMask(true);
- setWidth(450);
- setHeight(340);
+ setWidth(420);
+ setHeight(450);
setShowResizer(true);
setCanDragResize(true);
centerInPage();
+
DynamicForm form = new DynamicForm();
+ form.setGroupTitle(windowTitle + " "+title);
+ form.setIsGroup(true);
form.setMargin(25);
form.setAutoFocus(true);
form.setShowErrorText(true);
@@ -277,15 +280,44 @@ public class ButtonBarDateTimeRangeEditor extends EnhancedVLayout {
form.setWidth100();
form.setPadding(5);
form.setLayoutAlign(VerticalAlignment.BOTTOM);
+
final DateItem startDateItem = new DateItem("startDate", MSG.common_buttonbar_start_date());
startDateItem.setValue(startTime);
- final TimeItem startTimeItem = new TimeItem("startTime", MSG.common_buttonbar_start_time());
- startTimeItem.setValue(startTime);
+
+ final SpinnerItem startTimeHours = new SpinnerItem("startTimeHours",MSG.chart_slider_button_bar_hour());
+ startTimeHours.setMax(23);
+ startTimeHours.setMin(0);
+ startTimeHours.setWidth(60);
+ startTimeHours.setValue(startDateItem.getValueAsDate().getHours());
+
+ final SpinnerItem startTimeMinutes = new SpinnerItem("startTimeMinutes",MSG.chart_slider_button_bar_minute());
+ startTimeMinutes.setMax(59);
+ startTimeMinutes.setStep(5);
+ startTimeMinutes.setMin(0);
+ startTimeMinutes.setWidth(60);
+ startTimeMinutes.setEndRow(true);
+ startTimeMinutes.setValue(startDateItem.getValueAsDate().getMinutes());
+
final DateItem endDateItem = new DateItem("endDate", MSG.common_buttonbar_end_date());
endDateItem.setValue(endTime);
- final TimeItem endTimeItem = new TimeItem("endTime", MSG.common_buttonbar_end_time());
- endTimeItem.setValue(endTime);
- form.setFields(startDateItem, startTimeItem, new RowSpacerItem(), endDateItem, endTimeItem,
+
+ final SpinnerItem endTimeHours = new SpinnerItem("endTimeHours", MSG.chart_slider_button_bar_hour());
+ endTimeHours.setMax(23);
+ endTimeHours.setMin(0);
+ endTimeHours.setWidth(60);
+ endTimeHours.setValue(endDateItem.getValueAsDate().getHours());
+
+ final SpinnerItem endTimeMinutes = new SpinnerItem("endTimeMinutes",MSG.chart_slider_button_bar_minute());
+ endTimeMinutes.setMax(59);
+ endTimeMinutes.setMin(0);
+ endTimeMinutes.setStep(5);
+ endTimeMinutes.setWidth(60);
+ endTimeMinutes.setValue(endDateItem.getValueAsDate().getMinutes());
+
+ form.setFields(startDateItem, startTimeHours, startTimeMinutes,
+ new RowSpacerItem(), new RowSpacerItem(),
+ endDateItem,
+ endTimeHours, endTimeMinutes,
new RowSpacerItem());
this.addItem(form);
@@ -305,15 +337,13 @@ public class ButtonBarDateTimeRangeEditor extends EnhancedVLayout {
saveButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent clickEvent) {
- Date startTimeDate = (Date) startTimeItem.getValue();
- Date endTimeDate = (Date) endTimeItem.getValue();
-
+ //@todo: eventually get rid of deprecated calls but not in 3.2.1 minor release
Date newStartDate = new Date(startDateItem.getValueAsDate().getYear(), startDateItem
- .getValueAsDate().getMonth(), startDateItem.getValueAsDate().getDate(), startTimeDate
- .getHours(), startTimeDate.getMinutes());
+ .getValueAsDate().getMonth(), startDateItem.getValueAsDate().getDate(), (Integer) startTimeHours.getValue(),
+ (Integer) startTimeMinutes.getValue());
Date newEndDate = new Date(endDateItem.getValueAsDate().getYear(), endDateItem.getValueAsDate()
- .getMonth(), endDateItem.getValueAsDate().getDate(), endTimeDate.getHours(), endTimeDate
- .getMinutes());
+ .getMonth(), endDateItem.getValueAsDate().getDate(), (Integer) endTimeHours.getValue(),
+ (Integer) endTimeMinutes.getValue());
buttonBarDateTimeRangeEditor.saveDateRange(newStartDate.getTime(), newEndDate.getTime());
redrawGraphs();
showUserFriendlyTimeRange(newStartDate.getTime(), newEndDate.getTime());
commit 81c5903f3844a3bc5102ed9b21172ed153a6433e
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Jan 29 15:27:42 2014 -0500
Potential fix for intermittent server i-test failure: when waiting for
inventory depth make sure to wait on the inventory manager's view, not
the server-side/fake inv view.
diff --git a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java
index cb799de..74a35ad 100644
--- a/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java
+++ b/modules/core/plugin-container-itest/src/test/java/org/rhq/core/pc/inventory/AbstractIgnoreTypesInventoryManagerBaseTest.java
@@ -143,25 +143,25 @@ public abstract class AbstractIgnoreTypesInventoryManagerBaseTest extends Arquil
protected void waitForInventory(int depth) throws Exception {
long start = System.currentTimeMillis();
- int inventoryDepth = getInventoryDepth(platform);
+ int inventoryDepth = getInventoryDepth(pluginContainer.getInventoryManager().getPlatform(), "");
while (inventoryDepth < depth) {
if (System.currentTimeMillis() - start > 60000L) {
assert false : "Failed to get proper depth, depth is currently at=" + inventoryDepth;
}
Thread.sleep(1000);
- inventoryDepth = getInventoryDepth(platform);
+ inventoryDepth = getInventoryDepth(platform, "");
}
return;
}
- protected int getInventoryDepth(Resource root) {
- System.out.println("Inventory depth chart: " + root);
+ protected int getInventoryDepth(Resource root, String indent) {
+ System.out.println("Inventory depth chart: " + indent + root);
if (root == null) {
return 0;
}
int maxDepth = 0;
for (Resource c : root.getChildResources()) {
- int childDepth = getInventoryDepth(c);
+ int childDepth = getInventoryDepth(c, " " + indent);
if (maxDepth < childDepth) {
maxDepth = childDepth;
}
commit 15675d86648dbaba58096e58736e5f7917f92882
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Jan 29 14:17:37 2014 -0500
oops, I had narrowed the test suite, re-enable all the test classes
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml
index 28d33ff..7827000 100644
--- a/modules/plugins/jboss-as-7/pom.xml
+++ b/modules/plugins/jboss-as-7/pom.xml
@@ -627,7 +627,7 @@
<skipITs>false</skipITs>
<includes>
<!-- only include integration tests; normal unit tests are handled above by surefire plugin -->
- <include>org/rhq/modules/plugins/jbossas7/itest/**/DeploymentTest.java</include>
+ <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/standalone/DeploymentTest.java</include>-->
commit 11125dd1eb846cb9350bcf9b49c3176869e4e304
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Jan 29 14:08:21 2014 -0500
AS7 i-test work, try to get these mf's working... I'm sure this won't solve
everything but hopefully gets us closer - I want to see what jenkins does now...
- allow superclass mock decls to get defined each time discovery resets
the mocks. (get rid of fake tests annotated with @ServerServicesSetup)
- generate consistent resource ids in the arquillian fake inventory to
avoid mismatch betweeen the PC and the fake server inv.
- do a better job of mvn clean for the as7 itest env
- report 0 byte content uploads to sys out
- remove some (seemingly?) unnecessary class-level annotations
- remove some (seemingly?) unnecessary test sleeps
- beef up the deployment upload method
diff --git a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
index 0c66be8..a553a5d 100644
--- a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
+++ b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
@@ -154,7 +154,7 @@ public class FakeServerInventory {
private Resource platform;
private Map<String, Resource> resourceStore = new HashMap<String, Resource>();
- private int counter;
+ //private int counter;
private AtomicInteger metricScheduleCounter = new AtomicInteger(1); // used when creating measurement schedules
private boolean failing;
private boolean failUpgrade;
@@ -576,10 +576,11 @@ public class FakeServerInventory {
}
if (persisted == null) {
persisted = new Resource();
- if (agentSideResource.getId() != 0 && counter < agentSideResource.getId()) {
- counter = agentSideResource.getId() - 1;
+ if (agentSideResource.getId() != 0) {
+ persisted.setId(agentSideResource.getId());
+ } else {
+ persisted.setId(agentSideResource.getUuid().hashCode());
}
- persisted.setId(++counter);
persisted.setUuid(agentSideResource.getUuid());
persisted.setAgent(agentSideResource.getAgent());
persisted.setCurrentAvailability(agentSideResource.getCurrentAvailability());
diff --git a/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java b/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
index 74773c2..c7a2333 100644
--- a/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
+++ b/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
@@ -153,6 +153,17 @@ public abstract class AbstractAgentPluginTest extends Arquillian {
}
/**
+ * Superclass can override this to add additional mocked services to those already
+ * defined in this abstract base class. The base class will call for injection each
+ * time the mocks are reset.
+ *
+ * @param serverServices
+ */
+ protected void injectMocks(MockingServerServices serverServices) {
+ return;
+ }
+
+ /**
* Set up our fake server discovery ServerService, which will auto-import all Resources in reports it receives.
*
* @throws Exception if an error occurs
@@ -174,6 +185,8 @@ public abstract class AbstractAgentPluginTest extends Arquillian {
serverInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
Mockito.when(serverServices.getDiscoveryServerService().getResourceSyncInfo(Mockito.any(int.class))).then(
serverInventory.getResourceSyncInfo());
+
+ injectMocks(this.serverServices);
} catch (Exception e) {
e.printStackTrace();
}
diff --git a/modules/plugins/jboss-as-7/pom.xml b/modules/plugins/jboss-as-7/pom.xml
index bfeb587..28d33ff 100644
--- a/modules/plugins/jboss-as-7/pom.xml
+++ b/modules/plugins/jboss-as-7/pom.xml
@@ -448,17 +448,35 @@
</configuration>
</execution>
<execution>
- <id>delete</id>
+ <id>delete-post</id>
<phase>post-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
+ <echo>*** Deleting AS7 ${jboss7.home}...</echo>
<delete dir="${jboss7.home}" />
+ <echo>*** Deleting data ./data...</echo>
+ <delete dir="./data" />
</target>
</configuration>
</execution>
+ <execution>
+ <id>delete-clean</id>
+ <phase>clean</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <echo>*** Deleting AS7 ${jboss7.home}...</echo>
+ <delete dir="${jboss7.home}" />
+ <echo>*** Deleting data ./data...</echo>
+ <delete dir="./data" />
+ </target>
+ </configuration>
+ </execution>
</executions>
</plugin>
@@ -609,7 +627,7 @@
<skipITs>false</skipITs>
<includes>
<!-- 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/**/DeploymentTest.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/standalone/DeploymentTest.java</include>-->
diff --git a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
index 2451743..000d08c 100644
--- a/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
+++ b/modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseComponent.java
@@ -457,15 +457,28 @@ public class BaseComponent<T extends ResourceComponent<?>> implements AS7Compone
report.setErrorMessage("An error occured while the agent was preparing for content download");
return report;
}
+
+ long size = 0L;
try {
- contentServices.downloadPackageBitsForChildResource(cctx, resourceTypeName, details.getKey(), out);
+ size = contentServices.downloadPackageBitsForChildResource(cctx, resourceTypeName, details.getKey(),
+ out);
} catch (Exception e) {
uploadConnection.cancelUpload();
report.setStatus(CreateResourceStatus.FAILURE);
- report.setErrorMessage("An error occured while the agent was downloading the content");
+ report.setErrorMessage("An error occured while the agent was uploading the content for ["
+ + details.getKey() + "]");
return report;
}
+ if (0L == size) {
+ uploadConnection.cancelUpload();
+ report.setStatus(CreateResourceStatus.FAILURE);
+ report.setErrorMessage("An error occured (0 bytes) while the agent was uploading the content for ["
+ + details.getKey() + "]");
+ return report;
+
+ }
+
JsonNode uploadResult = uploadConnection.finishUpload();
if (verbose) {
getLog().info(uploadResult);
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java
index 05237ef..3747821 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentRuntimeResourcesTest.java
@@ -19,17 +19,14 @@
package org.rhq.modules.plugins.jbossas7.itest.standalone;
-import static java.lang.System.currentTimeMillis;
-import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.rhq.modules.plugins.jbossas7.itest.standalone.DeploymentTest.copyStreamAndReturnCount;
import static org.rhq.modules.plugins.jbossas7.itest.standalone.DeploymentTest.getMeasurementScheduleRequests;
import static org.rhq.modules.plugins.jbossas7.itest.standalone.DeploymentTest.getMissingMeasurements;
import static org.rhq.modules.plugins.jbossas7.itest.standalone.DeploymentTest.getTestDeploymentPackageDetails;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashSet;
@@ -40,6 +37,7 @@ import org.apache.commons.logging.LogFactory;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import org.testng.Assert;
import org.testng.annotations.Test;
import org.rhq.core.clientapi.agent.PluginContainerException;
@@ -59,15 +57,15 @@ import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.modules.plugins.jbossas7.itest.AbstractJBossAS7PluginTest;
import org.rhq.test.arquillian.DiscoveredResources;
+import org.rhq.test.arquillian.MockingServerServices;
import org.rhq.test.arquillian.RunDiscovery;
-import org.rhq.test.arquillian.ServerServicesSetup;
/**
* This test ensures that "* Runtime" (JPA, Messaging, EJB3) child resources of a deployment get discovered.
*
* @author Thomas Segismont
*/
-@Test(groups = { "integration", "pc", "standalone" }, singleThreaded = true)
+@Test
public class DeploymentRuntimeResourcesTest extends AbstractJBossAS7PluginTest {
private static final Log LOG = LogFactory.getLog(DeploymentRuntimeResourcesTest.class);
@@ -100,39 +98,59 @@ public class DeploymentRuntimeResourcesTest extends AbstractJBossAS7PluginTest {
}
}
- @DiscoveredResources(plugin = PLUGIN_NAME, resourceType = "JBossAS7 Standalone Server")
- private Set<Resource> standaloneResources;
-
- @DiscoveredResources(plugin = PLUGIN_NAME, resourceType = "Deployment")
- private Set<Resource> deploymentResources;
+ protected void injectMocks(MockingServerServices serverServices) {
+ Mockito.when(
+ serverServices.getContentServerService().downloadPackageBitsGivenResource(Mockito.anyInt(),
+ Mockito.any(PackageDetailsKey.class), Mockito.any(OutputStream.class))).then(new Answer<Long>() {
+ @Override
+ public Long answer(InvocationOnMock invocation) throws Throwable {
+ OutputStream out = (OutputStream) invocation.getArguments()[invocation.getArguments().length - 1];
+ return copyStreamAndReturnCount(out);
+ }
+ });
- @ServerServicesSetup
- @Test(enabled = false)
- public void setupContentServices() {
Mockito.when(
serverServices.getContentServerService().downloadPackageBitsForChildResource(Mockito.anyInt(),
Mockito.anyString(), Mockito.any(PackageDetailsKey.class), Mockito.any(OutputStream.class))).then(
new Answer<Long>() {
@Override
public Long answer(InvocationOnMock invocation) throws Throwable {
- InputStream str = getClass().getClassLoader().getResourceAsStream(
- TestDeployments.JAVAEE6_TEST_APP.getResourcePath());
OutputStream out = (OutputStream) invocation.getArguments()[invocation.getArguments().length - 1];
- return copyStreamAndReturnCount(str, out);
+ return copyStreamAndReturnCount(out);
}
});
+ }
- Mockito.when(
- serverServices.getContentServerService().downloadPackageBitsGivenResource(Mockito.anyInt(),
- Mockito.any(PackageDetailsKey.class), Mockito.any(OutputStream.class))).then(new Answer<Long>() {
- @Override
- public Long answer(InvocationOnMock invocation) throws Throwable {
- InputStream str = getClass().getClassLoader().getResourceAsStream(
- TestDeployments.JAVAEE6_TEST_APP.getResourcePath());
- OutputStream out = (OutputStream) invocation.getArguments()[invocation.getArguments().length - 1];
- return copyStreamAndReturnCount(str, out);
+ @DiscoveredResources(plugin = PLUGIN_NAME, resourceType = "JBossAS7 Standalone Server")
+ private Set<Resource> standaloneResources;
+
+ @DiscoveredResources(plugin = PLUGIN_NAME, resourceType = "Deployment")
+ private Set<Resource> deploymentResources;
+
+ private long copyStreamAndReturnCount(OutputStream out) throws IOException {
+ if (null == out) {
+ System.out.println("**** Unexepected null output stream in mock code!!");
+ return 0L;
+ }
+
+ String path = TestDeployments.JAVAEE6_TEST_APP.getResourcePath();
+ InputStream in = getClass().getClassLoader().getResourceAsStream(path);
+
+ long cnt = 0;
+
+ try {
+ int data;
+ while ((data = in.read()) != -1) {
+ if (out != null) {
+ out.write(data);
+ }
+ cnt++;
}
- });
+ } finally {
+ in.close();
+ out.flush();
+ }
+ return cnt;
}
@Test(priority = 10)
@@ -174,7 +192,7 @@ public class DeploymentRuntimeResourcesTest extends AbstractJBossAS7PluginTest {
}
private void ensureAllRuntimeServicesAreFound() throws InterruptedException {
- long start = currentTimeMillis();
+ long start = System.currentTimeMillis();
boolean foundAllRuntimeServices = false;
do {
boolean runtimeServiceMissing = false;
@@ -187,10 +205,11 @@ public class DeploymentRuntimeResourcesTest extends AbstractJBossAS7PluginTest {
}
}
foundAllRuntimeServices = !runtimeServiceMissing;
- Thread.sleep(SECONDS.toMillis(5));
- } while (!foundAllRuntimeServices && (currentTimeMillis() - start) < MINUTES.toMillis(10));
- assertTrue(foundAllRuntimeServices, "Could not find all runtime services");
- Thread.sleep(MINUTES.toMillis(5));
+ //Thread.sleep(SECONDS.toMillis(5));
+ } while (!foundAllRuntimeServices
+ && (System.currentTimeMillis() - start) < java.util.concurrent.TimeUnit.MINUTES.toMillis(10));
+ Assert.assertTrue(foundAllRuntimeServices, "Could not find all runtime services");
+ //Thread.sleep(MINUTES.toMillis(5));
}
private boolean canGetMeasurementFacet(Set<Resource> resources) {
@@ -247,6 +266,7 @@ public class DeploymentRuntimeResourcesTest extends AbstractJBossAS7PluginTest {
}
@Test(priority = 99)
+ @RunDiscovery
public void testUndeploy() throws Exception {
Resource deploymentResource = getDeploymentResource();
DeleteResourceRequest request = new DeleteResourceRequest(0, deploymentResource.getId());
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java
index 24add24..fbdc02b 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/DeploymentTest.java
@@ -67,12 +67,12 @@ import org.rhq.core.util.MessageDigestGenerator;
import org.rhq.modules.plugins.jbossas7.StandaloneASComponent;
import org.rhq.modules.plugins.jbossas7.itest.AbstractJBossAS7PluginTest;
import org.rhq.test.arquillian.DiscoveredResources;
+import org.rhq.test.arquillian.MockingServerServices;
import org.rhq.test.arquillian.ResourceComponentInstances;
import org.rhq.test.arquillian.RunDiscovery;
-import org.rhq.test.arquillian.ServerServicesSetup;
/**
- *
+ *
*
* @author Lukas Krejci
*/
@@ -95,20 +95,16 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest {
private static TestDeployments DEPLOYMENT_TO_SERVE = TestDeployments.DEPLOYMENT_1;
- //this is no test method
- @ServerServicesSetup
- @Test(enabled = false)
- public void setupContentServices() {
+ @Override
+ protected void injectMocks(MockingServerServices serverServices) {
Mockito.when(
serverServices.getContentServerService().downloadPackageBitsForChildResource(Mockito.anyInt(),
Mockito.anyString(), Mockito.any(PackageDetailsKey.class), Mockito.any(OutputStream.class))).then(
new Answer<Long>() {
@Override
public Long answer(InvocationOnMock invocation) throws Throwable {
- InputStream str = getClass().getClassLoader().getResourceAsStream(
- DEPLOYMENT_TO_SERVE.getResourcePath());
OutputStream out = (OutputStream) invocation.getArguments()[invocation.getArguments().length - 1];
- return copyStreamAndReturnCount(str, out);
+ return copyStreamAndReturnCount(out);
}
});
@@ -117,10 +113,8 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest {
Mockito.any(PackageDetailsKey.class), Mockito.any(OutputStream.class))).then(new Answer<Long>() {
@Override
public Long answer(InvocationOnMock invocation) throws Throwable {
- InputStream str = getClass().getClassLoader()
- .getResourceAsStream(DEPLOYMENT_TO_SERVE.getResourcePath());
OutputStream out = (OutputStream) invocation.getArguments()[invocation.getArguments().length - 1];
- return copyStreamAndReturnCount(str, out);
+ return copyStreamAndReturnCount(out);
}
});
}
@@ -243,6 +237,7 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest {
}
@Test(priority = 16)
+ @RunDiscovery
public void testUndeploy() throws Exception {
Resource deployment = deploymentResources.iterator().next();
DeleteResourceRequest request = new DeleteResourceRequest(0, deployment.getId());
@@ -300,14 +295,28 @@ public class DeploymentTest extends AbstractJBossAS7PluginTest {
}
}
- static long copyStreamAndReturnCount(InputStream in, OutputStream out) throws IOException {
- int data;
+ private long copyStreamAndReturnCount(OutputStream out) throws IOException {
+ if (null == out) {
+ System.out.println("**** Unexepected null output stream in mock code!!");
+ return 0L;
+ }
+
+ String path = DEPLOYMENT_TO_SERVE.getResourcePath();
+ InputStream in = getClass().getClassLoader().getResourceAsStream(path);
+
long cnt = 0;
- while ((data = in.read()) != -1) {
- if (out != null) {
- out.write(data);
+
+ try {
+ int data;
+ while ((data = in.read()) != -1) {
+ if (out != null) {
+ out.write(data);
+ }
+ cnt++;
}
- cnt++;
+ } finally {
+ in.close();
+ out.flush();
}
return cnt;
}
commit c86911c9850e81f498099395e509cc41f4a67dde
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Jan 29 13:08:00 2014 -0500
move trove4j dep version to root pom
diff --git a/modules/core/plugin-container/pom.xml b/modules/core/plugin-container/pom.xml
index 5fad36b..c9d5d17 100644
--- a/modules/core/plugin-container/pom.xml
+++ b/modules/core/plugin-container/pom.xml
@@ -92,7 +92,6 @@
<dependency>
<groupId>net.sf.trove4j</groupId>
<artifactId>trove4j</artifactId>
- <version>3.0.3</version>
</dependency>
</dependencies>
diff --git a/pom.xml b/pom.xml
index dd797a1..fec00c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1036,6 +1036,12 @@
<artifactId>snakeyaml</artifactId>
<version>${cassandra.snakeyaml.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>net.sf.trove4j</groupId>
+ <artifactId>trove4j</artifactId>
+ <version>3.0.3</version>
+ </dependency>
</dependencies>
</dependencyManagement>
commit 8fc26d558b65efe70d989c6bcb6223c46fb1a633
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Wed Jan 29 17:09:42 2014 +0100
Avoid unused variable creation
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index 4d4beab..a405b6c 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -2741,8 +2741,7 @@ public class AgentMain {
// The JBoss remoting HTTP transport can wait indefinitely for a response
// This ensures the client does not wait forever
- long clientSenderCommandTimeout = m_configuration.getClientSenderCommandTimeout();
- long timeout = clientSenderCommandTimeout;
+ long timeout = m_configuration.getClientSenderCommandTimeout();
if (timeout > 0) {
config.put("timeout", Long.toString(timeout));
}
commit 9302f90bc0d81905bf62649666b7df0913acdac7
Author: Elias Ross <genman(a)noderunner.net>
Date: Wed Jan 29 17:02:42 2014 +0100
Bug 1053922 - Agent does not set HTTP connect or read timeout in JBoss remoting
diff --git a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
index b6cd741..4d4beab 100644
--- a/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
+++ b/modules/enterprise/agent/src/main/java/org/rhq/enterprise/agent/AgentMain.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2013 Red Hat, Inc.
+ * Copyright (C) 2005-2014 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -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.enterprise.agent;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -2738,6 +2739,14 @@ public class AgentMain {
config.put(HTTPSClientInvoker.IGNORE_HTTPS_HOST, "true");
}
+ // The JBoss remoting HTTP transport can wait indefinitely for a response
+ // This ensures the client does not wait forever
+ long clientSenderCommandTimeout = m_configuration.getClientSenderCommandTimeout();
+ long timeout = clientSenderCommandTimeout;
+ if (timeout > 0) {
+ config.put("timeout", Long.toString(timeout));
+ }
+
RemoteCommunicator remote_comm = new JBossRemotingRemoteCommunicator(uri, config);
if (withFailover) {
remote_comm.setFailureCallback(new FailoverFailureCallback(this));
commit d2aac70ae17ea051080a16a92a1ac666d909e520
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Tue Jan 28 16:03:50 2014 +0100
[BZ 1016833] - Alert notification sender, resource operation, relative resource type filter drop-down has not logical or usable ordering - Using the LinkedHashMap that preserves the ordering instead of java.util.HashMap. Also adding the plugin name to the drop-down list.
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
index 2685411..686b9bb 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
@@ -1208,7 +1208,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip =
view_alert_definition_notification_operation_editor_relative_descendant = Then Filter By
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Cannot get type descendants
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection.
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection. Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = Pick
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = Please pick a resource
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Please pick a resource that has one or more operations
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
index 1dd46b1..58da08b 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
@@ -1226,7 +1226,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip =
view_alert_definition_notification_operation_editor_relative_descendant = Filtrovat čím
##view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Nelze získat typ potomků
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = Typ zdroje v němž hledat pomocí vyhledávacího formuláře
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = Typ zdroje v němž hledat pomocí vyhledávacího formuláře. Prvky tohoto comboboxu jsou ve tvaru _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = Vybrat
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = Prosím vyberte zdroj
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Prosím vyberte zdroj, který má jednu nebo více operací
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
index 36fcdcc..ea3bb5c 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
@@ -1334,7 +1334,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip=W
view_alert_definition_notification_operation_editor_relative_descendant=dann filtern nach
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip=Ein spezifischer Name zur eindeutigen Identifizierung einer Ressource, wenn mehr als eine Ressource des gewählten Typs vorhanden sein kann. Dies ist optional wenn stets nur eine Ressource des Ressourcentyps in der gewählten Typhierarchie existiert.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed=Erhalt von Typ Abkömmlingen nicht möglich
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip=Der Ressourcentyp, nach dem unter dem in der Start Search From Auswahl (Suche starten von) definierten Root Typ gesucht werden soll.
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip=Der Ressourcentyp, nach dem unter dem in der Start Search From Auswahl (Suche starten von) definierten Root Typ gesucht werden soll. Members of this combobox are in form _plugin_ -> _type_.
# #view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
# #view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Cannot get type descendants
# #view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection.
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
index 4421ea7..646e4e9 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
@@ -1349,7 +1349,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip=
view_alert_definition_notification_operation_editor_relative_descendant=次によるフィルター\:
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip=選択したタイプのリソースが複数存在するときに、リソースを一意に識別する名前。選択したタイプ階層に、選択したタイプのリソースが 1 つのみ存在する場合は任意の設定です。
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed=タイプの子孫を取得できません
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip=「検索を開始」で定義される、ルートタイプの下で検索されるリソースタイプ。
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip=「検索を開始」で定義される、ルートタイプの下で検索されるリソースタイプ。Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button=選択
view_alert_definition_notification_operation_editor_specific_pick_error_invalid=リソースを選択してください
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation=1 つ以上の操作を持つリソースを選択してください
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
index 1405896..ea2dbe1 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
@@ -1092,7 +1092,7 @@ view_alert_definition_notification_operation_editor_mode_title = 리소스 선
view_alert_definition_notification_operation_editor_relative_ancestor = 검색 시작
view_alert_definition_notification_operation_editor_relative_descendant = 다음의 필터
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = 유형의 자손을 얻을 수 없습니다
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = 검색시작 유형에 정의된 경로 유형에서 찾기 리소스 유형
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = 검색시작 유형에 정의된 경로 유형에서 찾기 리소스 유형 Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = 선택
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = 리소스를 선택하십시오
view_alert_definition_notification_operation_editor_specific_pick_text = 리소스를 선택...
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
index 3fad466..d710475 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
@@ -1210,7 +1210,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip =
view_alert_definition_notification_operation_editor_relative_descendant = Ent\u00E3o procure por
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = Um nome especifico para identificar unicamente um recurso quando existir mais de um do mesmo tipo. Isso \u00E9 opcional, se definido, sempre ser\u00E1 um recurso do tipo slecionda na hierarquia.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = N\u00E3o \u00E9 poss\u00EDvel obter os tipos de descendentes
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = Tipo do recurso a ser procurado a baixo do tipo raiz definido na sele\u00E7\u00E3o 'Inicia a Pesquesa a partir de'.
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = Tipo do recurso a ser procurado a baixo do tipo raiz definido na sele\u00E7\u00E3o 'Inicia a Pesquesa a partir de'. Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = Selecionar
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = Favor selecionar um recurso
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Selecione um recurso que possua um ou mais opera\u00E7\u00F5es
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
index f8a3a3b..97814e5 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
@@ -1126,7 +1126,7 @@
#view_alert_definition_notification_operation_editor_relative_descendant = Then Filter By
#view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
#view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Cannot get type descendants
-#view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection.
+#view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection. Members of this combobox are in form _plugin_ -> _type_.
#view_alert_definition_notification_operation_editor_specific_pick_button = Pick
#view_alert_definition_notification_operation_editor_specific_pick_error_invalid = Please pick a resource
#view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Please pick a resource that has one or more operations
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
index 0b766eb..27ef9b7 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
@@ -1199,7 +1199,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip =
view_alert_definition_notification_operation_editor_relative_descendant = Then Filter By
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Cannot get type descendants
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection.
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection. Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = Pick
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = \u9009\u62e9\u4e00\u4e2a\u8d44\u6e90
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Please pick a resource that has one or more operations
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
index e9d686a..669790e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -516,12 +517,12 @@ public class ResourceTypeManagerBean implements ResourceTypeManagerLocal, Resour
return results;
}
- public HashMap<Integer, String> getResourceTypeDescendantsWithOperations(Subject subject, int resourceTypeId) {
+ public LinkedHashMap<Integer, String> getResourceTypeDescendantsWithOperations(Subject subject, int resourceTypeId) {
List<ResourceType> types = getAllResourceTypeDescendants(subject, resourceTypeId);
excludeThoseWithoutOperations(types);
- HashMap<Integer, String> results = new HashMap<Integer, String>(types.size());
+ LinkedHashMap<Integer, String> results = new LinkedHashMap<Integer, String>(types.size());
for (ResourceType type : types) {
- results.put(type.getId(), type.getName());
+ results.put(type.getId(), type.getPlugin() + " -> " + type.getName());
}
return results;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java
index f86e6d4..a732171 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java
@@ -168,5 +168,12 @@ public interface ResourceTypeManagerLocal {
List<ResourceType> getAllResourceTypeAncestors(Subject subject, int resourceTypeId);
+ /**
+ *
+ * @param subject subject of the caller
+ * @param resourceTypeId resource type to begin with
+ * @return list of all {@link org.rhq.core.domain.resource.ResourceType}s of all descendants
+ * @deprecated This method is not currently being used at all
+ */
List<ResourceType> getAllResourceTypeDescendants(Subject subject, int resourceTypeId);
}
\ No newline at end of file
commit e64d872abbdb9219b2d4784d63dce75d1c795886
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Jan 27 17:44:19 2014 -0500
More as7 i-test work. Avoid ConcurrentModException in mock code.
diff --git a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
index 0b4e954..0c66be8 100644
--- a/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
+++ b/modules/core/arquillian-integration/container/src/main/java/org/rhq/test/arquillian/FakeServerInventory.java
@@ -553,11 +553,13 @@ public class FakeServerInventory {
public void removeResource(Resource r) {
resourceStore.remove(r.getUuid());
+ HashSet<Resource> safeChildren = new HashSet<Resource>(r.getChildResources());
Resource parent = r.getParentResource();
if (parent != null) {
- parent.getChildResources().remove(r);
+ parent.removeChildResource(r);
+ r.setParentResourceWithoutAncestry(null);
}
- for (Resource child : r.getChildResources()) {
+ for (Resource child : safeChildren) {
removeResource(child);
}
}
diff --git a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
index f26abd0..f5ebb5d 100644
--- a/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
+++ b/modules/core/plugin-container/src/test/java/org/rhq/core/pc/upgrade/FakeServerInventory.java
@@ -346,17 +346,6 @@ public class FakeServerInventory {
return result;
}
- public void removeResource(Resource r) {
- resourceStore.remove(r.getUuid());
- Resource parent = r.getParentResource();
- if (parent != null) {
- parent.getChildResources().remove(r);
- }
- for (Resource child : r.getChildResources()) {
- removeResource(child);
- }
- }
-
private Resource fakePersist(Resource agentSideResource, InventoryStatusJudge statusJudge,
Set<String> inProgressUUIds) {
Resource persisted = resourceStore.get(agentSideResource.getUuid());
commit f7f0011072dd56f1a081aa24351966656ff94f83
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Mon Jan 27 22:12:25 2014 +0100
[BZ 1058474] log meaningful messages on failure to find/link Augeas lib
Catch NoClassDefFoundError and UnsatisfiedLinkError and report them
appropriately when checking for presence of Augeas in Apache plugin.
Also emit slightly more direct message if we do not support Augeas for
given version of Apache.
diff --git a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
index de81e3e..6c43552 100644
--- a/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
+++ b/modules/plugins/apache/src/main/java/org/rhq/plugins/apache/ApacheServerComponent.java
@@ -113,7 +113,9 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
public static final String CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE =
"Configuration and child resource creation/deletion support for Apache is optional. "
+ "If you switched it on by enabling Augeas support in the connection settings of the Apache server resource and still get this message, "
- + "it means that either your Apache version is not supported (only Apache 2.x is supported) or Augeas is not available on your platform.";
+ + "it means that either your Apache version is not supported (only Apache 2.x is supported) or Augeas is not available on your platform."
+ + " Please refer to your agent's log for the precise exception that is causing this behavior. It will logged at error level only once "
+ + "per plugin container lifetime";
public static final String PLUGIN_CONFIG_PROP_SERVER_ROOT = "serverRoot";
public static final String PLUGIN_CONFIG_PROP_EXECUTABLE_PATH = "executablePath";
@@ -170,6 +172,7 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
private URL url;
private ApacheBinaryInfo binaryInfo;
private long availPingTime = -1;
+ private boolean augeasErrorLogged;
private Map<String, String> moduleNames;
@@ -1067,7 +1070,13 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
try {
ag = new Augeas();
} catch (Exception e) {
- LOG.error("Augeas is enabled in configuration but was not found on the system.", e);
+ logAugeasError(e);
+ throw new RuntimeException(CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ } catch (NoClassDefFoundError e) {
+ logAugeasError(e);
+ throw new RuntimeException(CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ } catch (UnsatisfiedLinkError e) {
+ logAugeasError(e);
throw new RuntimeException(CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
} finally {
if (ag != null) {
@@ -1081,7 +1090,11 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
String version = getVersion();
if (!version.startsWith("2.")) {
- LOG.error(CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
+ if (!augeasErrorLogged) {
+ augeasErrorLogged = true;
+ LOG.error("Augeas is only supported with Apache version 2.x but version '" + version +
+ "' was detected.");
+ }
throw new RuntimeException(CONFIGURATION_NOT_SUPPORTED_ERROR_MESSAGE);
}
return true;
@@ -1090,6 +1103,13 @@ public class ApacheServerComponent implements AugeasRHQComponent, ResourceCompon
}
}
+ private void logAugeasError(Throwable cause) {
+ if (!augeasErrorLogged) {
+ LOG.error("Augeas is enabled in configuration but was not found on the system.", cause);
+ augeasErrorLogged = true;
+ }
+ }
+
private String getVersion() {
String ret = resourceContext.getVersion();
if (ret == null) {
commit 15f495ed628635e259c6f17871ca17d973df1f35
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Jan 27 13:21:22 2014 -0500
Fix AS7 i-test failures
- add required mock expectation
- make sure tests wait for discovery to complete
- make public non-test methods protected so they are not interpreted as
tests. (maybe unnecessary but harmless)
Also note - current prop settings in pom are not working, I needed to override (used EAP 6.1.0):
<as7.version>
<as7.url>
I think the version of AS referenced in the pom is too old to properly respond to product type inquiries:
<as7.url>https://hudson.jboss.org/hudson/view/JBoss%20AS/job/JBoss-AS-7.0.x/lastSu...</as7.url>
(Note that our Jenkins jobs already override the pom settings)
diff --git a/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java b/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
index aef1fa8..74773c2 100644
--- a/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
+++ b/modules/core/plugin-test-util/src/main/java/org/rhq/core/plugin/testutil/AbstractAgentPluginTest.java
@@ -117,7 +117,7 @@ public abstract class AbstractAgentPluginTest extends Arquillian {
private FakeServerInventory.CompleteDiscoveryChecker discoveryCompleteChecker;
@Deployment(name = "platform", order = 1)
- public static RhqAgentPluginArchive getPlatformPlugin() throws Exception {
+ protected static RhqAgentPluginArchive getPlatformPlugin() throws Exception {
MavenResolverSystem mavenDependencyResolver = Maven.resolver();
String platformPluginArtifact = "org.rhq:rhq-platform-plugin:jar:" + getRhqVersion();
return mavenDependencyResolver.offline().loadPomFromFile("pom.xml").resolve(platformPluginArtifact)
@@ -125,7 +125,7 @@ public abstract class AbstractAgentPluginTest extends Arquillian {
}
@Deployment(name = "pluginUnderTest", order = 2)
- public static RhqAgentPluginArchive getPluginUnderTest() throws Exception {
+ protected static RhqAgentPluginArchive getPluginUnderTest() throws Exception {
// This is the jar that was just built during the Maven package phase, just prior to this test getting run
// during the Maven integration-test phase. This is exactly what we want, because it's the real Maven-produced
// jar, freshly assembled from the classes being tested.
@@ -158,7 +158,7 @@ public abstract class AbstractAgentPluginTest extends Arquillian {
* @throws Exception if an error occurs
*/
@BeforeDiscovery
- public void resetServerServices() throws Exception {
+ protected void resetServerServices() throws Exception {
System.out.println("\n=== Resetting fake Server prior to running discovery scan...");
this.serverInventory = new FakeServerInventory();
@@ -172,6 +172,8 @@ public abstract class AbstractAgentPluginTest extends Arquillian {
this.serverServices.getDiscoveryServerService()
.mergeInventoryReport(Mockito.any(InventoryReport.class))).then(
serverInventory.mergeInventoryReport(InventoryStatus.COMMITTED));
+ Mockito.when(serverServices.getDiscoveryServerService().getResourceSyncInfo(Mockito.any(int.class))).then(
+ serverInventory.getResourceSyncInfo());
} catch (Exception e) {
e.printStackTrace();
}
@@ -180,7 +182,7 @@ public abstract class AbstractAgentPluginTest extends Arquillian {
protected abstract int getTypeHierarchyDepth();
@AfterDiscovery
- public void waitForAsyncDiscoveries() throws Exception {
+ protected void waitForAsyncDiscoveries() throws Exception {
try {
discoveryCompleteChecker.waitForDiscoveryComplete(12000);
System.out.println("\n====== Discovery completed.");
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
index 32e83f2..780d398 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractJBossAS7PluginTest.java
@@ -55,21 +55,23 @@ public abstract class AbstractJBossAS7PluginTest extends AbstractAgentPluginTest
private static int OVERRIDE_TYPE_HIERARCHY_DEPTH = -1;
- public static int getMaxDiscoveryDepthOverride() {
+ protected static int getMaxDiscoveryDepthOverride() {
return OVERRIDE_TYPE_HIERARCHY_DEPTH;
}
- public static void setMaxDiscoveryDepthOverride(int overrideDepth) {
+ protected static void setMaxDiscoveryDepthOverride(int overrideDepth) {
OVERRIDE_TYPE_HIERARCHY_DEPTH = overrideDepth;
}
private static boolean createdManagementUsers;
/**
- * Make sure a management user is configured on both discovered AS7 test servers.
+ * Make sure a management user is configured on both discovered AS7 test servers.
*/
@AfterDiscovery
- public void installManagementUsers() throws PluginContainerException {
+ protected void installManagementUsers() throws PluginContainerException, Exception {
+ waitForAsyncDiscoveries();
+
System.out.println("\n=== Discovery scan completed.");
if (!createdManagementUsers) {
System.out.println("====== Installing management users...");
@@ -110,7 +112,7 @@ public abstract class AbstractJBossAS7PluginTest extends AbstractAgentPluginTest
Configuration pluginConfig = resourceFromServer.getPluginConfiguration();
pluginConfig.setSimpleValue("user", MANAGEMENT_USERNAME);
pluginConfig.setSimpleValue("password", MANAGEMENT_PASSWORD);
-
+
// Restart the ResourceComponent, so it will start using the new plugin config.
InventoryManager inventoryManager = this.pluginContainer.getInventoryManager();
try {
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java
index 6ff3d06..d0f023a 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/AbstractServerComponentTest.java
@@ -284,7 +284,7 @@ public abstract class AbstractServerComponentTest extends AbstractJBossAS7Plugin
protected abstract List<String> getExpectedStartScriptArgs();
- public void killServerProcesses() {
+ protected void killServerProcesses() {
List<ProcessInfo> processes = getServerProcesses();
System.out.println("\n=== Killing " + processes.size() + " " + getServerResourceType() + " processes...");
for (ProcessInfo process : processes) {
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java
index 7706e23..f16ab6d 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/domain/DomainServerComponentTest.java
@@ -97,7 +97,7 @@ public class DomainServerComponentTest extends AbstractServerComponentTest {
}
@AfterSuite
- public void killServerProcesses() {
+ protected void killServerProcesses() {
super.killServerProcesses();
}
diff --git a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java
index dd1b0ec..ed26c57 100644
--- a/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java
+++ b/modules/plugins/jboss-as-7/src/test/java/org/rhq/modules/plugins/jbossas7/itest/standalone/StandaloneServerComponentTest.java
@@ -172,7 +172,7 @@ public class StandaloneServerComponentTest extends AbstractServerComponentTest {
}
@AfterSuite
- public void killServerProcesses() {
+ protected void killServerProcesses() {
super.killServerProcesses();
}
10 years, 3 months
[rhq] Changes to 'mtho11/bz1014571-2'
by mike thompson
New branch 'mtho11/bz1014571-2' available with the following commits:
commit b8108d48dfea2006920449c969d19e3b8eb5589b
Author: Mike Thompson <mithomps(a)redhat.com>
Date: Fri Jan 31 14:41:05 2014 -0800
[BZ 1014571] UX issue: user can barely select time range on metric graph image. Make x-axis draggable as well.
10 years, 3 months
[rhq] Branch 'feature/embeddedagent' - modules/enterprise
by mazz
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java | 15 ++
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java | 3
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java | 41 ++++++
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/CustomConfigAttributeDefinition.java | 61 ++++++++++
modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties | 1
modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd | 11 +
modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java | 1
modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml | 5
8 files changed, 138 insertions(+)
New commits:
commit e4aedd0e706f38c069fad3570ead986576723d33
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Feb 3 17:19:54 2014 -0500
add ability to set generic config preferences
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
index 115f74b..154d5d8 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -43,6 +43,7 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
AgentSubsystemDefinition.SERVER_TRANSPORT_PARAMS_ATTRIBDEF.validateAndSet(operation, model);
AgentSubsystemDefinition.SERVER_ALIAS_ATTRIBDEF.validateAndSet(operation, model);
AgentSubsystemDefinition.SOCKET_BINDING_ATTRIBDEF.validateAndSet(operation, model);
+ AgentSubsystemDefinition.CUSTOM_CONFIG_ATTRIBDEF.validateAndSet(operation, model);
log.info("Populating the embedded agent subsystem model: " + operation + "=" + model);
}
@@ -85,6 +86,20 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_TRANSPORT_ATTRIBDEF);
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_TRANSPORT_PARAMS_ATTRIBDEF);
+ // allow the user to provide their own overrides
+ ModelNode customConfigNode = AgentSubsystemDefinition.CUSTOM_CONFIG_ATTRIBDEF.resolveModelAttribute(context,
+ model);
+ if (customConfigNode != null && customConfigNode.isDefined()) {
+ HashMap<String, String> customConfig = new HashMap<String, String>();
+ List<Property> prefList = customConfigNode.asPropertyList();
+ for (Property pref : prefList) {
+ String name = pref.getName();
+ String val = pref.getValue().asString();
+ customConfig.put(name, val);
+ }
+ overrides.putAll(customConfig);
+ }
+
// create our service
AgentService service = new AgentService();
service.setPlugins(pluginsWithEnableFlag);
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
index 78d274b..1224d84 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
@@ -30,6 +30,8 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
protected static final PluginsAttributeDefinition PLUGINS_ATTRIBDEF = new PluginsAttributeDefinition();
+ protected static final CustomConfigAttributeDefinition CUSTOM_CONFIG_ATTRIBDEF = new CustomConfigAttributeDefinition();
+
protected static final SimpleAttributeDefinition AGENT_NAME_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_AGENT_NAME, ModelType.STRING).setAllowExpression(true)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
@@ -97,6 +99,7 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
public void registerAttributes(ManagementResourceRegistration rr) {
rr.registerReadWriteAttribute(AGENT_ENABLED_ATTRIBDEF, null, AgentEnabledAttributeHandler.INSTANCE);
rr.registerReadWriteAttribute(PLUGINS_ATTRIBDEF, null, PluginsAttributeHandler.INSTANCE);
+ registerReloadRequiredWriteAttributeHandler(rr, CUSTOM_CONFIG_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, AGENT_NAME_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, DISABLE_NATIVE_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, SERVER_TRANSPORT_ATTRIBDEF);
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
index 637b7a8..4463ad9 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
@@ -17,6 +17,7 @@ import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.SubsystemRegistration;
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
+import org.jboss.as.controller.parsing.Attribute;
import org.jboss.as.controller.parsing.ExtensionParsingContext;
import org.jboss.as.controller.parsing.ParseUtils;
import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
@@ -51,6 +52,8 @@ public class AgentSubsystemExtension implements Extension {
protected static final String AGENT_ENABLED = "enabled";
protected static final boolean AGENT_ENABLED_DEFAULT = false;
protected static final boolean PLUGIN_ENABLED_DEFAULT = true;
+ protected static final String AGENT_CONFIG_ELEMENT = "extra-configuration";
+ protected static final String PREFERENCE_ELEMENT = "preference";
protected static final String SERVER_ENDPOINT_ELEMENT = "server-endpoint";
protected static final String SERVER_ENDPOINT_ADDRESS_XML = "address";
protected static final String SERVER_ENDPOINT_PORT_XML = "port";
@@ -131,6 +134,13 @@ public class AgentSubsystemExtension implements Extension {
readPlugin(reader, pluginsAttributeNode);
}
}
+ } else if (elementName.equals(AGENT_CONFIG_ELEMENT)) {
+ ModelNode configAttributeNode = opAdd.get(AGENT_CONFIG_ELEMENT);
+ while (reader.hasNext() && reader.nextTag() != END_ELEMENT) {
+ if (reader.isStartElement()) {
+ readPreference(reader, configAttributeNode);
+ }
+ }
} else if (elementName.equals(SERVER_ENDPOINT_ELEMENT)) {
String val = reader.getAttributeValue(null, SERVER_ENDPOINT_ADDRESS_XML);
if (val != null) {
@@ -206,6 +216,21 @@ public class AgentSubsystemExtension implements Extension {
pluginsAttributeNode.add(pluginName, pluginEnabled);
}
+ private void readPreference(XMLExtendedStreamReader reader, ModelNode configAttributeNode)
+ throws XMLStreamException {
+
+ if (!reader.getLocalName().equals(PREFERENCE_ELEMENT)) {
+ throw ParseUtils.unexpectedElement(reader);
+ }
+
+ ParseUtils.requireAttributes(reader, Attribute.NAME.getLocalName(), Attribute.VALUE.getLocalName());
+ String attr = reader.getAttributeValue(null, Attribute.NAME.getLocalName());
+ String val = reader.getAttributeValue(null, Attribute.VALUE.getLocalName());
+ ParseUtils.requireNoContent(reader);
+
+ configAttributeNode.add(attr, val);
+ }
+
@Override
public void writeContent(final XMLExtendedStreamWriter writer, final SubsystemMarshallingContext context)
throws XMLStreamException {
@@ -261,6 +286,22 @@ public class AgentSubsystemExtension implements Extension {
// </agent-endpoint>
writer.writeEndElement();
+ // <extra-configuration>
+ writer.writeStartElement(AGENT_CONFIG_ELEMENT);
+ ModelNode configNode = node.get(AGENT_CONFIG_ELEMENT);
+ if (configNode != null && configNode.isDefined()) {
+ for (Property property : configNode.asPropertyList()) {
+ // <preference>
+ writer.writeStartElement(PREFERENCE_ELEMENT);
+ writer.writeAttribute(Attribute.NAME.getLocalName(), property.getName());
+ writer.writeAttribute(Attribute.VALUE.getLocalName(), property.getValue().asString());
+ // </preference>
+ writer.writeEndElement();
+ }
+ }
+ // </extra-configuration>
+ writer.writeEndElement();
+
// <plugins>
writer.writeStartElement(PLUGINS_ELEMENT);
ModelNode plugins = node.get(PLUGINS_ELEMENT);
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/CustomConfigAttributeDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/CustomConfigAttributeDefinition.java
new file mode 100644
index 0000000..5129f3d
--- /dev/null
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/CustomConfigAttributeDefinition.java
@@ -0,0 +1,61 @@
+package org.rhq.embeddedagent.extension;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.jboss.as.controller.MapAttributeDefinition;
+import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
+import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
+import org.jboss.as.controller.operations.validation.ModelTypeValidator;
+import org.jboss.as.controller.parsing.Attribute;
+import org.jboss.as.controller.registry.AttributeAccess.Flag;
+import org.jboss.dmr.ModelNode;
+import org.jboss.dmr.ModelType;
+
+/**
+ * A generic catch-all to allow the agent to have any config preference set.
+ *
+ * @author John Mazzitelli
+ */
+public class CustomConfigAttributeDefinition extends MapAttributeDefinition {
+
+ public CustomConfigAttributeDefinition() {
+ super(AgentSubsystemExtension.AGENT_CONFIG_ELEMENT, AgentSubsystemExtension.AGENT_CONFIG_ELEMENT, true,
+ 0, Integer.MAX_VALUE, new ModelTypeValidator(ModelType.STRING), null, null, Flag.RESTART_RESOURCE_SERVICES);
+ }
+
+ @Override
+ protected void addValueTypeDescription(ModelNode node, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ protected void addAttributeValueTypeDescription(ModelNode node, ResourceDescriptionResolver resolver,
+ Locale locale, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ protected void addOperationParameterValueTypeDescription(ModelNode node, String operationName,
+ ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
+ node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
+ }
+
+ @Override
+ public void marshallAsElement(ModelNode resourceModel, XMLStreamWriter writer) throws XMLStreamException {
+ if (!isMarshallable(resourceModel))
+ return;
+
+ resourceModel = resourceModel.get(getName());
+ writer.writeStartElement(getName());
+ for (ModelNode property : resourceModel.asList()) {
+ writer.writeEmptyElement(getXmlName());
+ writer.writeAttribute(Attribute.NAME.getLocalName(), property.asProperty().getName());
+ writer.writeAttribute(Attribute.VALUE.getLocalName(), property.asProperty().getValue().asString());
+ }
+ writer.writeEndElement();
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
index 680f9f2..f4b08d1 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
@@ -6,6 +6,7 @@ embeddedagent.stop=Stops the RHQ Agent if it is running.
embeddedagent.status=Tells you if the RHQ Agent is currently started or stopped.
embeddedagent.enabled=When true, the RHQ Agent will be deployed and started. Otherwise, it will be disabled.
embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
+embeddedagent.extra-configuration=Additional preference values used to configure the agent
embeddedagent.socket-binding=Determines the binding address and port the agent listens to for incoming server messages.
embeddedagent.rhq.communications.connector.transport=The transport server must use to communicate with the agent.
embeddedagent.rhq.communications.connector.transport-params=The transport parameters the server must use to communicate with the agent.
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
index a116308..3439cf2 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
@@ -15,6 +15,7 @@
<xs:element name="rhq.agent.server.alias" type="xs:string"/>
<xs:element name="server-endpoint" type="serverEndpointType"/>
<xs:element name="agent-endpoint" type="agentEndpointType"/>
+ <xs:element name="extra-configuration" type="extraConfigurationType"/>
<xs:element name="plugins" type="pluginsType"/>
</xs:all>
</xs:complexType>
@@ -41,4 +42,14 @@
<xs:attribute name="name" use="required"/>
<xs:attribute name="enabled" type="xs:boolean" use="required" default="true"/>
</xs:complexType>
+
+ <xs:complexType name="extraConfigurationType">
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element name="preference" type="preferenceType"/>
+ </xs:choice>
+ </xs:complexType>
+ <xs:complexType name="preferenceType">
+ <xs:attribute name="name" use="required"/>
+ <xs:attribute name="value" use="required"/>
+ </xs:complexType>
</xs:schema>
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
index b6126a0..5c2f3d4 100644
--- a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -198,6 +198,7 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
List<Property> attributes = content.get("attributes").asPropertyList();
List<String> expectedAttributes = Arrays.asList( //
+ AgentSubsystemExtension.AGENT_CONFIG_ELEMENT, //
AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT_PARAMS, //
AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT, //
AgentSubsystemExtension.ATTRIB_SOCKET_BINDING, //
diff --git a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
index d4ea3c8..c847ee6 100644
--- a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
+++ b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
@@ -6,6 +6,11 @@
<server-endpoint port="7080" transport="test-transport" transport-params="test-transport-params" />
<agent-endpoint socket-binding="embeddedagent" transport="socket"/>
+ <extra-configuration>
+ <preference name="custom-prop" value="custom-prop-val"/>
+ <preference name="custom-prop2" value="custom-prop-val2"/>
+ </extra-configuration>
+
<plugins>
<plugin name="platform" enabled="true" />
<plugin name="blah" enabled="false" />
10 years, 3 months
[rhq] Branch 'release/jon3.2.x' - modules/enterprise
by Jay Shaughnessy
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties | 2 +-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties | 2 +-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties | 2 +-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties | 2 +-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties | 2 +-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties | 2 +-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties | 2 +-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties | 2 +-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java | 7 ++++---
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java | 7 +++++++
10 files changed, 19 insertions(+), 11 deletions(-)
New commits:
commit c2f37733be994a9237853a7f21733e2459a9f055
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 3 16:39:30 2014 -0500
[BZ 1016833] - Alert notification sender, resource operation, relative resource type filter drop-down has not logical or usable ordering - Using the LinkedHashMap that preserves the ordering instead of java.util.HashMap. Also adding the plugin name to the drop-down list.
Cherry pick of d2aac70ae17ea051080a16a92a1ac666d909e520
Signed-off-by: Jay Shaughnessy <jshaughn(a)redhat.com>
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
index c5becf5..e3c2c32 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages.properties
@@ -1124,7 +1124,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip =
view_alert_definition_notification_operation_editor_relative_descendant = Then Filter By
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Cannot get type descendants
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection.
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection. Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = Pick
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = Please pick a resource
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Please pick a resource that has one or more operations
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
index edf6af7..a4e0369 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_cs.properties
@@ -1143,7 +1143,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip =
view_alert_definition_notification_operation_editor_relative_descendant = Filtrovat čím
##view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Nelze získat typ potomků
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = Typ zdroje v němž hledat pomocí vyhledávacího formuláře
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = Typ zdroje v němž hledat pomocí vyhledávacího formuláře. Prvky tohoto comboboxu jsou ve tvaru _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = Vybrat
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = Prosím vyberte zdroj
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Prosím vyberte zdroj, který má jednu nebo více operací
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
index 36fcdcc..ea3bb5c 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_de.properties
@@ -1334,7 +1334,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip=W
view_alert_definition_notification_operation_editor_relative_descendant=dann filtern nach
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip=Ein spezifischer Name zur eindeutigen Identifizierung einer Ressource, wenn mehr als eine Ressource des gewählten Typs vorhanden sein kann. Dies ist optional wenn stets nur eine Ressource des Ressourcentyps in der gewählten Typhierarchie existiert.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed=Erhalt von Typ Abkömmlingen nicht möglich
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip=Der Ressourcentyp, nach dem unter dem in der Start Search From Auswahl (Suche starten von) definierten Root Typ gesucht werden soll.
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip=Der Ressourcentyp, nach dem unter dem in der Start Search From Auswahl (Suche starten von) definierten Root Typ gesucht werden soll. Members of this combobox are in form _plugin_ -> _type_.
# #view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
# #view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Cannot get type descendants
# #view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection.
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
index 4421ea7..646e4e9 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ja.properties
@@ -1349,7 +1349,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip=
view_alert_definition_notification_operation_editor_relative_descendant=次によるフィルター\:
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip=選択したタイプのリソースが複数存在するときに、リソースを一意に識別する名前。選択したタイプ階層に、選択したタイプのリソースが 1 つのみ存在する場合は任意の設定です。
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed=タイプの子孫を取得できません
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip=「検索を開始」で定義される、ルートタイプの下で検索されるリソースタイプ。
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip=「検索を開始」で定義される、ルートタイプの下で検索されるリソースタイプ。Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button=選択
view_alert_definition_notification_operation_editor_specific_pick_error_invalid=リソースを選択してください
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation=1 つ以上の操作を持つリソースを選択してください
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
index 7a4f477..bc15064 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ko.properties
@@ -998,7 +998,7 @@ view_alert_definition_notification_operation_editor_mode_title = 리소스 선
view_alert_definition_notification_operation_editor_relative_ancestor = 검색 시작
view_alert_definition_notification_operation_editor_relative_descendant = 다음의 필터
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = 유형의 자손을 얻을 수 없습니다
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = 검색시작 유형에 정의된 경로 유형에서 찾기 리소스 유형
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = 검색시작 유형에 정의된 경로 유형에서 찾기 리소스 유형 Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = 선택
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = 리소스를 선택하십시오
view_alert_definition_notification_operation_editor_specific_pick_text = 리소스를 선택...
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
index 68c78a6..c3fd136 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_pt.properties
@@ -1127,7 +1127,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip =
view_alert_definition_notification_operation_editor_relative_descendant = Ent\u00E3o procure por
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = Um nome especifico para identificar unicamente um recurso quando existir mais de um do mesmo tipo. Isso \u00E9 opcional, se definido, sempre ser\u00E1 um recurso do tipo slecionda na hierarquia.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = N\u00E3o \u00E9 poss\u00EDvel obter os tipos de descendentes
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = Tipo do recurso a ser procurado a baixo do tipo raiz definido na sele\u00E7\u00E3o 'Inicia a Pesquesa a partir de'.
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = Tipo do recurso a ser procurado a baixo do tipo raiz definido na sele\u00E7\u00E3o 'Inicia a Pesquesa a partir de'. Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = Selecionar
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = Favor selecionar um recurso
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Selecione um recurso que possua um ou mais opera\u00E7\u00F5es
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
index fdb1244..6c30d0d 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_ru.properties
@@ -1035,7 +1035,7 @@
#view_alert_definition_notification_operation_editor_relative_descendant = Then Filter By
#view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
#view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Cannot get type descendants
-#view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection.
+#view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection. Members of this combobox are in form _plugin_ -> _type_.
#view_alert_definition_notification_operation_editor_specific_pick_button = Pick
#view_alert_definition_notification_operation_editor_specific_pick_error_invalid = Please pick a resource
#view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Please pick a resource that has one or more operations
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
index 058c8b7..c25fc2b 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/coregui/client/Messages_zh.properties
@@ -1113,7 +1113,7 @@ view_alert_definition_notification_operation_editor_relative_ancestor_tooltip =
view_alert_definition_notification_operation_editor_relative_descendant = Then Filter By
view_alert_definition_notification_operation_editor_relative_descendant_filter_tooltip = A specific name to uniquely identify a resource when more than one resource of the selected type might exist. This is optional if there will only ever be one resource of the resource type in the selected type hierarchy.
view_alert_definition_notification_operation_editor_relative_descendant_loadFailed = Cannot get type descendants
-view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection.
+view_alert_definition_notification_operation_editor_relative_descendant_tooltip = The resource type to search for under the root type defined in the Start Search From selection. Members of this combobox are in form _plugin_ -> _type_.
view_alert_definition_notification_operation_editor_specific_pick_button = Pick
view_alert_definition_notification_operation_editor_specific_pick_error_invalid = \u9009\u62e9\u4e00\u4e2a\u8d44\u6e90
view_alert_definition_notification_operation_editor_specific_pick_error_no_operation = Please pick a resource that has one or more operations
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
index e9d686a..669790e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerBean.java
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -516,12 +517,12 @@ public class ResourceTypeManagerBean implements ResourceTypeManagerLocal, Resour
return results;
}
- public HashMap<Integer, String> getResourceTypeDescendantsWithOperations(Subject subject, int resourceTypeId) {
+ public LinkedHashMap<Integer, String> getResourceTypeDescendantsWithOperations(Subject subject, int resourceTypeId) {
List<ResourceType> types = getAllResourceTypeDescendants(subject, resourceTypeId);
excludeThoseWithoutOperations(types);
- HashMap<Integer, String> results = new HashMap<Integer, String>(types.size());
+ LinkedHashMap<Integer, String> results = new LinkedHashMap<Integer, String>(types.size());
for (ResourceType type : types) {
- results.put(type.getId(), type.getName());
+ results.put(type.getId(), type.getPlugin() + " -> " + type.getName());
}
return results;
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java
index f86e6d4..a732171 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceTypeManagerLocal.java
@@ -168,5 +168,12 @@ public interface ResourceTypeManagerLocal {
List<ResourceType> getAllResourceTypeAncestors(Subject subject, int resourceTypeId);
+ /**
+ *
+ * @param subject subject of the caller
+ * @param resourceTypeId resource type to begin with
+ * @return list of all {@link org.rhq.core.domain.resource.ResourceType}s of all descendants
+ * @deprecated This method is not currently being used at all
+ */
List<ResourceType> getAllResourceTypeDescendants(Subject subject, int resourceTypeId);
}
\ No newline at end of file
10 years, 3 months
[rhq] modules/core
by Jay Shaughnessy
modules/core/domain/src/main/resources/META-INF/persistence.xml | 2 ++
1 file changed, 2 insertions(+)
New commits:
commit 56f372fca0ff1c299ed206c6d387d7d6517209c7
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 3 16:28:42 2014 -0500
disable the hibernate.query.factory_class override in persistence.xml now
that the feature has stabilized.
diff --git a/modules/core/domain/src/main/resources/META-INF/persistence.xml b/modules/core/domain/src/main/resources/META-INF/persistence.xml
index 1bbd8c2..a15fd2e 100644
--- a/modules/core/domain/src/main/resources/META-INF/persistence.xml
+++ b/modules/core/domain/src/main/resources/META-INF/persistence.xml
@@ -21,7 +21,9 @@
<!--<property name="com.intellij.javaee.persistence.datasource" value="rhq-oracle" />-->
<property name="com.intellij.javaee.persistence.datasource" value="rhq-postgres" />
+ <!-- Used only for debugging the usages of JOIN FETCHes
<property name="hibernate.query.factory_class" value="org.rhq.core.domain.util.JoinFetchReportingQueryTranslatorFactory" />
+ -->
<!-- This value doesn't have any theoretical grounds and is purely based on experiments. Value of 32 gives
the best compromise between the quick load of queries with low and high limits (i.e. page size in tens vs.
10 years, 3 months
[rhq] modules/core
by Jay Shaughnessy
modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java | 3 +++
1 file changed, 3 insertions(+)
New commits:
commit 6b3d68b582f2ac263e5c1074facaecd6e9f84b55
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Feb 3 16:14:27 2014 -0500
Fix test failure due to new compacted resource config files being under
the agent datadir.
diff --git a/modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java b/modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java
index 60cd53d..0511a39 100644
--- a/modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java
+++ b/modules/core/arquillian-integration/container/src/test/java/org/rhq/test/arquillian/CleanUpTest.java
@@ -151,6 +151,9 @@ public class CleanUpTest extends Arquillian {
//the "changesets" directory is going to always be there because it is eagerly created during PC startup.
sExpected.add("changesets");
+ //the "rc" directory is probably going to be there because it contains compacted resource configs
+ sActual.remove("rc");
+
assertEquals(sActual, sExpected, message);
}
}
10 years, 3 months
[rhq] Branch 'feature/embeddedagent' - modules/enterprise
by mazz
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java | 2
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java | 48 +++-
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java | 102 ++++++++--
modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties | 4
modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd | 24 +-
modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java | 2
modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml | 7
7 files changed, 143 insertions(+), 46 deletions(-)
New commits:
commit 4a04637133039124295b673274e0853fbdf35050
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Mon Feb 3 15:46:27 2014 -0500
add transport agent-endpoint configurability
make server endpoing configured via one element with some attribs
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
index 937af70..115f74b 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java
@@ -82,6 +82,8 @@ class AgentSubsystemAdd extends AbstractAddStepHandler {
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_BIND_ADDRESS_ATTRIBDEF);
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_TRANSPORT_PARAMS_ATTRIBDEF);
addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.SERVER_ALIAS_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_TRANSPORT_ATTRIBDEF);
+ addOverrideProperty(context, model, overrides, AgentSubsystemDefinition.AGENT_TRANSPORT_PARAMS_ATTRIBDEF);
// create our service
AgentService service = new AgentService();
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
index ad50c4e..78d274b 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java
@@ -17,6 +17,7 @@ import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.rhq.enterprise.agent.AgentConfigurationConstants;
+import org.rhq.enterprise.communications.ServiceContainerConfigurationConstants;
public class AgentSubsystemDefinition extends SimpleResourceDefinition {
@@ -31,50 +32,61 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
protected static final SimpleAttributeDefinition AGENT_NAME_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_AGENT_NAME, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_AGENT_NAME).setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setAllowNull(true).build();
protected static final SimpleAttributeDefinition DISABLE_NATIVE_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_DISABLE_NATIVE, ModelType.BOOLEAN).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_DISABLE_NATIVE)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
- protected static final SimpleAttributeDefinition SERVER_TRANSPORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
- AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT)
- .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
- .setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_TRANSPORT)).setAllowNull(false)
- .build();
+ protected static final SimpleAttributeDefinition SERVER_BIND_ADDRESS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.SERVER_ENDPOINT_ADDRESS_XML)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
protected static final SimpleAttributeDefinition SERVER_BIND_PORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT)
+ .setXmlName(AgentSubsystemExtension.SERVER_ENDPOINT_PORT_XML)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_BIND_PORT)).setAllowNull(false)
.build();
- protected static final SimpleAttributeDefinition SERVER_BIND_ADDRESS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
- AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_BIND_ADDRESS)
- .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
+ protected static final SimpleAttributeDefinition SERVER_TRANSPORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.SERVER_ENDPOINT_TRANSPORT_XML)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_TRANSPORT)).setAllowNull(false)
+ .build();
protected static final SimpleAttributeDefinition SERVER_TRANSPORT_PARAMS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT_PARAMS, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT_PARAMS)
+ .setXmlName(AgentSubsystemExtension.SERVER_ENDPOINT_TRANSPORT_XML)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
.setDefaultValue(new ModelNode(AgentConfigurationConstants.DEFAULT_SERVER_TRANSPORT_PARAMS))
.setAllowNull(false).build();
protected static final SimpleAttributeDefinition SERVER_ALIAS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_SERVER_ALIAS, ModelType.STRING).setAllowExpression(true)
- .setXmlName(AgentSubsystemExtension.ATTRIB_SERVER_ALIAS)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setAllowNull(true).build();
protected static final SimpleAttributeDefinition SOCKET_BINDING_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
AgentSubsystemExtension.ATTRIB_SOCKET_BINDING, ModelType.STRING)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES).setDefaultValue(new ModelNode("embeddedagent"))
+ .setValidator(new StringLengthValidator(1)).setAllowNull(false).build();
+
+ protected static final SimpleAttributeDefinition AGENT_TRANSPORT_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.AGENT_ENDPOINT_TRANSPORT_XML)
.setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
- .setDefaultValue(new ModelNode("embeddedagent")).setValidator(new StringLengthValidator(1)).setAllowNull(false)
- .build();
+ .setDefaultValue(new ModelNode(ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_TRANSPORT))
+ .setAllowNull(true).build();
+
+ protected static final SimpleAttributeDefinition AGENT_TRANSPORT_PARAMS_ATTRIBDEF = new SimpleAttributeDefinitionBuilder(
+ AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT_PARAMS, ModelType.STRING).setAllowExpression(true)
+ .setXmlName(AgentSubsystemExtension.AGENT_ENDPOINT_TRANSPORT_PARAMS_XML)
+ .setFlags(AttributeAccess.Flag.RESTART_RESOURCE_SERVICES)
+ .setDefaultValue(new ModelNode(ServiceContainerConfigurationConstants.DEFAULT_CONNECTOR_TRANSPORT_PARAMS))
+ .setAllowNull(true).build();
private AgentSubsystemDefinition() {
super(AgentSubsystemExtension.SUBSYSTEM_PATH, AgentSubsystemExtension.getResourceDescriptionResolver(null),
@@ -93,6 +105,8 @@ public class AgentSubsystemDefinition extends SimpleResourceDefinition {
registerReloadRequiredWriteAttributeHandler(rr, SERVER_TRANSPORT_PARAMS_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, SERVER_ALIAS_ATTRIBDEF);
registerReloadRequiredWriteAttributeHandler(rr, SOCKET_BINDING_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, AGENT_TRANSPORT_ATTRIBDEF);
+ registerReloadRequiredWriteAttributeHandler(rr, AGENT_TRANSPORT_PARAMS_ATTRIBDEF);
}
private void registerReloadRequiredWriteAttributeHandler(ManagementResourceRegistration rr, AttributeDefinition def) {
diff --git a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
index 4374c7e..637b7a8 100644
--- a/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
+++ b/modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java
@@ -30,6 +30,7 @@ import org.jboss.staxmapper.XMLExtendedStreamReader;
import org.jboss.staxmapper.XMLExtendedStreamWriter;
import org.rhq.enterprise.agent.AgentConfigurationConstants;
+import org.rhq.enterprise.communications.ServiceContainerConfigurationConstants;
public class AgentSubsystemExtension implements Extension {
@@ -50,6 +51,15 @@ public class AgentSubsystemExtension implements Extension {
protected static final String AGENT_ENABLED = "enabled";
protected static final boolean AGENT_ENABLED_DEFAULT = false;
protected static final boolean PLUGIN_ENABLED_DEFAULT = true;
+ protected static final String SERVER_ENDPOINT_ELEMENT = "server-endpoint";
+ protected static final String SERVER_ENDPOINT_ADDRESS_XML = "address";
+ protected static final String SERVER_ENDPOINT_PORT_XML = "port";
+ protected static final String SERVER_ENDPOINT_TRANSPORT_XML = "transport";
+ protected static final String SERVER_ENDPOINT_TRANSPORT_PARAMS_XML = "transport-params";
+ protected static final String AGENT_ENDPOINT_ELEMENT = "agent-endpoint";
+ protected static final String AGENT_ENDPOINT_SOCKET_BINDING_XML = "socket-binding";
+ protected static final String AGENT_ENDPOINT_TRANSPORT_XML = "transport";
+ protected static final String AGENT_ENDPOINT_TRANSPORT_PARAMS_XML = "transport-params";
protected static final String AGENT_RESTART_OP = "restart";
protected static final String AGENT_STOP_OP = "stop";
@@ -62,10 +72,13 @@ public class AgentSubsystemExtension implements Extension {
protected static final String ATTRIB_SERVER_BIND_ADDRESS = AgentConfigurationConstants.SERVER_BIND_ADDRESS;
protected static final String ATTRIB_SERVER_TRANSPORT_PARAMS = AgentConfigurationConstants.SERVER_TRANSPORT_PARAMS;
protected static final String ATTRIB_SERVER_ALIAS = AgentConfigurationConstants.SERVER_ALIAS;
- protected static final String ATTRIB_SOCKET_BINDING = "socket-binding";
+ protected static final String ATTRIB_SOCKET_BINDING = AGENT_ENDPOINT_SOCKET_BINDING_XML;
+ protected static final String ATTRIB_AGENT_TRANSPORT = ServiceContainerConfigurationConstants.CONNECTOR_TRANSPORT;
+ protected static final String ATTRIB_AGENT_TRANSPORT_PARAMS = ServiceContainerConfigurationConstants.CONNECTOR_TRANSPORT_PARAMS;
protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME);
+
static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) {
String prefix = SUBSYSTEM_NAME + (keyPrefix == null ? "" : "." + keyPrefix);
return new StandardResourceDescriptionResolver(prefix, RESOURCE_NAME,
@@ -118,22 +131,44 @@ public class AgentSubsystemExtension implements Extension {
readPlugin(reader, pluginsAttributeNode);
}
}
+ } else if (elementName.equals(SERVER_ENDPOINT_ELEMENT)) {
+ String val = reader.getAttributeValue(null, SERVER_ENDPOINT_ADDRESS_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SERVER_BIND_ADDRESS).set(val);
+ }
+ val = reader.getAttributeValue(null, SERVER_ENDPOINT_PORT_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SERVER_BIND_PORT).set(val);
+ }
+ val = reader.getAttributeValue(null, SERVER_ENDPOINT_TRANSPORT_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SERVER_TRANSPORT).set(val);
+ }
+ val = reader.getAttributeValue(null, SERVER_ENDPOINT_TRANSPORT_PARAMS_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SERVER_TRANSPORT_PARAMS).set(val);
+ }
+ ParseUtils.requireNoContent(reader);
+ } else if (elementName.equals(AGENT_ENDPOINT_ELEMENT)) {
+ String val = reader.getAttributeValue(null, AGENT_ENDPOINT_SOCKET_BINDING_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_SOCKET_BINDING).set(val);
+ }
+ val = reader.getAttributeValue(null, AGENT_ENDPOINT_TRANSPORT_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_AGENT_TRANSPORT).set(val);
+ }
+ val = reader.getAttributeValue(null, AGENT_ENDPOINT_TRANSPORT_PARAMS_XML);
+ if (val != null) {
+ opAdd.get(ATTRIB_AGENT_TRANSPORT_PARAMS).set(val);
+ }
+ ParseUtils.requireNoContent(reader);
} else if (elementName.equals(ATTRIB_AGENT_NAME)) {
opAdd.get(ATTRIB_AGENT_NAME).set(reader.getElementText());
} else if (elementName.equals(ATTRIB_DISABLE_NATIVE)) {
opAdd.get(ATTRIB_DISABLE_NATIVE).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SERVER_TRANSPORT)) {
- opAdd.get(ATTRIB_SERVER_TRANSPORT).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SERVER_BIND_PORT)) {
- opAdd.get(ATTRIB_SERVER_BIND_PORT).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SERVER_BIND_ADDRESS)) {
- opAdd.get(ATTRIB_SERVER_BIND_ADDRESS).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SERVER_TRANSPORT_PARAMS)) {
- opAdd.get(ATTRIB_SERVER_TRANSPORT_PARAMS).set(reader.getElementText());
} else if (elementName.equals(ATTRIB_SERVER_ALIAS)) {
opAdd.get(ATTRIB_SERVER_ALIAS).set(reader.getElementText());
- } else if (elementName.equals(ATTRIB_SOCKET_BINDING)) {
- opAdd.get(ATTRIB_SOCKET_BINDING).set(reader.getElementText());
} else {
throw ParseUtils.unexpectedElement(reader);
}
@@ -184,12 +219,47 @@ public class AgentSubsystemExtension implements Extension {
// our config elements
writeElement(writer, node, ATTRIB_AGENT_NAME);
writeElement(writer, node, ATTRIB_DISABLE_NATIVE);
- writeElement(writer, node, ATTRIB_SERVER_TRANSPORT);
- writeElement(writer, node, ATTRIB_SERVER_BIND_PORT);
- writeElement(writer, node, ATTRIB_SERVER_BIND_ADDRESS);
- writeElement(writer, node, ATTRIB_SERVER_TRANSPORT_PARAMS);
writeElement(writer, node, ATTRIB_SERVER_ALIAS);
- writeElement(writer, node, ATTRIB_SOCKET_BINDING);
+
+ // <server-endpoint>
+ writer.writeStartElement(SERVER_ENDPOINT_ELEMENT);
+ ModelNode serverAddressNode = node.get(ATTRIB_SERVER_BIND_ADDRESS);
+ ModelNode serverPortNode = node.get(ATTRIB_SERVER_BIND_PORT);
+ ModelNode serverTransportNode = node.get(ATTRIB_SERVER_TRANSPORT);
+ ModelNode serverTransportParamsNode = node.get(ATTRIB_SERVER_TRANSPORT_PARAMS);
+
+ if (serverPortNode.isDefined()) {
+ writer.writeAttribute(SERVER_ENDPOINT_PORT_XML, serverPortNode.asString());
+ }
+ if (serverAddressNode.isDefined()) {
+ writer.writeAttribute(SERVER_ENDPOINT_ADDRESS_XML, serverAddressNode.asString());
+ }
+ if (serverTransportNode.isDefined()) {
+ writer.writeAttribute(SERVER_ENDPOINT_TRANSPORT_XML, serverTransportNode.asString());
+ }
+ if (serverTransportParamsNode.isDefined()) {
+ writer.writeAttribute(SERVER_ENDPOINT_TRANSPORT_PARAMS_XML, serverTransportParamsNode.asString());
+ }
+ // </server-endpoint>
+ writer.writeEndElement();
+
+ // <agent-endpoint>
+ writer.writeStartElement(AGENT_ENDPOINT_ELEMENT);
+ ModelNode agentSocketBindingNode = node.get(ATTRIB_SOCKET_BINDING);
+ ModelNode agentTransportNode = node.get(ATTRIB_AGENT_TRANSPORT);
+ ModelNode agentTransportParamsNode = node.get(ATTRIB_AGENT_TRANSPORT_PARAMS);
+
+ if (agentSocketBindingNode.isDefined()) {
+ writer.writeAttribute(AGENT_ENDPOINT_SOCKET_BINDING_XML, agentSocketBindingNode.asString());
+ }
+ if (agentTransportNode.isDefined()) {
+ writer.writeAttribute(AGENT_ENDPOINT_TRANSPORT_XML, agentTransportNode.asString());
+ }
+ if (agentTransportParamsNode.isDefined()) {
+ writer.writeAttribute(AGENT_ENDPOINT_TRANSPORT_PARAMS_XML, agentTransportParamsNode.asString());
+ }
+ // </agent-endpoint>
+ writer.writeEndElement();
// <plugins>
writer.writeStartElement(PLUGINS_ELEMENT);
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
index e2badfc..680f9f2 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties
@@ -7,6 +7,8 @@ embeddedagent.status=Tells you if the RHQ Agent is currently started or stopped.
embeddedagent.enabled=When true, the RHQ Agent will be deployed and started. Otherwise, it will be disabled.
embeddedagent.plugins=Indicates what plugins should be enabled or disabled.
embeddedagent.socket-binding=Determines the binding address and port the agent listens to for incoming server messages.
+embeddedagent.rhq.communications.connector.transport=The transport server must use to communicate with the agent.
+embeddedagent.rhq.communications.connector.transport-params=The transport parameters the server must use to communicate with the agent.
embeddedagent.rhq.agent.name=Name to uniquely identify this agent among all other agents in the environment
embeddedagent.rhq.agent.disable-native-system=The RHQ Agent has a native system on certain supported platforms to help the \n\
plugin container perform discovery of native components on those platforms. \n\
@@ -20,4 +22,4 @@ alias (see rhq.agent.server.alias), and if that is not defined \n\
the RHQ Agent will default to localhost or 127.0.0.1.
embeddedagent.rhq.agent.server.transport-params=Communications transport parameters used when sending messages to the RHQ Server.
embeddedagent.rhq.agent.server.alias=If the server address is not defined, this is the DNS alias name the \n\
-RHQ Agent will resolve and use for the server address.
+RHQ Agent will resolve and use for the server address.
\ No newline at end of file
diff --git a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
index d587e23..a116308 100644
--- a/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
+++ b/modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd
@@ -11,17 +11,27 @@
<xs:attribute name="enabled" type="xs:boolean" use="required" default="false"/>
<xs:all>
<xs:element name="rhq.agent.name" type="xs:string"/>
- <xs:element name="rhq.agent.disable-native-system" type="xs:boolean" use="optional"/>
- <xs:element name="rhq.agent.server.transport" type="xs:string"/>
- <xs:element name="rhq.agent.server.bind-port" type="xs:integer"/>
- <xs:element name="rhq.agent.server.bind-address" type="xs:string" use="optional"/>
- <xs:element name="rhq.agent.server.transport-params" type="xs:string" />
- <xs:element name="rhq.agent.server.alias" type="xs:string" use="optional"/>
- <xs:element name="socket-binding" type="xs:string"/>
+ <xs:element name="rhq.agent.disable-native-system" type="xs:boolean"/>
+ <xs:element name="rhq.agent.server.alias" type="xs:string"/>
+ <xs:element name="server-endpoint" type="serverEndpointType"/>
+ <xs:element name="agent-endpoint" type="agentEndpointType"/>
<xs:element name="plugins" type="pluginsType"/>
</xs:all>
</xs:complexType>
+ <xs:complexType name="serverEndpointType">
+ <xs:attribute name="address"/>
+ <xs:attribute name="port" type="xs:integer"/>
+ <xs:attribute name="transport"/>
+ <xs:attribute name="transport-params"/>
+ </xs:complexType>
+
+ <xs:complexType name="agentEndpointType">
+ <xs:attribute name="socket-binding"/>
+ <xs:attribute name="transport"/>
+ <xs:attribute name="transport-params"/>
+ </xs:complexType>
+
<xs:complexType name="pluginsType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="plugin" type="pluginType"/>
diff --git a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
index 0f3a8fa..b6126a0 100644
--- a/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
+++ b/modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java
@@ -198,6 +198,8 @@ public class SubsystemParsingTestCase extends SubsystemBaseParsingTestCase {
List<Property> attributes = content.get("attributes").asPropertyList();
List<String> expectedAttributes = Arrays.asList( //
+ AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT_PARAMS, //
+ AgentSubsystemExtension.ATTRIB_AGENT_TRANSPORT, //
AgentSubsystemExtension.ATTRIB_SOCKET_BINDING, //
AgentSubsystemExtension.ATTRIB_SERVER_TRANSPORT, //
AgentSubsystemExtension.ATTRIB_SERVER_BIND_PORT, //
diff --git a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
index 09da3f6..d4ea3c8 100644
--- a/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
+++ b/modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml
@@ -1,13 +1,10 @@
<subsystem xmlns="urn:org.rhq:embeddedagent:1.0" enabled="true">
<rhq.agent.name>embeddedagent-test</rhq.agent.name>
<!-- <rhq.agent.disable-native-system>true</rhq.agent.disable-native-system> -->
- <rhq.agent.server.transport>test-transport</rhq.agent.server.transport>
- <rhq.agent.server.bind-port>12345</rhq.agent.server.bind-port>
- <!-- <rhq.agent.server.bind-address>test-bind-address</rhq.agent.server.bind-address> -->
- <rhq.agent.server.transport-params>test-transport-params</rhq.agent.server.transport-params>
<!-- <rhq.agent.server.alias>test-alias</rhq.agent.server.alias> -->
- <socket-binding>embeddedagent</socket-binding>
+ <server-endpoint port="7080" transport="test-transport" transport-params="test-transport-params" />
+ <agent-endpoint socket-binding="embeddedagent" transport="socket"/>
<plugins>
<plugin name="platform" enabled="true" />
10 years, 3 months