Custom event plugin
helpneeded Jul 18, 2011 2:52 PMHi, everyone,
I am new to RHQ and have run into a problem creating a custom plugin that monitors log file output.
I keep getting this error (Please note that I changed some of the text fields to be generic names and removed the package line that was at the top of each java file):
"An unexpected error occurred in the Agent. Cause: org.rhq.core.clientapi.agent.PuginContainerException: The [text] plugin does not properly support manual addition of [text] Resources."
I am using RHQ 3.0.0.
Here is my rhq-plugin.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<plugin name="plugin2" displayName="plugin2"
description="Counts files in a directory" package="plugin2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:xmlns:rhq-plugin"
xmlns:c="urn:xmlns:rhq-configuration">
<service name="plugin service 2" discovery="CountDiscovery" class="CountComponent"
singleton="false" supportsManualAdd="true">
<plugin-configuration>
<c:simple-property name="directory" displayName="Directory To Monitor"
required="true"
description="A file path to monitor for the number of files. Example: C:\Temp" />
</plugin-configuration>
<operation name="dummyOperation" displayName="dummyOperation"
description="Purges all files from the directory.">
<results>
<c:simple-property name="totalFiles" description="Total number of files." />
<c:simple-property name="totalFilesDeleted"
description="Number of files deleted." />
<c:simple-property name="totalFilesRemain"
description="Number of files unable to delete." />
</results>
</operation>
<metric property="dummyMetric" displayName="dummyMetric"
dataType="trait" displayType="summary" defaultOn="true" defaultInterval="120000" />
<event name="RHEVMDummyEvent" />
</service>
</plugin>
The CountComponent looks like this:
import java.util.HashSet;
import java.util.Set;
import java.io.File;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
import org.rhq.core.pluginapi.inventory.CreateChildResourceFacet;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.core.pluginapi.inventory.DeleteResourceFacet;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.event.EventContext;
import org.rhq.core.pluginapi.operation.OperationContext;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.core.pluginapi.plugin.PluginContext;
import org.rhq.core.pluginapi.plugin.PluginLifecycleListener;
import org.rhq.core.pluginapi.support.SnapshotReportRequest;
import org.rhq.core.pluginapi.support.SnapshotReportResults;
import org.rhq.core.pluginapi.support.SupportFacet;
public class CountComponent implements ResourceComponent
, MeasurementFacet
, OperationFacet
, ConfigurationFacet
, CreateChildResourceFacet
, DeleteResourceFacet
, PluginLifecycleListener
, SupportFacet
{
private final Log log = LogFactory.getLog(this.getClass());
private static final int CHANGEME = 1; // TODO remove or change this
private File dir;
public static final String DUMMY_EVENT = "RHEVMDummyEvent"; // Same as in Plugin-Descriptor
EventContext eventContext;
/**
* Callback when the plugin is created
* @see org.rhq.core.pluginapi.plugin.PluginLifecycleListener#initialize(PluginContext)
*/
public void initialize(PluginContext context) throws Exception
{
}
/**
* Callback when the plugin is unloaded
* @see org.rhq.core.pluginapi.plugin.PluginLifecycleListener#shutdown()
*/
public void shutdown()
{
}
/**
* Return availability of this resource
* @see org.rhq.core.pluginapi.inventory.ResourceComponent#getAvailability()
*/
public AvailabilityType getAvailability() {
// TODO supply real implementation
return AvailabilityType.UP;
}
/**
* Start the resource connection
* @see org.rhq.core.pluginapi.inventory.ResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext)
*/
public void start(ResourceContext context) throws InvalidPluginConfigurationException, Exception {
Configuration conf = context.getPluginConfiguration();
// TODO add code to start the resource / connection to it
dir = new File(context.getResourceKey());
eventContext = context.getEventContext();
RHEVMEventPoller eventPoller = new RHEVMEventPoller();
eventContext.registerEventPoller(eventPoller, 60);
}
/**
* Tear down the rescource connection
* @see org.rhq.core.pluginapi.inventory.ResourceComponent#stop()
*/
public void stop() {
eventContext.unregisterEventPoller(DUMMY_EVENT);
}
/**
* Gather measurement data
* @see org.rhq.core.pluginapi.measurement.MeasurementFacet#getValues(org.rhq.core.domain.measurement.MeasurementReport, java.util.Set)
*/
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
for (MeasurementScheduleRequest req : metrics) {
if (req.getName().equals("dummyMetric")) {
// MeasurementDataNumeric res = new MeasurementDataNumeric(req, Double.valueOf(CHANGEME));
// report.addData(res);
}
// TODO add more metrics here
}
}
public void startOperationFacet(OperationContext context) {
}
/**
* Invokes the passed operation on the managed resource
* @param name Name of the operation
* @param params The method parameters
* @return An operation result
* @see org.rhq.core.pluginapi.operation.OperationFacet
*/
public OperationResult invokeOperation(String name, Configuration params) throws Exception {
OperationResult res = new OperationResult();
if ("dummyOperation".equals(name)) {
// TODO implement me
}
return res;
}
/**
* Load the configuration from a resource into the configuration
* @return The configuration of the resource
* @see org.rhq.core.pluginapi.configuration.ConfigurationFacet
*/
public Configuration loadResourceConfiguration()
{
// TODO supply code to load the configuration from the resource into the plugin
return null;
}
/**
* Write down the passed configuration into the resource
* @param report The configuration updated by the server
* @see org.rhq.core.pluginapi.configuration.ConfigurationFacet
*/
public void updateResourceConfiguration(ConfigurationUpdateReport report)
{
// TODO supply code to update the passed report into the resource
}
/**
* Create a child resource
* @see org.rhq.core.pluginapi.inventory.CreateChildResourceFacet
*/
public CreateResourceReport createResource(CreateResourceReport report)
{
// TODO supply code to create a child resource
return null; // TODO change this
}
/**
* Delete a child resource
* @see org.rhq.core.pluginapi.inventory.DeleteResourceFacet
*/
public void deleteResource() throws Exception
{
// TODO supply code to delete a child resource
}
/**
* Takes a snapshot and returns the snapshot report content in the given stream. A facet implementation
* can support different kinds of snapshots, the given name determines which kind of snapshot to take.
*
* @param request identifies the type of snapshot to take
* @return snapshot results, including a stream containing the contents of the snapshot report
* @throws Exception if failed to generate the snapshot report
*/
public SnapshotReportResults getSnapshotReport(SnapshotReportRequest request) throws Exception
{
// TODO
return null;
}
}
The Discovery looks like this:
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ManualAddFacet;
import org.rhq.core.pluginapi.inventory.ProcessScanResult;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent;
import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext;
/**
* Discovery class
*/
public class CountDiscovery implements ResourceDiscoveryComponent
,ManualAddFacet
{
private final Log log = LogFactory.getLog(this.getClass());
/**
* This method is an empty dummy, as you have selected manual addition
* in the plugin generator.
* If you want to have auto discovery too, remove the "return emptySet"
* and implement the auto discovery logic.
*/
public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext discoveryContext) throws Exception {
return Collections.emptySet();
}
/**
* Do the manual add of this one resource
*/
public DiscoveredResourceDetails discoverResource(Configuration pluginConfiguration, ResourceDiscoveryContext context) throws InvalidPluginConfigurationException {
// TODO implement this
DiscoveredResourceDetails detail = null; // new DiscoveredResourceDetails(
// context.getResourceType(), // ResourceType
// );
return detail;
}
}
And the RHEVMEventPoller looks like this:
import java.util.HashSet;
import java.util.Set;
import org.rhq.core.domain.event.Event;
import org.rhq.core.domain.event.EventSeverity;
import org.rhq.core.pluginapi.event.EventPoller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class RHEVMEventPoller implements EventPoller {
private final Log log = LogFactory.getLog(this.getClass());
public RHEVMEventPoller() {
}
/** Return the type of events we handle
* @see org.rhq.core.pluginapi.event.EventPoller#getEventType()
*/
public String getEventType() {
return CountComponent.DUMMY_EVENT;
}
/** Return collected events
* @see org.rhq.core.pluginapi.event.EventPoller#poll()
*/
public Set<Event> poll() {
Set<Event> eventSet = new HashSet<Event>();
// TODO add your events here. Below is an example that
/*
synchronized (events) {
eventSet.addAll(events);
events.clear();
}
*/
log.warn("Polling Polling");
return eventSet;
}
}
Thanks in advance,
Sara