Discovery component classes are classes that plugin developers write to detect resources that can be managed. A discovery component is called by the plugin container. When the discovery component discovers one or more resources, it will return details about that newly discovered resource. The plugin container will provide this information to the server which then provides the user the ability to commit those resources into inventory.
Plugin developers now have a way to "intercept" details from newly discovered resources that are returned from discovery components. This allows a plugin to intercept details coming from its own discovery components or coming from discovery components from dependent plugins.
A plugin defines a "discovery callback" in the descriptor. The metadata includes the resource type whose discovery is to be intercepted and it includes the classname of the discovery callback implementation. An example:
The plugin that owns this descriptor must provide the class "SomeDiscoveryCallback" which implements the new plugin API interface org.rhq.core.pluginapi.inventory.ResourceDiscoveryCallback. That callback will be invoked every time the discovery component for that resource type ("Some Resource Type" from the plugin "somePluginName") returns details about newly discovered resource(s).
The callback can do several things when it is called:
It can ignore the details (that is, do nothing to the details that are passed into it, in effect, be a no-op). This is usually the case when the callback does not recognize the discovered resource. In this case, the callback will return DiscoveryCallbackResults.UNPROCESSED.
Or the callback can opt to tweek the details if the callback sees that the discovered resource details needs to have additional or different data associated with it, compared to the data that the original discovery component found. If a callback decides that it has identified details that it wants to alter, it must return DiscoveryCallbackResults.PROCESSED letting the plugin container know that the callback identified the discovered resource and altered the details. Note that if more than one callback has altered the details, the plugin container will log an error and abort the discovery of that resource. In the current implementation, this means only one callback is allowed to change discovered details and return PROCESSED. [Note: You can turn this behavior off (that is, you can allow multiple callbacks to alter details for the same discovered resource and return PROCESSED) by starting the agent with the system property "rhq.agent.discovery-callbacks.never-abort" set to "true".]
Lastly, the callback can opt to veto (that is, reject) a discovered resource. If the callback returns DiscoveryCallbackResults.VETO that resource will not make it into inventory. A VETO means the plugin container will ignore that discovered resource and skip it regardless of what any other callback does. The newly discovered resource's information will not be sent up to the server and it will not make it into inventory.
You can define a <type-callback> on a type defined in the same plugin descriptor where it, itself, is defined. A callback can also be defined in one plugin, which the resource type discovery it is intercepting was in another plugin.
|You should only define callbacks on types that are in your plugin's dependency tree. Things may not work if you try to intercept arbitrary resource type discoveries for types defined in any plugin not in your plugin's dependency tree. I have a feeling we are going to run into problems if you try to intercept discovery details for plugins that are not related to the plugin where the callback was defined. This is due to potential class loader issues. If your callback doesn't need to connect to the remote resource that was just discovered, this caveat doesn't apply probably. But if your callback needs to talk to the newly discovered resource, you'll probably need to ensure the resource type's plugin is a dependency of the callback's plugin (and it probably will need useClasses='true').|
For a layered plugin that would run on top of the as7-plugin, this layered plugin could have a descriptor: