[rhq] Branch 'feature/embeddedagent' - modules/enterprise
by mazz
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java | 32 ++++-
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java | 56 +++++++++-
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java | 41 ++++++-
modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties | 15 ++
modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd | 6 +
modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java | 12 +-
modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml | 7 +
7 files changed, 150 insertions(+), 19 deletions(-)
New commits:
commit 2f0746ff35efc2c5748073cd4ed0c333d56c17d0
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" />
9 years, 10 months
[rhq] etc/rhq-ircBot
by Jiri Kremser
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 ++++------
6 files changed, 308 insertions(+), 74 deletions(-)
New commits:
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;
}
}
9 years, 10 months
[rhq] Branch 'release/jon3.2.x' - modules/plugins
by Jiri Kremser
modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptArgumentParser.java | 41 ++++++----
modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptDiscoveryComponent.java | 27 ------
modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptServerComponent.java | 40 +++++++--
modules/plugins/script/src/main/resources/META-INF/rhq-plugin.xml | 13 ++-
modules/plugins/script/src/test/java/org/rhq/plugins/script/ScriptArgumentParserTest.java | 7 +
5 files changed, 76 insertions(+), 52 deletions(-)
New commits:
commit 8058e6ba255af1cce6e269b4452fe9be2c548833
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Sat Jan 25 00:08:01 2014 +0100
[BZ 1049608] - Changes to arg parsing in script server plugin
* we by default keep the broken old behavior (blind split by space)
* a boolean plugin prop to switch quoting and escapes on/off
* configurable escape char set to \ for all platforms
* escaping (when switched on) is POSIX-like:
1) In unquoted text: the escape character preserves the value of any
following character
2) In double-quoted text: the escape character escapes " and itself
otherwise is both the escape character and the following character
are left intact
3) In single-quoted text: no escaping can occur
(cherry picked from commit d8e1e71efc8eb3ffcf2729fc4518b37e5cd304e5)
Signed-off-by: Jirka Kremser <jkremser(a)redhat.com>
diff --git a/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptArgumentParser.java b/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptArgumentParser.java
index cd12f0d..a152b1e 100644
--- a/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptArgumentParser.java
+++ b/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptArgumentParser.java
@@ -10,7 +10,7 @@ import java.util.List;
public final class ScriptArgumentParser {
private enum State {
- SPACE, ESCAPE, ARG, QUOTE
+ SPACE, ESCAPE, ARG, DOUBLE_QUOTE, DOUBLE_QUOTE_ESCAPE, SINGLE_QUOTE
}
private ScriptArgumentParser() {
@@ -18,7 +18,6 @@ public final class ScriptArgumentParser {
public static String[] parse(String args, char escape) {
State state = State.SPACE;
- char activeQuote = '\u0000';
List<String> parsedArgs = new ArrayList<String>();
int i = 0;
@@ -37,9 +36,10 @@ public final class ScriptArgumentParser {
if (c == escape) {
state = State.ESCAPE;
- } else if (isQuote(c)) {
- activeQuote = c;
- state = State.QUOTE;
+ } else if (c == '"') {
+ state = State.DOUBLE_QUOTE;
+ } else if (c == '\'') {
+ state = State.SINGLE_QUOTE;
} else if (isNotWhitespace) {
arg.append(c);
state = State.ARG;
@@ -52,20 +52,35 @@ public final class ScriptArgumentParser {
case ARG:
if (c == escape) {
state = State.ESCAPE;
- } else if (isQuote(c)) {
- activeQuote = c;
- state = State.QUOTE;
+ } else if (c == '"') {
+ state = State.DOUBLE_QUOTE;
+ } else if (c == '\'') {
+ state = State.SINGLE_QUOTE;
} else if (!Character.isWhitespace(c)) {
arg.append(c);
} else {
state = State.SPACE;
}
break;
- case QUOTE:
- if (c == activeQuote) {
+ case DOUBLE_QUOTE:
+ if (c == '"') {
state = State.ARG;
} else if (c == escape) {
- state = State.ESCAPE;
+ state = State.DOUBLE_QUOTE_ESCAPE;
+ } else {
+ arg.append(c);
+ }
+ break;
+ case DOUBLE_QUOTE_ESCAPE:
+ if (c != '"' && c != escape) {
+ arg.append(escape);
+ }
+ arg.append(c);
+ state = State.DOUBLE_QUOTE;
+ break;
+ case SINGLE_QUOTE:
+ if (c == '\'') {
+ state = State.ARG;
} else {
arg.append(c);
}
@@ -88,8 +103,4 @@ public final class ScriptArgumentParser {
bld.delete(0, bld.length());
}
}
-
- private static boolean isQuote(char c) {
- return c == '\'' || c == '"';
- }
}
diff --git a/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptDiscoveryComponent.java b/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptDiscoveryComponent.java
index 4ee055a..82cf34e 100644
--- a/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptDiscoveryComponent.java
+++ b/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptDiscoveryComponent.java
@@ -52,11 +52,7 @@ import org.rhq.core.util.exception.ThrowableUtil;
*
* @author John Mazzitelli
*/
-public class ScriptDiscoveryComponent implements ResourceDiscoveryComponent<ResourceComponent<?>>, ManualAddFacet<ResourceComponent<?>>,
- ResourceUpgradeFacet<ResourceComponent<?>> {
-
- public static final String ESCAPE_CHARACTER_PROP_NAME = "escapeCharacter";
- private static final String ESCAPE_CHARACTER_DEFAULT = "__TO_BE_SET_TO_\\_OR_^__";
+public class ScriptDiscoveryComponent implements ResourceDiscoveryComponent<ResourceComponent<?>>, ManualAddFacet<ResourceComponent<?>> {
private final Log log = LogFactory.getLog(ScriptDiscoveryComponent.class);
@@ -128,7 +124,7 @@ public class ScriptDiscoveryComponent implements ResourceDiscoveryComponent<Reso
} else {
String args = pluginConfig.getSimpleValue(ScriptServerComponent.PLUGINCONFIG_DESC_ARGS, null);
ProcessExecutionResults results = ScriptServerComponent.executeExecutable(context
- .getSystemInformation(), pluginConfig, args, 5000L, true);
+ .getSystemInformation(), pluginConfig, args, 5000L, true, ScriptServerComponent.getConfiguredEscapeCharacter(pluginConfig));
if (results != null) {
if (results.getError() != null) {
log.warn("Failed to execute cli executable to get description. Cause: "
@@ -164,23 +160,6 @@ public class ScriptDiscoveryComponent implements ResourceDiscoveryComponent<Reso
return description;
}
- @Override
- public ResourceUpgradeReport upgrade(ResourceUpgradeContext<ResourceComponent<?>> inventoriedResource) {
- PropertySimple escapeCharacter = inventoriedResource.getPluginConfiguration().getSimple(ESCAPE_CHARACTER_PROP_NAME);
-
- if (escapeCharacter != null && !ESCAPE_CHARACTER_DEFAULT.equals(escapeCharacter.getStringValue())) {
- return null;
- }
-
- char escapeChar = File.separatorChar == '/' ? '\\' : '^';
-
- ResourceUpgradeReport report = new ResourceUpgradeReport();
- report.setNewPluginConfiguration(inventoriedResource.getPluginConfiguration().clone());
- report.getNewPluginConfiguration().put(new PropertySimple(ESCAPE_CHARACTER_PROP_NAME, Character.toString(escapeChar)));
-
- return report;
- }
-
/**
* Attempts to determine the version of the resource managed by the CLI.
*
@@ -198,7 +177,7 @@ public class ScriptDiscoveryComponent implements ResourceDiscoveryComponent<Reso
} else {
String args = pluginConfig.getSimpleValue(ScriptServerComponent.PLUGINCONFIG_VERSION_ARGS, null);
ProcessExecutionResults results = ScriptServerComponent.executeExecutable(context
- .getSystemInformation(), pluginConfig, args, 5000L, true);
+ .getSystemInformation(), pluginConfig, args, 5000L, true, ScriptServerComponent.getConfiguredEscapeCharacter(pluginConfig));
if (results != null) {
if (results.getError() != null) {
log.warn("Failed to execute cli executable to get version. Cause: "
diff --git a/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptServerComponent.java b/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptServerComponent.java
index 7a81a6f..d62f2a1 100644
--- a/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptServerComponent.java
+++ b/modules/plugins/script/src/main/java/org/rhq/plugins/script/ScriptServerComponent.java
@@ -78,6 +78,8 @@ public class ScriptServerComponent implements ResourceComponent, MeasurementFace
protected static final String PLUGINCONFIG_DESC_ARGS = "descriptionArguments";
protected static final String PLUGINCONFIG_DESC_REGEX = "descriptionRegex";
protected static final String PLUGINCONFIG_FIXED_DESC = "fixedDescription";
+ protected static final String PLUGINCONFIG_QUOTING_ENABLED = "quotingEnabled";
+ protected static final String PLUGINCONFIG_ESCAPE_CHARACTER = "escapeCharacter";
protected static final String OPERATION_PARAM_ARGUMENTS = "arguments";
protected static final String OPERATION_PARAM_WAIT_TIME = "waitTime";
@@ -90,7 +92,9 @@ public class ScriptServerComponent implements ResourceComponent, MeasurementFace
protected static final String METRIC_PROPERTY_REGEX = "regex";
protected static final String METRIC_PROPERTY_EXITCODE = "exitcode";
- private Configuration resourceConfiguration;
+ protected static final char DISABLING_ESCAPE_CHARACTER = '\u0000';
+
+ private char escapeChar = DISABLING_ESCAPE_CHARACTER;
private ResourceContext resourceContext;
public void start(ResourceContext context) {
@@ -99,6 +103,8 @@ public class ScriptServerComponent implements ResourceComponent, MeasurementFace
}
this.resourceContext = context;
+
+ escapeChar = getConfiguredEscapeCharacter(resourceContext.getPluginConfiguration());
}
public void stop() {
@@ -380,7 +386,7 @@ public class ScriptServerComponent implements ResourceComponent, MeasurementFace
SystemInfo sysInfo = this.resourceContext.getSystemInformation();
Configuration pluginConfig = this.resourceContext.getPluginConfiguration();
ProcessExecutionResults results = executeExecutable(sysInfo, pluginConfig, args, wait, captureOutput,
- killOnTimeout);
+ killOnTimeout, escapeChar);
if (log.isDebugEnabled()) {
logDebug("CLI results: exitcode=[" + results.getExitCode() + "]; error=[" + results.getError()
@@ -390,22 +396,36 @@ public class ScriptServerComponent implements ResourceComponent, MeasurementFace
return results;
}
+
+ protected static char getConfiguredEscapeCharacter(Configuration pluginConfiguration) {
+ char escapeChar = DISABLING_ESCAPE_CHARACTER;
+ boolean quotingEnabled = Boolean.parseBoolean(pluginConfiguration.getSimpleValue(PLUGINCONFIG_QUOTING_ENABLED, "false"));
+ if (quotingEnabled) {
+ String ec = pluginConfiguration.getSimpleValue(PLUGINCONFIG_ESCAPE_CHARACTER, "\\");
+ escapeChar = ec.charAt(0);
+ }
+
+ return escapeChar;
+ }
+
// This is protected static so the discovery component can use it.
protected static ProcessExecutionResults executeExecutable(SystemInfo sysInfo, Configuration pluginConfig,
- String args, long wait, boolean captureOutput) throws InvalidPluginConfigurationException {
+ String args, long wait, boolean captureOutput, char escapeChar) throws InvalidPluginConfigurationException {
- return executeExecutable(sysInfo, pluginConfig, args, wait, captureOutput, true);
+ return executeExecutable(sysInfo, pluginConfig, args, wait, captureOutput, true, escapeChar);
}
private static ProcessExecutionResults executeExecutable(SystemInfo sysInfo, Configuration pluginConfig,
- String args, long wait, boolean captureOutput, boolean killOnTimeout)
+ String args, long wait, boolean captureOutput, boolean killOnTimeout, char escapeChar)
throws InvalidPluginConfigurationException {
ProcessExecution processExecution = getProcessExecutionInfo(pluginConfig);
if (args != null) {
- char escapeChar = pluginConfig.getSimpleValue(ScriptDiscoveryComponent.ESCAPE_CHARACTER_PROP_NAME, "\\").charAt(
- 0);
- processExecution.setArguments(ScriptArgumentParser.parse(args, escapeChar));
+ if (isQuotingEnabled(escapeChar)) {
+ processExecution.setArguments(ScriptArgumentParser.parse(args, escapeChar));
+ } else {
+ processExecution.setArguments(args.split(" "));
+ }
}
processExecution.setCaptureOutput(captureOutput);
processExecution.setWaitForCompletion(wait);
@@ -601,4 +621,8 @@ public class ScriptServerComponent implements ResourceComponent, MeasurementFace
private void logDebug(String msg) {
log.debug("[" + this.resourceContext.getResourceKey() + "]: " + msg);
}
+
+ private static boolean isQuotingEnabled(char escapeChar) {
+ return escapeChar != DISABLING_ESCAPE_CHARACTER;
+ }
}
diff --git a/modules/plugins/script/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/script/src/main/resources/META-INF/rhq-plugin.xml
index 3f63d36..e1a96f2 100644
--- a/modules/plugins/script/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/script/src/main/resources/META-INF/rhq-plugin.xml
@@ -42,9 +42,16 @@
<c:simple-property name="descriptionRegex" required="false" description="The regex that can pick out the description from the executable output. If the regex has a captured group, its matched content will be used as the description. If there is no captured group, the entire output will be used as the description."/>
<c:simple-property name="fixedDescription" required="false" description="If specified, this will be the description of the managed resource - the executable will not be invoked to determine it." />
</c:group>
- <c:group name="advanced" displayName="Advanced">
- <c:simple-property name="escapeCharacter" required="true" description="The escape character to be used when parsing arguments. By default this is (without quotes) '^' on Windows and '\' everywhere else."
- default="__TO_BE_SET_TO_\_OR_^__">
+ <c:group name="argumentsParsing" displayName="Parsing of Arguments">
+ <c:simple-property name="quotingEnabled" displayName="Enable Quoting of Arguments" required="true" type="boolean" default="false">
+ <c:description>
+ 1) In unquoted text: the escape character preserves the value of any following character
+ 2) In double-quoted text: the escape character escapes " and itself otherwise is both the escape character and the following character are left intact
+ 3) In single-quoted text: no escaping can occur
+ </c:description>
+ </c:simple-property>
+ <c:simple-property name="escapeCharacter" required="true" description="The escape character to be used when parsing arguments. By default the escape character is backslash."
+ default="\">
<c:constraint>
<c:regex-constraint expression="." />
</c:constraint>
diff --git a/modules/plugins/script/src/test/java/org/rhq/plugins/script/ScriptArgumentParserTest.java b/modules/plugins/script/src/test/java/org/rhq/plugins/script/ScriptArgumentParserTest.java
index 67a88c0..5c30200 100644
--- a/modules/plugins/script/src/test/java/org/rhq/plugins/script/ScriptArgumentParserTest.java
+++ b/modules/plugins/script/src/test/java/org/rhq/plugins/script/ScriptArgumentParserTest.java
@@ -2,6 +2,7 @@ package org.rhq.plugins.script;
import static org.testng.Assert.assertEquals;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -19,12 +20,14 @@ public class ScriptArgumentParserTest {
testCases.put("1 2\t3", new String[]{"1", "2", "3"});
testCases.put("1 '2 ' \"3'\" '4'abs '5\"'", new String[]{"1", "2 ", "3'", "4abs", "5\""});
- testCases.put("\\ \\2 '3\\'a'", new String[]{" ", "2", "3'a"});
+ testCases.put("\\ \\2 '3\\'\\'a'", new String[]{" ", "2", "3\\'a"});
+ testCases.put("\"C:\\Program Files\\Lukas' \\\"Tests\\\"\\1\"", new String[]{"C:\\Program Files\\Lukas' \"Tests\"\\1"});
for(Map.Entry<String, String[]> testCase : testCases.entrySet()) {
String[] result = ScriptArgumentParser.parse(testCase.getKey(), '\\');
- assertEquals(result, testCase.getValue(), "Failed to parse [" + testCase.getKey() + "]");
+ assertEquals(result, testCase.getValue(), "Failed to parse [" + testCase.getKey() + "]. Expected: " + Arrays
+ .asList(testCase.getValue()) + ", but got: " + Arrays.asList(result));
}
}
}
9 years, 10 months
[rhq] Branch 'release/jon3.2.x' - modules/core
by Jiri Kremser
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 +-
2 files changed, 42 insertions(+), 42 deletions(-)
New commits:
commit 3e109d407a38ec35221b2c5e2cb26b5687c40ef1
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
(cherry picked from commit b4c048f8dfe3aab6f4c8347e856b80f40e66f29a)
Signed-off-by: Jirka Kremser <jkremser(a)redhat.com>
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);
9 years, 10 months
[rhq] Branch 'feature/embeddedagent' - 3 commits - .classpath modules/enterprise
by mazz
.classpath | 4
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java | 23 +--
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentEnabledAttributeHandler.java | 22 +--
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java | 19 ++-
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemAdd.java | 17 ++
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemDefinition.java | 8 +
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemExtension.java | 27 +++-
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/PluginsAttributeHandler.java | 6 -
modules/enterprise/server/embeddedagent/src/main/resources/org/rhq/embeddedagent/extension/LocalDescriptions.properties | 3
modules/enterprise/server/embeddedagent/src/main/resources/schema/embeddedagent.xsd | 1
modules/enterprise/server/embeddedagent/src/test/java/org/rhq/embeddedagent/extension/SubsystemParsingTestCase.java | 58 +++++-----
modules/enterprise/server/embeddedagent/src/test/resources/org/rhq/embeddedagent/extension/subsystem.xml | 1
12 files changed, 120 insertions(+), 69 deletions(-)
New commits:
commit e70d32f70a1ee39eb82b5919844ef15ef4803977
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 ec473d3ad469ffbc63f6b0ac0504ff992c744d14
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 5b9e02a9cd8249844507fff12395edfdd842797a
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 {
9 years, 10 months
[rhq] Branch 'feature/embeddedagent' - modules/enterprise
by mazz
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java | 21 +++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
New commits:
commit 3ca6149ace5c4bdfbdcfcc020c49c94b7dd3a19c
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 {
9 years, 10 months
[rhq] Branch 'feature/embeddedagent' - modules/enterprise
by mazz
modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
New commits:
commit fef4ec6c3ce4c2733b5427f69bb2478b3cdf352e
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>
9 years, 10 months
[rhq] Branch 'feature/embeddedagent' - modules/enterprise
by mazz
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java | 55 ++++++----
1 file changed, 35 insertions(+), 20 deletions(-)
New commits:
commit d737ad943bc13ed1de76294ae6baa5ac9a58ba76
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);
}
/**
9 years, 10 months
[rhq] Branch 'feature/embeddedagent' - modules/enterprise
by mazz
modules/enterprise/server/embeddedagent/pom.xml | 28
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentConfigurationSetup.java | 305 ++++++++++
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentService.java | 52 +
modules/enterprise/server/embeddedagent/src/main/java/org/rhq/embeddedagent/extension/AgentSubsystemRestart.java | 15
modules/enterprise/server/embeddedagent/src/main/resources/module/main/module.xml | 1
modules/enterprise/server/embeddedagent/src/main/scripts/module-assembly.xml | 7
6 files changed, 393 insertions(+), 15 deletions(-)
New commits:
commit ef729cd9b8c989ef0f37c35bb5734e8c698482da
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>
9 years, 10 months
[rhq] modules/plugins
by Thomas Segismont
modules/plugins/jboss-as-7/src/main/java/org/rhq/modules/plugins/jbossas7/BaseServerComponent.java | 19 +++++-----
1 file changed, 10 insertions(+), 9 deletions(-)
New commits:
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() {
9 years, 10 months