modules/enterprise/agent/src/etc/product_connectors/README.txt | 20 modules/enterprise/server/container/src/main/downloadable-resources/connectors/README.txt | 22 + modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml | 20 modules/helpers/pom.xml | 1 modules/helpers/rtfilter-subsystem/pom.xml | 108 +++++ modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterExtension.java | 207 ++++++++++ modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemAdd.java | 69 +++ modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemDefinition.java | 45 ++ modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemRemove.java | 44 ++ modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/deployment/RtFilterDeploymentUnitProcessor.java | 141 ++++++ modules/helpers/rtfilter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension | 1 modules/helpers/rtfilter-subsystem/src/main/resources/module/main/module.xml | 27 + modules/helpers/rtfilter-subsystem/src/main/resources/org/rhq/helpers/rtfilter/subsystem/LocalDescriptions.properties | 3 modules/helpers/rtfilter-subsystem/src/main/resources/schema/rtfilter-subsystem.xsd | 129 ++++++ modules/helpers/rtfilter-subsystem/src/main/scripts/module-assembly.xml | 31 + modules/helpers/rtfilter-subsystem/src/test/java/org/rhq/helpers/rtfilter/subsystem/SubsystemXmlParsingTest.java | 67 +++ modules/helpers/rtfilter/pom.xml | 46 +- modules/helpers/rtfilter/src/main/resources/module/main/module.xml | 15 modules/helpers/rtfilter/src/main/scripts/module-assembly.xml | 31 + 19 files changed, 990 insertions(+), 37 deletions(-)
New commits: commit 17261077b22265a59dc1aef5074945e5dd137320 Author: Ian Springer ian.springer@redhat.com Date: Fri Apr 27 11:56:20 2012 -0400
[BZ 815889] add support for globally deploying the RT filter to an AS7 instance using an AS7 subsystem (https://bugzilla.redhat.com/show_bug.cgi?id=815889)
diff --git a/modules/enterprise/agent/src/etc/product_connectors/README.txt b/modules/enterprise/agent/src/etc/product_connectors/README.txt deleted file mode 100644 index 2118261..0000000 --- a/modules/enterprise/agent/src/etc/product_connectors/README.txt +++ /dev/null @@ -1,20 +0,0 @@ -This directory contains connectors that instrument various products to expose -monitoring data. This monitoring data can then be accessed by the RHQ plugins -corresponding to those products. - -HTTP Response Time Filter --------------------------- -This is a servlet filter that can measure response times for HTTP requests -made to servlets. The filter currently supports: - -- Embedded JBossAS Tomcat -- Standalone JBoss EWS Tomcat -- Standalone Apache EWS Tomcat - -Note, a commons-logging jar is supplied for use with Standalone Tomcat6. It -is not required for ealier, supported versions (e.g 5.5). - -The Tomcat Server must be instrumented with the Filter. For information on -configuring the filter, see the Response Times section at the following URL: - -http://www.redhat.com/docs/en-US/JBoss_ON/html/Feature_Guide/index.html \ No newline at end of file diff --git a/modules/enterprise/server/container/src/main/downloadable-resources/connectors/README.txt b/modules/enterprise/server/container/src/main/downloadable-resources/connectors/README.txt new file mode 100644 index 0000000..e0e10d5 --- /dev/null +++ b/modules/enterprise/server/container/src/main/downloadable-resources/connectors/README.txt @@ -0,0 +1,22 @@ +This directory contains connectors that instrument various products to expose +monitoring data. This monitoring data can then be accessed by the RHQ plugins +corresponding to those products. + +HTTP Response Time Filter +-------------------------- +This is a servlet filter that can measure response times for HTTP requests +made to servlets and write the response times to a logfile. The filter is +compatible with any servlet 2.4 or later container running on Java 1.4 or +later. However, since upport for parsing the response time logfiles is +only provided by the jboss-as, jboss-as-5, jboss-as-7, and tomcat RHQ +plugins, it typically is only of value to deploy the filter to JBoss AS +or Tomcat. + +Note, a commons-logging jar is supplied for use with Tomcat 6. It is not +required for earlier versions of Tomcat, since they already include that jar. + +For details on how to deploy the filter to various versions of JBoss AS and +Tomcat, see: + +http://rhq-project.org/display/JOPR2/Managed+Product+Configuration + diff --git a/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml b/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml index 98bd130..50e891d 100644 --- a/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml +++ b/modules/enterprise/server/container/src/main/scripts/rhq-container.build.xml @@ -364,11 +364,11 @@ <mkdir dir="${jboss.deploy.dir}/${rhq.earName}/rhq-downloads" /> <!-- deploy all the static downloadable content --> - <echo>Deploying static downloadable content</echo> + <echo>Deploying static downloadable content...</echo> <copy todir="${jboss.deploy.dir}/${rhq.earName}/rhq-downloads" verbose="true" failonerror="false"> - <fileset dir="${basedir}/src/main/downloadable-resources" /> + <fileset dir="${basedir}/src/main/downloadable-resources" /> </copy> <!-- make sure our downloads directories exist --> @@ -435,19 +435,23 @@ </target>
<target name="package-connectors"> - <echo>Deploying the response-time servlet filter connectors ...</echo> + <echo>Deploying the response-time (RT) servlet filter connectors ...</echo> <delete file="${jboss.deploy.dir}/${rhq.earName}/rhq-downloads/connectors/connector-rtfilter.zip" /> <zip destfile="${jboss.deploy.dir}/${rhq.earName}/rhq-downloads/connectors/connector-rtfilter.zip"> - <zipfileset dir="${basedir}/../../agent/src/etc/product_connectors"> - <include name="README.txt" /> - </zipfileset> - <zipfileset dir="${settings.localRepository}/org/rhq/rhq-rtfilter/${project.version}"> + <zipfileset dir="${settings.localRepository}/org/rhq/helpers/rhq-rtfilter/${project.version}"> <include name="rhq-rtfilter-${project.version}.jar" /> </zipfileset> <zipfileset dir="${settings.localRepository}/commons-logging/commons-logging/1.1.1"> <include name="commons-logging-1.1.1.jar" /> </zipfileset> </zip> + + <!-- rtfilter AS7 modules --> + <copy file="${settings.localRepository}/org/rhq/helpers/rhq-rtfilter/${project.version}/rhq-rtfilter-${project.version}.zip" + tofile="${jboss.deploy.dir}/${rhq.earName}/rhq-downloads/connectors/rhq-rtfilter-module.zip" /> + + <copy file="${settings.localRepository}/org/rhq/helpers/rhq-rtfilter-subsystem/${project.version}/rhq-rtfilter-subsystem-${project.version}.zip" + tofile="${jboss.deploy.dir}/${rhq.earName}/rhq-downloads/connectors/rhq-rtfilter-subsystem-module.zip" /> </target>
<target name="prepare-bin-dir"> @@ -842,7 +846,7 @@ rhq.autoinstall.public-endpoint-address= undeploy-ds, prepare-web-services-2" description="If this is a release build, make sure it is properly prepared.">
- <echo>Adding license headers files...</echo> + <echo>Adding license files...</echo> <copy todir="${project.build.outputDirectory}"> <fileset dir="${basedir}/../../../.." includes="LICENSE*" /> </copy> diff --git a/modules/helpers/pom.xml b/modules/helpers/pom.xml index 797f302..1f3754d 100644 --- a/modules/helpers/pom.xml +++ b/modules/helpers/pom.xml @@ -29,6 +29,7 @@ <modules>
<module>rtfilter</module> + <module>rtfilter-subsystem</module> <!-- <module>pluginGen</module> <module>pluginAnnotations</module> diff --git a/modules/helpers/rtfilter-subsystem/pom.xml b/modules/helpers/rtfilter-subsystem/pom.xml new file mode 100644 index 0000000..e2166c4 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/pom.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd%22%3E + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.rhq.helpers</groupId> + <artifactId>rhq-helpers</artifactId> + <version>4.4.0-SNAPSHOT</version> + </parent> + + <groupId>org.rhq.helpers</groupId> + <artifactId>rhq-rtfilter-subsystem</artifactId> + + <name>RHQ Response-Time Filter - JBoss AS7 Subsystem</name> + + <properties> + <version.jboss.as>7.1.1.Final</version.jboss.as> + <version.junit>4.8.2</version.junit> + <moduleName>${groupId}.${artifactId}</moduleName> + </properties> + + + <build> + + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> + + <plugins> + + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.6</source> + <target>1.6</target> + </configuration> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <descriptors> + <descriptor>src/main/scripts/module-assembly.xml</descriptor> + </descriptors> + </configuration> + <executions> + <execution> + <id>module-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.jboss.as</groupId> + <artifactId>jboss-as-controller</artifactId> + <version>${version.jboss.as}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jboss.as</groupId> + <artifactId>jboss-as-server</artifactId> + <version>${version.jboss.as}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jboss.as</groupId> + <artifactId>jboss-as-ee</artifactId> + <version>${version.jboss.as}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.jboss.as</groupId> + <artifactId>jboss-as-web</artifactId> + <version>${version.jboss.as}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.rhq.helpers</groupId> + <artifactId>rhq-rtfilter</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + <!-- test deps --> + <dependency> + <groupId>org.jboss.as</groupId> + <artifactId>jboss-as-subsystem-test</artifactId> + <version>${version.jboss.as}</version> + <scope>test</scope> + </dependency> + </dependencies> + +</project> diff --git a/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterExtension.java b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterExtension.java new file mode 100644 index 0000000..06a300b --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterExtension.java @@ -0,0 +1,207 @@ +/* + * RHQ Management Platform + * Copyright (C) 2012 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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.helpers.rtfilter.subsystem; + +import org.jboss.as.controller.Extension; +import org.jboss.as.controller.ExtensionContext; +import org.jboss.as.controller.PathElement; +import org.jboss.as.controller.SubsystemRegistration; +import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver; +import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler; +import org.jboss.as.controller.parsing.ExtensionParsingContext; +import org.jboss.as.controller.parsing.ParseUtils; +import org.jboss.as.controller.persistence.SubsystemMarshallingContext; +import org.jboss.as.controller.registry.ManagementResourceRegistration; +import org.jboss.as.controller.registry.OperationEntry; +import org.jboss.dmr.ModelNode; +import org.jboss.staxmapper.XMLElementReader; +import org.jboss.staxmapper.XMLElementWriter; +import org.jboss.staxmapper.XMLExtendedStreamReader; +import org.jboss.staxmapper.XMLExtendedStreamWriter; + +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIBE; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR; +import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUBSYSTEM; + +/** + * A JBoss AS7 extension that configures the RHQ response-time servlet filter for all deployed webapps. + * + * @author Ian Springer + */ +public class RtFilterExtension implements Extension { + + /** + * The name space used for the {@code subsystem} element + */ + public static final String NAMESPACE = "urn:rhq:rtfilter:1.0"; + + /** + * The name of our subsystem within the model. + */ + public static final String SUBSYSTEM_NAME = "rhq-rtfilter"; + + private final SubsystemReader reader = new SubsystemReader(); + private final SubsystemWriter writer = new SubsystemWriter(); + + protected static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(SUBSYSTEM, SUBSYSTEM_NAME); + private static final String RESOURCE_NAME = RtFilterExtension.class.getPackage().getName() + ".LocalDescriptions"; + + public static final Map<String, String> INIT_PARAMS = new HashMap<String, String>(); + + public static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String keyPrefix) { + String prefix = SUBSYSTEM_NAME + (keyPrefix == null ? "" : "." + keyPrefix); + return new StandardResourceDescriptionResolver(prefix, RESOURCE_NAME, RtFilterExtension.class.getClassLoader(), + true, false); + } + + @Override + public void initializeParsers(ExtensionParsingContext context) { + context.setSubsystemXmlMapping(SUBSYSTEM_NAME, NAMESPACE, reader); + } + + @Override + public void initialize(ExtensionContext context) { + final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, 1, 0); + final ManagementResourceRegistration registration = + subsystem.registerSubsystemModel(RtFilterSubsystemDefinition.INSTANCE); + registration.registerOperationHandler(DESCRIBE, GenericSubsystemDescribeHandler.INSTANCE, + GenericSubsystemDescribeHandler.INSTANCE, false, OperationEntry.EntryType.PRIVATE); + subsystem.registerXMLElementWriter(writer); + } + + /** + * The subsystem reader, which uses STAX to read the subsystem XML. + */ + private static class SubsystemReader implements XMLStreamConstants, XMLElementReader<List<ModelNode>> { + + /** + * {@inheritDoc} + */ + @Override + public void readElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException { + INIT_PARAMS.clear(); + + // Parse the 'subsystem' element... + ParseUtils.requireNoAttributes(reader); + + list.add(createAddSubsystemOperation()); + + // Read the child elements + while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { + if (reader.getLocalName().equals("init-param")) { + readInitParam(reader); + } else { + throw ParseUtils.unexpectedElement(reader); + } + // TODO: Add support for configuring filter mappings. + } + } + + private void readInitParam(XMLExtendedStreamReader reader) throws XMLStreamException { + String id = null; + for (int i = 0; i < reader.getAttributeCount(); i++) { + if (reader.getAttributeLocalName(i).equals("id")) { + if (id != null) { + throw ParseUtils.unexpectedAttribute(reader, i); + } + id = reader.getAttributeValue(i); + } else { + throw ParseUtils.unexpectedAttribute(reader, i); + } + } + + String description = null; + String paramName = null; + String paramValue = null; + while (reader.hasNext() && reader.nextTag() != END_ELEMENT) { + if (reader.isStartElement()) { + if (reader.getLocalName().equals("description")) { + if (description != null) { + throw ParseUtils.unexpectedElement(reader); + } + description = reader.getElementText(); + } else if (reader.getLocalName().equals("param-name")) { + if (paramName != null) { + throw ParseUtils.unexpectedElement(reader); + } + paramName = reader.getElementText(); + } else if (reader.getLocalName().equals("param-value")) { + if (paramValue != null) { + throw ParseUtils.unexpectedElement(reader); + } + paramValue = reader.getElementText(); + } else { + throw ParseUtils.unexpectedElement(reader); + } + } + } + + Set<String> missingRequiredElements = new HashSet<String>(); + if (paramName == null) { + missingRequiredElements.add("param-name"); + } + if (paramValue == null) { + missingRequiredElements.add("param-value"); + } + if (!missingRequiredElements.isEmpty()) { + throw ParseUtils.missingRequiredElement(reader, missingRequiredElements); + } + + // There's no need for us to expose the init params via the AS7 management model. Just store them in a + // static Map that RtFilterDeploymentUnitProcessor will be able to access. + INIT_PARAMS.put(paramName, paramValue); + } + + private static ModelNode createAddSubsystemOperation() { + final ModelNode subsystem = new ModelNode(); + subsystem.get(OP).set(ADD); + subsystem.get(OP_ADDR).add(SUBSYSTEM, SUBSYSTEM_NAME); + return subsystem; + } + + } + + /** + * The subsystem writer, which uses STAX to write the subsystem XML. + */ + private static class SubsystemWriter implements XMLStreamConstants, XMLElementWriter<SubsystemMarshallingContext> { + + /** + * {@inheritDoc} + */ + @Override + public void writeContent(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException { + context.startSubsystemElement(RtFilterExtension.NAMESPACE, false); + writer.writeEndElement(); + } + + } + +} diff --git a/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemAdd.java b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemAdd.java new file mode 100644 index 0000000..d767e17 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemAdd.java @@ -0,0 +1,69 @@ +/* + * RHQ Management Platform + * Copyright (C) 2012 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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.helpers.rtfilter.subsystem; + +import java.util.List; + +import org.jboss.as.controller.AbstractBoottimeAddStepHandler; +import org.jboss.as.controller.OperationContext; +import org.jboss.as.controller.OperationFailedException; +import org.jboss.as.controller.ServiceVerificationHandler; +import org.jboss.as.server.AbstractDeploymentChainStep; +import org.jboss.as.server.DeploymentProcessorTarget; +import org.jboss.dmr.ModelNode; +import org.jboss.msc.service.ServiceController; + +import org.rhq.helpers.rtfilter.subsystem.deployment.RtFilterDeploymentUnitProcessor; + +/** + * Handler responsible for adding the rqh-rtfilter-subsystem resource to the model + * + * @author Ian Springer + */ +class RtFilterSubsystemAdd extends AbstractBoottimeAddStepHandler { + + static final RtFilterSubsystemAdd INSTANCE = new RtFilterSubsystemAdd(); + + private RtFilterSubsystemAdd() { + } + + /** {@inheritDoc} */ + @Override + protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException { + model.setEmptyObject(); + } + + /** {@inheritDoc} */ + @Override + public void performBoottime(OperationContext context, ModelNode operation, ModelNode model, + ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) + throws OperationFailedException { + + // Add our deployment processor + //see SubDeploymentProcessor for explanation of the phases + context.addStep(new AbstractDeploymentChainStep() { + public void execute(DeploymentProcessorTarget processorTarget) { + processorTarget.addDeploymentProcessor(RtFilterDeploymentUnitProcessor.PHASE, + RtFilterDeploymentUnitProcessor.PRIORITY, new RtFilterDeploymentUnitProcessor()); + + } + }, OperationContext.Stage.RUNTIME); + } + +} diff --git a/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemDefinition.java b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemDefinition.java new file mode 100644 index 0000000..ce5cee0 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemDefinition.java @@ -0,0 +1,45 @@ +/* + * RHQ Management Platform + * Copyright (C) 2012 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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.helpers.rtfilter.subsystem; + +import org.jboss.as.controller.SimpleResourceDefinition; +import org.jboss.as.controller.registry.ManagementResourceRegistration; + +/** + * Definition of the rhq-rtfilter-subsystem resource. + * + * @author Ian Springer + */ +public class RtFilterSubsystemDefinition extends SimpleResourceDefinition { + + public static final RtFilterSubsystemDefinition INSTANCE = new RtFilterSubsystemDefinition(); + + private RtFilterSubsystemDefinition() { + super(RtFilterExtension.SUBSYSTEM_PATH, + RtFilterExtension.getResourceDescriptionResolver(null), + RtFilterSubsystemAdd.INSTANCE, + RtFilterSubsystemRemove.INSTANCE); + } + + @Override + public void registerOperations(ManagementResourceRegistration resourceRegistration) { + super.registerOperations(resourceRegistration); + } + +} diff --git a/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemRemove.java b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemRemove.java new file mode 100644 index 0000000..242f1f1 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/RtFilterSubsystemRemove.java @@ -0,0 +1,44 @@ +/* + * RHQ Management Platform + * Copyright (C) 2012 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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.helpers.rtfilter.subsystem; + +import org.jboss.as.controller.AbstractRemoveStepHandler; +import org.jboss.as.controller.OperationContext; +import org.jboss.as.controller.OperationFailedException; +import org.jboss.dmr.ModelNode; + +/** + * Handler responsible for removing the rqh-rtfilter-subsystem resource from the model + * + * @author Ian Springer + */ +class RtFilterSubsystemRemove extends AbstractRemoveStepHandler { + + static final RtFilterSubsystemRemove INSTANCE = new RtFilterSubsystemRemove(); + + private RtFilterSubsystemRemove() { + } + + @Override + protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException { + //Remove any services installed by the corresponding add handler here + //context.removeService(ServiceName.of("some", "name")); + } + +} diff --git a/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/deployment/RtFilterDeploymentUnitProcessor.java b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/deployment/RtFilterDeploymentUnitProcessor.java new file mode 100644 index 0000000..d8bce4e --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/java/org/rhq/helpers/rtfilter/subsystem/deployment/RtFilterDeploymentUnitProcessor.java @@ -0,0 +1,141 @@ +/* + * RHQ Management Platform + * Copyright (C) 2012 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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.helpers.rtfilter.subsystem.deployment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.jboss.as.ee.structure.DeploymentType; +import org.jboss.as.ee.structure.DeploymentTypeMarker; +import org.jboss.as.server.deployment.DeploymentPhaseContext; +import org.jboss.as.server.deployment.DeploymentUnit; +import org.jboss.as.server.deployment.DeploymentUnitProcessingException; +import org.jboss.as.server.deployment.DeploymentUnitProcessor; +import org.jboss.as.server.deployment.Phase; +import org.jboss.as.web.deployment.WarMetaData; +import org.jboss.logging.Logger; +import org.jboss.metadata.javaee.spec.ParamValueMetaData; +import org.jboss.metadata.web.spec.FilterMappingMetaData; +import org.jboss.metadata.web.spec.FilterMetaData; +import org.jboss.metadata.web.spec.FiltersMetaData; +import org.jboss.metadata.web.spec.WebMetaData; + +import org.rhq.helpers.rtfilter.filter.RtFilter; +import org.rhq.helpers.rtfilter.subsystem.RtFilterExtension; + +/** + * A deployment unit processor that configures the RHQ RT filter on each WAR that is deployed. + * + * @author Ian Springer + */ +public class RtFilterDeploymentUnitProcessor implements DeploymentUnitProcessor { + + private static final String RT_FILTER_NAME = "RHQ Response-Time Filter"; + private final Logger log = Logger.getLogger(RtFilterDeploymentUnitProcessor.class); + + /** + * See {@link Phase} for descriptions of the different phases. + */ + public static final Phase PHASE = Phase.DEPENDENCIES; + + /** + * The relative order of this processor within the {@link #PHASE}. + * The current number is large enough for it to happen after all + * the standard deployment unit processors that come with JBoss AS. + */ + public static final int PRIORITY = 0x4000; + + @Override + public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { + final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); + if (isWar(deploymentUnit)) { + log.debug("Configuring RHQ response-time servlet filter for WAR " + deploymentUnit.getName() + "..."); + + final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); + WebMetaData webMetaData = warMetaData.getSharedWebMetaData(); + + FilterMetaData rtFilter = null; + FiltersMetaData filters = webMetaData.getFilters(); + if (filters != null) { + for (FilterMetaData filter : filters) { + if (RtFilter.class.getName().equals(filter.getFilterClass())) { + // the filter's already configured in this webapp. + rtFilter = filter; + break; + } + } + } else { + filters = new FiltersMetaData(); + webMetaData.setFilters(filters); + } + if (rtFilter == null) { + rtFilter = new FilterMetaData(); + rtFilter.setFilterName(RT_FILTER_NAME); + rtFilter.setFilterClass(RtFilter.class.getName()); + filters.add(rtFilter); + } + + List<ParamValueMetaData> initParams = rtFilter.getInitParam(); + if (initParams == null) { + initParams = new ArrayList<ParamValueMetaData>(); + rtFilter.setInitParam(initParams); + } + for (String paramName : RtFilterExtension.INIT_PARAMS.keySet()) { + ParamValueMetaData initParam = new ParamValueMetaData(); + initParam.setParamName(paramName); + String paramValue = RtFilterExtension.INIT_PARAMS.get(paramName); + initParam.setParamValue(paramValue); + initParams.add(initParam); + } + + boolean filterMappingAlreadyConfigured = false; + List<FilterMappingMetaData> filterMappings = webMetaData.getFilterMappings(); + if (filterMappings != null) { + for (FilterMappingMetaData filterMapping : filterMappings) { + if (filterMapping.getFilterName().equals(rtFilter.getFilterName())) { + // a mapping for the filter's already configured in this webapp. + filterMappingAlreadyConfigured = true; + break; + } + } + } else { + filterMappings = new ArrayList<FilterMappingMetaData>(); + webMetaData.setFilterMappings(filterMappings); + } + + if (!filterMappingAlreadyConfigured) { + FilterMappingMetaData filterMapping = new FilterMappingMetaData(); + filterMapping.setFilterName(rtFilter.getFilterName()); + filterMapping.setUrlPatterns(Arrays.asList("/*")); + filterMappings.add(filterMapping); + } + } + } + + @Override + public void undeploy(DeploymentUnit context) { + return; + } + + private static boolean isWar(final DeploymentUnit deploymentUnit) { + return (DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)); + } + +} diff --git a/modules/helpers/rtfilter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension b/modules/helpers/rtfilter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension new file mode 100644 index 0000000..1c3a869 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/resources/META-INF/services/org.jboss.as.controller.Extension @@ -0,0 +1 @@ +org.rhq.helpers.rtfilter.subsystem.RtFilterExtension diff --git a/modules/helpers/rtfilter-subsystem/src/main/resources/module/main/module.xml b/modules/helpers/rtfilter-subsystem/src/main/resources/module/main/module.xml new file mode 100644 index 0000000..3a2dd34 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/resources/module/main/module.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<module xmlns="urn:jboss:module:1.0" name="${moduleName}"> + + <resources> + <resource-root path="${project.build.finalName}.jar"/> + </resources> + + <dependencies> + <!-- modules required by any subsystem --> + <module name="javax.api"/> + <module name="org.jboss.staxmapper"/> + <module name="org.jboss.as.controller"/> + <module name="org.jboss.as.server"/> + <module name="org.jboss.modules"/> + <module name="org.jboss.msc"/> + <module name="org.jboss.logging"/> + <module name="org.jboss.vfs"/> + + <!-- additional modules that this subsystem depends on --> + <module name="org.jboss.metadata"/> + <module name="org.jboss.as.ee"/> + <module name="org.jboss.as.web"/> + <module name="org.rhq.helpers.rhq-rtfilter"/> + </dependencies> + +</module> diff --git a/modules/helpers/rtfilter-subsystem/src/main/resources/org/rhq/helpers/rtfilter/subsystem/LocalDescriptions.properties b/modules/helpers/rtfilter-subsystem/src/main/resources/org/rhq/helpers/rtfilter/subsystem/LocalDescriptions.properties new file mode 100644 index 0000000..e60d1d7 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/resources/org/rhq/helpers/rtfilter/subsystem/LocalDescriptions.properties @@ -0,0 +1,3 @@ +rhq-rtfilter=RHQ Response-Time Servlet Filter Subsystem +rhq-rtfilter.add=Operation Adds subsystem +rhq-rtfilter.remove=Operation Removes subsystem diff --git a/modules/helpers/rtfilter-subsystem/src/main/resources/schema/rtfilter-subsystem.xsd b/modules/helpers/rtfilter-subsystem/src/main/resources/schema/rtfilter-subsystem.xsd new file mode 100644 index 0000000..16cb468 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/resources/schema/rtfilter-subsystem.xsd @@ -0,0 +1,129 @@ +<xsd:schema + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="urn:org.rhq:rtfilter:1.0" + xmlns="urn:rhq:rtfilter:1.0" + elementFormDefault="qualified" + attributeFormDefault="unqualified" + version="1.0"> + + <!-- The subsystem root element --> + <xsd:element name="subsystem" type="subsystemType"/> + + <xsd:complexType name="subsystemType"> + xsd:sequence + <xsd:element name="init-param" + type="param-valueType" + minOccurs="0" maxOccurs="unbounded"> + xsd:annotation + xsd:documentation + The init-param element contains a name/value pair as + an initialization param of the RHQ response-time servlet filter + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + </xsd:complexType> + + <!-- **************************************************** --> + + <xsd:complexType name="param-valueType"> + xsd:annotation + xsd:documentation + This type is a general type that can be used to declare + parameter/value lists. + </xsd:documentation> + </xsd:annotation> + + xsd:sequence + <xsd:element name="description" + type="descriptionType" + minOccurs="0" + maxOccurs="unbounded"/> + <xsd:element name="param-name" + type="string"> + xsd:annotation + xsd:documentation + The param-name element contains the name of a + parameter. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + + <xsd:element name="param-value" + type="xsdStringType"> + xsd:annotation + xsd:documentation + The param-value element contains the value of a + parameter. + </xsd:documentation> + </xsd:annotation> + </xsd:element> + </xsd:sequence> + <xsd:attribute name="id" type="xsd:ID"/> + </xsd:complexType> + + <!-- **************************************************** --> + + <xsd:complexType name="descriptionType"> + xsd:annotation + xsd:documentation + + The description type is used by a description element to + provide text describing the parent element. The elements + that use this type should include any information that the + Deployment Component's Deployment File file producer wants + to provide to the consumer of the Deployment Component's + Deployment File (i.e., to the Deployer). Typically, the + tools used by such a Deployment File consumer will display + the description when processing the parent element that + contains the description. + + The lang attribute defines the language that the + description is provided in. The default value is "en" (English). + + </xsd:documentation> + </xsd:annotation> + xsd:simpleContent + <xsd:extension base="xsdStringType"> + <xsd:attribute ref="xml:lang"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + <!-- **************************************************** --> + + <xsd:complexType name="string"> + xsd:annotation + xsd:documentation + + This is a special string datatype that is defined by J2EE as + a base type for defining collapsed strings. When schemas + require trailing/leading space elimination as well as + collapsing the existing whitespace, this base type may be + used. + + </xsd:documentation> + </xsd:annotation> + xsd:simpleContent + <xsd:extension base="xsd:token"> + <xsd:attribute name="id" type="xsd:ID"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + + <!-- **************************************************** --> + + <xsd:complexType name="xsdStringType"> + xsd:annotation + xsd:documentation + This type adds an "id" attribute to xsd:string. + </xsd:documentation> + </xsd:annotation> + xsd:simpleContent + <xsd:extension base="xsd:string"> + <xsd:attribute name="id" type="xsd:ID"/> + </xsd:extension> + </xsd:simpleContent> + </xsd:complexType> + +</xsd:schema> diff --git a/modules/helpers/rtfilter-subsystem/src/main/scripts/module-assembly.xml b/modules/helpers/rtfilter-subsystem/src/main/scripts/module-assembly.xml new file mode 100644 index 0000000..5570b77 --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/main/scripts/module-assembly.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> + +<assembly> + <id>module-assembly</id> + <formats> + <format>zip</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <baseDirectory>${project.build.finalName}-module</baseDirectory> + <fileSets> + <fileSet> + <directory>${project.build.outputDirectory}/module</directory> + <outputDirectory>/org/rhq/helpers/${artifactId}</outputDirectory> + <includes> + <include>main/module.xml</include> + </includes> + <fileMode>0644</fileMode> + <directoryMode>0755</directoryMode> + </fileSet> + <fileSet> + <directory>${project.build.directory}</directory> + <outputDirectory>/org/rhq/helpers/${artifactId}/main</outputDirectory> + <includes> + <include>${project.build.finalName}.jar</include> + </includes> + <fileMode>0644</fileMode> + <directoryMode>0755</directoryMode> + </fileSet> + </fileSets> +</assembly> + diff --git a/modules/helpers/rtfilter-subsystem/src/test/java/org/rhq/helpers/rtfilter/subsystem/SubsystemXmlParsingTest.java b/modules/helpers/rtfilter-subsystem/src/test/java/org/rhq/helpers/rtfilter/subsystem/SubsystemXmlParsingTest.java new file mode 100644 index 0000000..aee7a6b --- /dev/null +++ b/modules/helpers/rtfilter-subsystem/src/test/java/org/rhq/helpers/rtfilter/subsystem/SubsystemXmlParsingTest.java @@ -0,0 +1,67 @@ +/* + * RHQ Management Platform + * Copyright (C) 2012 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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.helpers.rtfilter.subsystem; + +import org.jboss.as.subsystem.test.AbstractSubsystemBaseTest; + +import java.io.IOException; + +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +/** + * Test for parsing of the subsystem XML. + * + * @author Ian Springer + */ +@Test(enabled = false) +public class SubsystemXmlParsingTest extends AbstractSubsystemBaseTest { + + public SubsystemXmlParsingTest() { + super(RtFilterExtension.SUBSYSTEM_NAME, new RtFilterExtension()); + } + + @Override + @BeforeTest + public void initializeParser() throws Exception { + super.initializeParser(); + } + + public void testSubsystem() throws Exception { + super.testSubsystem(); + } + + @Override + @AfterTest + public void cleanup() throws Exception { + super.cleanup(); + } + + @Override + protected String getSubsystemXml() throws IOException { + return "<subsystem xmlns="" + RtFilterExtension.NAMESPACE + "">" + + "<init-param>" + + "<param-name>foo</param-name>" + + "<param-value>bar</param-value>" + + "</init-param>" + + "</subsystem>"; + } + +} diff --git a/modules/helpers/rtfilter/pom.xml b/modules/helpers/rtfilter/pom.xml index 761f3ec..6683a46 100644 --- a/modules/helpers/rtfilter/pom.xml +++ b/modules/helpers/rtfilter/pom.xml @@ -1,4 +1,6 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd%22%3E
<modelVersion>4.0.0</modelVersion>
@@ -8,16 +10,14 @@ <version>4.4.0-SNAPSHOT</version> </parent>
- <groupId>org.rhq</groupId> + <groupId>org.rhq.helpers</groupId> <artifactId>rhq-rtfilter</artifactId> - <packaging>jar</packaging>
- <name>RHQ rtfilter</name> - <description>Filter to gather response time metrics from web applcations</description> + <name>RHQ Response-Time Filter</name> + <description>a servlet filter that logs response times for HTTP requests to JEE web applications</description>
<properties> - <final.name>rhq-rtfilter</final.name> - <war.dir>${basedir}/target/${final.name}</war.dir> + <moduleName>${groupId}.${artifactId}</moduleName> </properties>
<dependencies> @@ -41,16 +41,44 @@ </dependencies>
<build> + + <resources> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + </resource> + </resources> + <plugins> + <plugin> <artifactId>maven-compiler-plugin</artifactId> - <version>2.0.2</version> <configuration> - <optimize>false</optimize> + <!-- Override what's in the root pom (1.6/1.6), since we want the filter to be deployable to + a wide array of app servers. --> <source>1.4</source> <target>1.4</target> </configuration> </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <descriptors> + <descriptor>src/main/scripts/module-assembly.xml</descriptor> + </descriptors> + </configuration> + <executions> + <execution> + <id>module-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> </build>
diff --git a/modules/helpers/rtfilter/src/main/resources/module/main/module.xml b/modules/helpers/rtfilter/src/main/resources/module/main/module.xml new file mode 100644 index 0000000..1d0075c --- /dev/null +++ b/modules/helpers/rtfilter/src/main/resources/module/main/module.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<module xmlns="urn:jboss:module:1.0" name="${moduleName}"> + + <resources> + <resource-root path="${project.build.finalName}.jar"/> + </resources> + + <dependencies> + <module name="javax.servlet.api"/> + <module name="javax.api"/> + <module name="org.apache.commons.logging"/> + </dependencies> + +</module> diff --git a/modules/helpers/rtfilter/src/main/scripts/module-assembly.xml b/modules/helpers/rtfilter/src/main/scripts/module-assembly.xml new file mode 100644 index 0000000..5570b77 --- /dev/null +++ b/modules/helpers/rtfilter/src/main/scripts/module-assembly.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> + +<assembly> + <id>module-assembly</id> + <formats> + <format>zip</format> + </formats> + <includeBaseDirectory>false</includeBaseDirectory> + <baseDirectory>${project.build.finalName}-module</baseDirectory> + <fileSets> + <fileSet> + <directory>${project.build.outputDirectory}/module</directory> + <outputDirectory>/org/rhq/helpers/${artifactId}</outputDirectory> + <includes> + <include>main/module.xml</include> + </includes> + <fileMode>0644</fileMode> + <directoryMode>0755</directoryMode> + </fileSet> + <fileSet> + <directory>${project.build.directory}</directory> + <outputDirectory>/org/rhq/helpers/${artifactId}/main</outputDirectory> + <includes> + <include>${project.build.finalName}.jar</include> + </includes> + <fileMode>0644</fileMode> + <directoryMode>0755</directoryMode> + </fileSet> + </fileSets> +</assembly> +
rhq-commits@lists.fedorahosted.org