modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java | 13 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java | 2 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ScheduledJobInvocationContext.java | 12 modules/enterprise/server/plugins/cloud/pom.xml | 146 ++++++++++ modules/enterprise/server/plugins/cloud/src/main/java/org/rhq/enterprise/server/plugins/cloud/CloudServerPluginComponent.java | 36 ++ modules/enterprise/server/plugins/cloud/src/main/resources/META-INF/rhq-serverplugin.xml | 42 ++ 6 files changed, 249 insertions(+), 2 deletions(-)
New commits: commit c83a6cf9bd4043fd737be5b2d14ff4ec27507839 Author: John Sanda jsanda@redhat.com Date: Tue Sep 21 21:46:32 2010 -0400
Adding ability for plugin jobs to persist data across invocations of jobs
Server plugin scheduled jobs previously had no mechanism provided by the plugin framework for persisting data across invocations of the job. Quartz however provides this capability when using a StatefulJob. Server plugin jobs run as StatefulJob objects when they do not run concurrently. The only change needed then was to expose a hook to the JobDataMap. A map has been added to ScheduledJobInvocationContext which comes from the JobDataMap. Anything added to this map by the server plugin job will be persisted from invocation of the job to the next.
Initial commit for cloud plugin which at this point is just testing that persisting job data works as expected.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java index 19c8eb8..974cc4d 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractJobWrapper.java @@ -19,13 +19,17 @@
package org.rhq.enterprise.server.plugin.pc;
+import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Date; +import java.util.Map; import java.util.Properties;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.Job; import org.quartz.JobDataMap; +import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException;
@@ -109,6 +113,12 @@ abstract class AbstractJobWrapper implements Job { public static final String DATAMAP_IS_CLUSTERED = DATAMAP_LEADER + "isClustered";
/** + * Key to the data map to a map where the plugin job can store data that it wants + * to persist across invocations of the job. + */ + public static final String DATAMAP_PLUGIN_JOB_DATA = DATAMAP_LEADER + "pluginJobData"; + + /** * This is the method that quartz calls when the schedule has triggered. This method will * delegate to the plugin component that is responsible to do work for the plugin. * @@ -229,7 +239,8 @@ abstract class AbstractJobWrapper implements Job { ScheduledJobDefinition jobDefinition = new ScheduledJobDefinition(jobId, true, jobClass, jobMethodName, scheduleType, callbackData); ServerPluginContext pluginContext = pluginManager.getServerPluginContext(pluginEnv); - params[0] = new ScheduledJobInvocationContext(jobDefinition, pluginContext, pluginComponent); + params[0] = new ScheduledJobInvocationContext(jobDefinition, pluginContext, pluginComponent, + (Map<String, Serializable>)dataMap.get(DATAMAP_PLUGIN_JOB_DATA)); } catch (NoSuchMethodException e) { try { // see if there is a no-arg method of the given name diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java index b8e760c..bfaae58 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/AbstractTypeServerPluginContainer.java @@ -19,6 +19,7 @@
package org.rhq.enterprise.server.plugin.pc;
+import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -457,6 +458,7 @@ public abstract class AbstractTypeServerPluginContainer { jobData.putAsString(AbstractJobWrapper.DATAMAP_IS_CONCURRENT, schedule.getScheduleType().isConcurrent()); jobData.putAsString(AbstractJobWrapper.DATAMAP_IS_CLUSTERED, schedule.getScheduleType().isClustered()); jobData.put(AbstractJobWrapper.DATAMAP_JOB_METHOD_NAME, schedule.getMethodName()); + jobData.put(AbstractJobWrapper.DATAMAP_PLUGIN_JOB_DATA, new HashMap<String, Serializable>()); if (schedule.getClassName() != null) { jobData.put(AbstractJobWrapper.DATAMAP_JOB_CLASS, schedule.getClassName()); } diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ScheduledJobInvocationContext.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ScheduledJobInvocationContext.java index cdb0ebf..81cd7c5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ScheduledJobInvocationContext.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ScheduledJobInvocationContext.java @@ -19,6 +19,10 @@
package org.rhq.enterprise.server.plugin.pc;
+import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + import org.rhq.enterprise.server.xmlschema.ScheduledJobDefinition;
/** @@ -32,12 +36,14 @@ public class ScheduledJobInvocationContext { private final ScheduledJobDefinition jobDefinition; private final ServerPluginContext serverPluginContext; private final ServerPluginComponent serverPluginComponent; + private Map<String, Serializable> properties;
public ScheduledJobInvocationContext(ScheduledJobDefinition jobDefinition, ServerPluginContext pluginContext, - ServerPluginComponent serverPluginComponent) { + ServerPluginComponent serverPluginComponent, Map<String, Serializable> properties) { this.jobDefinition = jobDefinition; this.serverPluginContext = pluginContext; this.serverPluginComponent = serverPluginComponent; + this.properties = properties; }
/** @@ -68,4 +74,8 @@ public class ScheduledJobInvocationContext { public ServerPluginComponent getServerPluginComponent() { return serverPluginComponent; } + + public Map<String, Serializable> getProperties() { + return properties; + } } diff --git a/modules/enterprise/server/plugins/cloud/pom.xml b/modules/enterprise/server/plugins/cloud/pom.xml new file mode 100644 index 0000000..8d10fcd --- /dev/null +++ b/modules/enterprise/server/plugins/cloud/pom.xml @@ -0,0 +1,146 @@ +<?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"> + + <parent> + <groupId>org.rhq</groupId> + <artifactId>rhq-enterprise-server-plugins-parent</artifactId> + <version>3.0.1-SNAPSHOT</version> + </parent> + + <modelVersion>4.0.0</modelVersion> + + <groupId>org.rhq</groupId> + <artifactId>rhq-serverplugin-cloud</artifactId> + + <name>RHQ Enterprise Server Cloud Plugin</name> + + <scm> + <connection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/cloud/</connection> + <developerConnection>scm:git:ssh://git.fedorahosted.org/git/rhq.git/modules/enterprise/server/plugins/cloud/</developerConnection> + </scm> + + <properties> + <scm.module.path>modules/enterprise/server/plugins/cloud/</scm.module.path> + <cobber4j.version>0.1</cobber4j.version> + </properties> + + <dependencies> + </dependencies> + + <build> + <plugins> + + <!-- + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.0</version> + <executions> + <execution> + <id>copy-libs</id> + <phase>process-resources</phase> + <goals> + <goal>copy</goal> + </goals> + <configuration> + <artifactItems> + </artifactItems> + <outputDirectory>${project.build.outputDirectory}/lib</outputDirectory> + </configuration> + </execution> + </executions> + </plugin> + --> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <excludedGroups>${rhq.testng.excludedGroups}</excludedGroups> + <!-- + <argLine>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y</argLine> + --> + </configuration> + </plugin> + + </plugins> + </build> + + <profiles> + + <profile> + <id>dev</id> + + <properties> + <rhq.rootDir>../../../../..</rhq.rootDir> + <rhq.containerDir>${rhq.rootDir}/${rhq.defaultDevContainerPath}</rhq.containerDir> + <rhq.deploymentDir>${rhq.containerDir}/jbossas/server/default/deploy/${rhq.earName}/rhq-serverplugins</rhq.deploymentDir> + </properties> + + <build> + <plugins> + + <plugin> + <artifactId>maven-antrun-plugin</artifactId> + <version>1.1</version> + <executions> + + <execution> + <id>deploy</id> + <phase>compile</phase> + <configuration> + <tasks> + <mkdir dir="${rhq.deploymentDir}" /> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating ${deployment.file}...</echo> + <jar destfile="${deployment.file}" basedir="${project.build.outputDirectory}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>undeploy</id> + <phase>clean</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Deleting ${deployment.file}...</echo> + <delete file="${deployment.file}" /> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + <execution> + <id>deploy-jar-meta-inf</id> + <phase>package</phase> + <configuration> + <tasks> + <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" /> + <echo>*** Updating META-INF dir in ${deployment.file}...</echo> + <unjar src="${project.build.directory}/${project.build.finalName}.jar" dest="${project.build.outputDirectory}"> + <patternset> + <include name="META-INF/**" /> + </patternset> + </unjar> + <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF" update="true"> + </jar> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + + </executions> + </plugin> + + </plugins> + </build> + </profile> + + </profiles> +</project> diff --git a/modules/enterprise/server/plugins/cloud/src/main/java/org/rhq/enterprise/server/plugins/cloud/CloudServerPluginComponent.java b/modules/enterprise/server/plugins/cloud/src/main/java/org/rhq/enterprise/server/plugins/cloud/CloudServerPluginComponent.java new file mode 100644 index 0000000..e2aac5a --- /dev/null +++ b/modules/enterprise/server/plugins/cloud/src/main/java/org/rhq/enterprise/server/plugins/cloud/CloudServerPluginComponent.java @@ -0,0 +1,36 @@ +package org.rhq.enterprise.server.plugins.cloud; + +import java.io.Serializable; +import java.util.Map; + +import org.rhq.enterprise.server.plugin.pc.ScheduledJobInvocationContext; +import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent; +import org.rhq.enterprise.server.plugin.pc.ServerPluginContext; + +public class CloudServerPluginComponent implements ServerPluginComponent { + + public void initialize(ServerPluginContext context) throws Exception { + } + + public void start() { + } + + public void stop() { + } + + public void shutdown() { + } + + public void syncServerEndpoints(ScheduledJobInvocationContext context) { + Map<String, Serializable> jobProperties = context.getProperties(); + + if (!jobProperties.containsKey("counter")) { + jobProperties.put("counter", 1); + return; + } + + Integer counter = (Integer)jobProperties.get("counter"); + System.out.println("CURRENT COUNT: " + counter); + jobProperties.put("counter", counter + 1); + } +} diff --git a/modules/enterprise/server/plugins/cloud/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/cloud/src/main/resources/META-INF/rhq-serverplugin.xml new file mode 100644 index 0000000..fd3b2f9 --- /dev/null +++ b/modules/enterprise/server/plugins/cloud/src/main/resources/META-INF/rhq-serverplugin.xml @@ -0,0 +1,42 @@ +<generic-plugin name="CloudServerPlugin" + displayName="Cloud" + description="" + package="org.rhq.enterprise.server.plugins.cloud" + disabledOnDiscovery="false" + xmlns="urn:xmlns:rhq-serverplugin.generic" + xmlns:serverplugin="urn:xmlns:rhq-serverplugin" + xmlns:c="urn:xmlns:rhq-configuration"> + <serverplugin:plugin-component class="CloudServerPluginComponent"> + </serverplugin:plugin-component> + + serverplugin:scheduled-jobs + <c:map-property name="syncServerEndpoints"> + <c:simple-property name="scheduleType" + type="string" + required="true" + default="cron" + summary="true" + description="Indicates the type of trigger this synchronize job will use"> + <c:property-options> + <c:option value="periodic" default="true"/> + <c:option value="cron"/> + </c:property-options> + </c:simple-property> + <c:simple-property name="scheduleTrigger" default="300000"/> + <c:simple-property name="concurrent" + type="boolean" + required="true" + default="false" + summary="false" + readOnly="true" + description="This must always be false - only want one sync job running at a time"/> + <c:simple-property name="clustered" + type="boolean" + required="true" + default="false" + summary="false" + readOnly="true" + description="This must always be false"/> + </c:map-property> + </serverplugin:scheduled-jobs> +</generic-plugin> \ No newline at end of file
rhq-commits@lists.fedorahosted.org