Search

4.2. The Breakdown of Agent Plug-in Configuration

download PDF
Agents do not have a fixed functionality; their functions, from monitoring to the resources they can inventory, are defined by their plug-ins.
At its core, an agent plug-in consists of a single JAR file and an XML plug-in descriptor file (rhq-plugin.xml inside the META-INF/ directory).
Along with the plug-in descriptor, an agent plug-in has up to three different types of Java files for each plug-in defined in the JAR file package:
  • A plug-in component file that contains all of the code for the plug-in functionality
  • A *Discovery.java file that configures the discovery process for the resources defined in the plug-in
  • A *EventPoller.java that defines the events that can be collected by the resource
The definitions in the Java files closely track the configuration for the plug-in in the rhq-plugin.xml plug-in descriptor.
TIP
Generating an agent plug-in template with the plug-in generator creates files with TODO markers to help guide writing the plug-in.

4.2.1. Schema Files

The agent plug-in is defined through its metadata and configuration in its XML plug-in descriptor file. The configuration elements that are available to the descriptor are defined in the XML schema definition (XSD) files for agent plug-ins.
All JBoss ON plug-ins — both agent plug-ins and server-side plug-ins — uses the rhq-configuration.xsd file to define the basic configuration options available.
Agents also use the rhq-plugin.xsd file, which extends the rhq-configuration.xsd schema and adds additional elements specifically for resource-related plug-ins.
Note
More information about specific elements within both XSD files is available through the comments (in <xs:annotation> items) in the XSD files themselves.
The rhq-configuration.xsd file provides schema which is available for all JBoss ON plug-ins. The rhq-configuration.xsd file is in source/modules/core/client-api/src/main/resources.
The most commonly used elements defined in the rhq-configuration schema relate to setting configuration values for a plug-in, like <simple-property> and <map-property>.
Table 4.1. rhq-configuration.xsd Schema Elements
Element Description
configuration-property For adding a configuration attribute to a plug-in for user-defined settings.
simple-property For setting a default configuration value.
option For setting whether a property's values come from an enumerated list (false) or can be anything defined by the user (true).
The rhq-configuration.xsd file also defines the most common flags that can be used for the plug-in descriptor, including the required name and optional displayName attributes.
Table 4.2. rhq-configuration.xsd Schema Attributes
Attribute Description
name Required. Gives a unique name for the plug-in.
displayName Gives the name to use for the plug-in in the GUI. If this isn't given, then the name value is used.
description Gives a short description of the plug-in.
The rhq-plugin.xsd provides all of the schema elements specifically for agent plug-ins. The rhq-plugin.xsd file is in the source/modules/core/client-api/src/main/resources directory.
The most common elements in the rhq-plugin.xsd file are listed in Table 4.3, “rhq-plugin.xsd Schema Elements”.
Table 4.3. rhq-plugin.xsd Schema Elements
Element Description
plugin Contains the root element for the plug-in descriptor.
depends Identifies any other plug-ins which this plug-in requires or extends.
platforms, servers, services Identifies the type for a resource defined within the agent plug-in. <platforms> are top-level elements, but <servers> and <services> are added as children of platforms or other server and service resources.
metric
An element within a platform, server, or service which defines metrics which can be collected for that resource type.
Child elements and attributes for this resource element are listed in the rhq-plugin.xsd file.
Values that form part of a larger data structure, such as an array of values, need to be deconstructed into individual values before they can be monitored.
event An element within a platform, server, or service which defines whether that resource supports events. There are no other configuration properties with events; the events themselves are culled from the resource's log files.
bundle-target
Configures whether and how bundles can be deployed to a resource.
Child elements and attributes for this resource element are listed in the rhq-plugin.xsd file.
drift-definition
Configures whether and how drift monitoring can be performed for a resource.
Child elements and attributes for this resource element are listed in the rhq-plugin.xsd file.
resource-configuration
Defines a configuration property for a resource type.
Child elements and attributes for this resource element are listed in the rhq-plugin.xsd file.
operation
Defines an operation that can be performed on that resource type.
Child elements and attributes for this resource element are listed in the rhq-plugin.xsd file.
content
Configures what types of packages can be uploaded or deployed on a resource type.
Child elements and attributes for this resource element are listed in the rhq-plugin.xsd file.
Most of the attributes defined within the rhq-plugin.xsd contain flags that are used within the root element of the plug-in descriptor. These add additional management attributes for controlling the release and updates of agent plug-ins.
Table 4.4. rhq-plugin.xsd Schema Attributes
Attribute Description
package For setting the plug-in package name.
version For setting the version of the plug-in. This must be in an OSGi-compatible format.
ampsVersion For the agent plug-in system version that this plug-in requires. This must be in an OSGi-compatible format.
pluginLifecycleListener For the listener which initializes and shuts down the plug-in.
discovery Sets whether a resource type is detected by discovery scans. This flag may not be necessary for child resources that will be discovered by the parent resource.
There are many other elements and attributes set in the rhq-plugin.xsd file. Each one is described by the text in the <xs:annotation> tags for the item.

4.2.2. Descriptor and Configuration

A plug-in descriptor contains the metadata that described everything about the plug-in and the resource it configured. The descriptor describes the type and interactions of the resource type the agent plug-in defines.
The plug-in descriptor contains the information about name of the resource, the supported resource versions, the total resource hierarchy (meaning parents or children of the resource), configuration properties that the agent uses to connect to the resource, and all of the monitoring metrics, operations, and events related to the resource that can be managed by the agent.
The plug-in descriptor also contains information about the plug-in itself.
A resource definition in a plug-in descriptor can be a platform, server, or service. Multiple resources can be defined in a single plug-in descriptor; one resource is the root (parent) element, and the rest of the resources defines are its children.
Because the plug-in descriptor is an XML file, it follows a clear and structured schema definition. The schema definitions are what allow the plug-in descriptor to expose the resource's management interfaces to JBoss ON.
The plug-in descriptor, at a minimum, defines the resource type. Past that, it defines the different aspects of the resource that JBoss ON can manage:
  • The names of the resource types (servers and services) supported by the plug-in
  • Any configuration settings that the agent's plug-in components use to connect to the resource
  • Any metrics (measurement definitions) to use to monitor the resource; this depends on the type of data issued by the resource itself.
  • A set of operations that can be invoked on the resource. This is commonly start and stop operations, but it can include application-specific operations or other actions, like running a script.
  • Resource configuration values that can be edited in the actual configuration of the resource.
    The plug-in configuration tells the components how to connect to the resource. The resource configuration, on the other hand, are settings in the resource itself that can be edited externally.
  • Any child resources that are part of the resource hierarchy. For example, a JBoss server has data source services running within them, so the data source services are defined in the JBoss server resource plug-in, as a child resource of the JBoss server.

4.2.2.1. Resource Type, Metadata, and Plug-in Configuration

The top element in an agent plug-in is the <plugin> element.
<plugin name="JMX"
        displayName="Generic JMX"
        package="org.rhq.plugins.jmx"
        description="Supports management of JMX MBean Servers via various remoting systems."
        ampsVersion="2.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="urn:xmlns:rhq-plugin"
        xmlns:c="urn:xmlns:rhq-configuration">
Several attributes on this element are important:
  • name and displayName give the internal and GUI name of the plug-in.
  • ampsVersion gives the version number of the plug-in itself.
  • package gives the name of the classes used by the components in the plug-in.
The next element in the plug-in descriptor defines the root resource that is defined by the plug-in. This can be <platform>, <server>, or <service>.
One or multiple resources can be defined in a plug-in descriptor. The plug-in descriptor not only defines those resource types, but it organizes those types in a parent-child hierarchy. For example, a JBoss EJB service only runs inside of a JBoss server, so the EJB service resource type should logically be a child type of the JBoss server resource type.
The hierarchy is defined by nesting <service> resource definitions inside <server> (or other <service>) resource definitions.
   <server name="JMX Server" discovery="JMXDiscoveryComponent" class="JMXServerComponent"
           description="Generic JMX Server"
	   supportsManualAdd="true" createDeletePolicy="neither">
IMPORTANT
Do not rename resource types when you edit the resource plug-in. This breaks backward compatibility with any resource that was inventoried using the older version of the plug-in.
Two of the attributes are related to the Java resource files associated with the plug-in:
  • discovery identifies the discovery component used to identify the resource type.
  • class identifies the plug-in component which contains the actual code of the plug-in.
Two of the attributes define how resources of that type are added to the inventory:
  • supportsManualAdd allows resources to be added to the inventory by administrators.
  • createDeletePolicy sets whether children can be added or removed manually from inventory.
The last part that relates to configuring the plug-in is setting (optional) plug-in configuration properties. These are flexible and can define anything related to the information required to identify or set up a resource which matches the resource type in the plug-in, even setting constraints on allowed values or templates to define default settings.
<plugin-configuration>
  <c:list-property name="Servers">
     <c:map-property name="OneServer">
        <c:simple-property name="host"/>
        <c:simple-property name="port">
           <c:integer-constraint 
              minimum="0"
              maximum="65535"/> 
        </c:simple-property>
        <c:simple-property name="protocol">
           <c:property-options>
              <c:option value="http" default="true"/>
              <c:option value="https"/>
           </c:property-options>
        </c:simple-property>
     </c:map-property>
  </c:list-property>
</plugin-configuration>
The port has a constraint so, the GUI can validate the input being between 0 and 65535. The protocol can be selected from a list of drop-down menu items, with a default value of HTTP.
There are three types of properties:
  • <simple-property>, which defines a one key-value pair
  • <map-property>, which defines multiple key-value pairs related to a single entity, following the java.util.Map concept
  • <list-property>, which contains a list of properties
Both <map-property> and <list-property> define groups of <simple-property> element. Additionally, these properties can be formally grouped together under <group> element. Using a <group> element creates a collapsible configuration ares in the UI.
Templates can preset some configuration properties.
         <c:template name="JDK 5" description="Connect to JDK 5">
            <c:simple-property name="type" default="org.mc4j.ems.connection.support.metadata.J2SE5ConnectionTypeDescriptor"/>
            <c:simple-property name="connectorAddress" default="service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi"/>
         </c:template>

4.2.2.2. Discovery and Process Scans

The central functionality of JBoss ON is the inventory. Each resource must be present in that inventory, so the plug-in descriptor has to define how resources are detected and how they are added to inventory. This is done through the discovery component.
The <plugin> element has a discovery attribute which identifies the discovery Java file for the resource plug-in. (If there are multiple resources defined in the plug-in, then there will be multiple discovery components.)
When the agent plug-in is generated using the plug-in generator, it creates the appropriate template to add the discovery requirements. The discovery component has to have the information to find a resource instance and to assign a unique identifier to that resource.
/**
 * Discovery class
 */
public class testDiscovery implements ResourceDiscoveryComponent
,ManualAddFacet
{

    private final Log log = LogFactory.getLog(this.getClass());

      /**
       * 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;
      }
}
Identifying resource instances is a critical part of maintaining the inventory. Any resource must be unique and must be consistently identified between discovery scans . Agents identify resources by constructing a unique resource key. A resource key varies by resource type. Whatever the key is, it has to intrinsic to the resources and detectable for the agent. Keys do not have to be globally unique, but they must be unique beneath a parent resource. For a JMX server, the resource key is its connector address, which is unique to the instance.
    public DiscoveredResourceDetails discoverResource(Configuration pluginConfig,
                                                      ResourceDiscoveryContext discoveryContext)
            throws InvalidPluginConfigurationException {
        // TODO: Connect to the remote JVM to verify the user-specified conn props are valid, and if connecting
        // fails, throw an exception.
        String resourceKey = pluginConfig.getSimpleValue(CONNECTOR_ADDRESS_CONFIG_PROPERTY, null);
        String connectionType = pluginConfig.getSimpleValue(CONNECTION_TYPE, null);
                            
        // TODO (ips, 09/04/09): We should connect to the remote JVM in order to obtain its version.
        String version = null;
                    
        DiscoveredResourceDetails resourceDetails = new DiscoveredResourceDetails(discoveryContext.getResourceType(),
                resourceKey, "Java VM", version, connectionType + " [" + resourceKey + "]", pluginConfig, null);
        return resourceDetails;
    }  
Optional dependencies can affect discovery. Embedded plug-ins copy the child type from the source plug-in, and then use the embedded plug-in's discovery component to run the discovery. Injected plug-ins take a parent resource and cycle through all potential children resource types and run a discovery for each type, injecting the parent component into each child type's discovery method.
Often, resources are processes running on the local machine. The JBoss ON agent can query the process table to detect those local processes. This is first defined in the plug-in descriptor using a <process-scan> element and then implemented in the discovery component.
Each resource type defined in the plug-in descriptor can have a <process-scan> child element. The <process-scan> element itself is empty, but has two required attributes: name and query. name identifies the specific scan method. query is the attribute that does something. The query is a string written in Process Info Query Language (PIQL). This value is used to search for the process.
The sourceforge PIQL API docs provide much more information on the syntax of PIQL queries.
The basic format of a PIQL process scan query is a three-part term which looks for the process, some kind of identifying marker, and then the value to match.
process|attribute|match=value,arg|attribute|match=value
For a process scan for discovery, the scan will usually look for a process name or a PID file.
Looking for a process by name can require additional attributes to help narrow the search down to a specific type of resource or even a specific instance. For example, a JBoss AS instance has a process name that starts with java and an argument with the value org.jboss.Main. The ps information contains both of those attributes.
jsmith     2035   0.0 -1.5   724712  30616  p7  S+    9:49PM   0:01.61 java  
 -Dprogram.name=run.sh -Xms128m -Xmx512m -Dsun.rmi.dgc.client.gcInterval=3600000
 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.platform.mbeanserver
 -Djava.endorsed.dirs=/devel/jboss-4.0.5.GA/lib/endorsed
 -classpath /devel/jboss-4.0.5.GA/bin/run.jar:/lib/tools.jar
 org.jboss.Main -c minimal
The PIQL query, then attempts to match the process name, using the basename query attribute, with a matching argument, defined in the arg query attribute.
process|attribute|match=value,arg|attribute|match=value
   |       |       |____      |_    |____     |______
   |       |            |       |        |           |
   |       |            |       |        |           |
   |       |            |       |        |           |
   |       |            |       |        |           |
process|basename|match=^java.*,arg|org.jboss.Main|match=.*
Alternatively, the process scan query can match a pid file, which is a simple way to identify processes. A PID-based PIQL query has a slightly simpler format:
process|attribute|match=value
For example:
process|pidfile|match=/etc/product/lock.pid
After defining the scan query in the rhq-plugin.xml descriptor file, then the discovery component must be written to implement the scan and process results.

Example 4.1. Process Scan Method in the Discovery Component

   List<ProcessScanResult< autoDiscoveryResults = 
      context.getAutoDiscoveredProcesses();
   for (ProcessScanResult result : autoDiscoveryResults) {
       ProcessInfo procInfo = result.getProcessInfo();
       ....
       // as before
       DiscoveredResourceDetails detail = 
          new DiscoveredResourceDetails(
              resourceType, key, name, null,
              description, childConfig, procInfo
          );
       result.add(detail);
   }
The agent manages resources by gathering metrics (for monitoring) and by launching scheduled operations, or tasks, on the resource. These two areas are configured similarly in the plug-in.
Monitoring areas are configured through <metric> elements in the plug-in descriptor.
        <metric displayName="Bytes Sent"
                description="Shows the rate that data bytes are sent by the Web service."
                property="Bytes Sent/sec"
                defaultOn="true"
                displayType="summary"
                measurementType="trendsup"
                units="bytes"/>
The most relevant attributes on that attribute relate to the monitoring property (which is partially defined by the resource itself).
  • property identifies the resource monitoring property.
  • measurementType sets the data type being collected.
  • units sets the units of the thing being monitored.
In the plug-in Java component, the metric is first set up by pulling in the MeasurementFacet.
public class testComponent implements ResourceComponent
, MeasurementFacet
, OperationFacet
Then, there is an entry for monitoring in a MeasurementReport, with a MeasurementScheduleRequest entity for each type of monitoring data.
    public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {

        String propertyBase = "\\Web Service(_Total)\\";
        Pdh pdh = new Pdh();

        for (MeasurementScheduleRequest request : metrics) {
            double value = pdh.getRawValue(propertyBase + request.getName());
            report.addData(new MeasurementDataNumeric(request, value));
        }
}
Important
When defining metrics, values that form part of a larger data structure, such as an array of values, need to be deconstructed into individual values before they can be monitored.
Similarly, operations are configured in the plug-in descriptor in an <operation> element, implemented in the plug-in Java component through an OperationFacet, and then invoked in a OperationResult method.

4.2.2.3. Events

Events for resources are essentially types of log messages that are recognized by the agent.
In the plug-in descriptor, an event is configured by a simple <event> element, no children, that identifies the logging area by name.
<event name="errorLogEntry" description="an entry in the error log file"/>
The event handling is handled through an EventPoller component. This can be in the larger plug-in Java component, but it is usually broken into a separate *EventPoller.java component. The way to implement event polling depends on the resource and the nature of its logging. One of the simplest ways is to call the EventPoller(), then define the event type and set how the event is polled.
    public PerfTestEventPoller(ResourceContext resourceContext) {
        this.resourceContext = resourceContext;
    }

    public String getEventType() {
        return PERFTEST_EVENT_TYPE;
    }

    public Set<Event> poll() {
        int count = Integer.parseInt(System.getProperty(SYSPROP_EVENTS_COUNT, "1"));
        String severityString = System.getProperty(SYSPROP_EVENTS_SEVERITY, EventSeverity.INFO.name());
        EventSeverity severity = EventSeverity.valueOf(severityString);
        Set<Event> events = new HashSet<Event>(count);
        for (int i = 0; i < count; i++) {
            Event event = new Event(PERFTEST_EVENT_TYPE, "source.loc", System.currentTimeMillis(), severity, "event #"
                + i);
            events.add(event);
        }
        return events;
    }

4.2.2.4. Resource Configuration

Resources can have parameters or settings changed through the JBoss ON GUI, managed by the agent. Those properties that can be edited are defined in the plug-in descriptor in <resource-configuration> elements. These configuration elements follow the same conventions as the <plugin-configuration> elements. The properties are defined as <simple-property> elements and can be listed (for options), mapped, or organized into groups that are collapsible sections in the UI.
         <resource-configuration>
            <c:group name="Attributes">
               <c:simple-property
                  name="appBase"
                  required="true"
                  readOnly="true"
                  description="The Application Base directory for this virtual host." />
               <c:simple-property
                  name="autoDeploy"
                  type="boolean"
                  description="Does this host deploy new applications dropped in appBase at runtime?" />
               <c:simple-property
                  name="deployOnStartup"
                  type="boolean"
                  description="Does this host deploy applications in appBase at startup?" />
               <c:simple-property
                  name="deployXML"
                  displayName="Deploy XML"
                  type="boolean"
                  description="deploy Context XML config files?" />
               <c:simple-property
                  name="unpackWARs"
                  displayName="Unpack WARs"
                  type="boolean"
                  description="Does this Host automatically unpack deployed WAR files?" />
               <c:simple-property
                  name="aliases"
                  required="false"
                  type="longString"
                  description="Aliases assigned to the Host. When editing, each alias must be on a new line. Aliases are automatically lowercased." />
            </c:group>
         </resource-configuration>
The first thing that is defined in the plug-in Java component is the ability to load the current configuration.
    public Configuration loadResourceConfiguration() {
        Configuration configuration = super.loadResourceConfiguration();
        try {
            resetConfig(CONFIG_ALIASES, configuration);
        } catch (Exception e) {
            log.error("Failed to reset role property value", e);
        }

        return configuration;
    }
The second part in the plug-in component allows the agent to change the configuration properties.
    public void updateResourceConfiguration(ConfigurationUpdateReport report) {
        Configuration reportConfiguration = report.getConfiguration();
        // reserve the new alias settings 
        PropertySimple newAliases = reportConfiguration.getSimple(CONFIG_ALIASES);
        // get the current alias settings
        resetConfig(CONFIG_ALIASES, reportConfiguration);
        PropertySimple currentAliases = reportConfiguration.getSimple(CONFIG_ALIASES);
        // remove the aliases config from the report so they are ignored by the mbean config processing
        reportConfiguration.remove(CONFIG_ALIASES);

        // perform standard processing on remaining config
        super.updateResourceConfiguration(report);

        // add back the aliases config so the report is complete
        reportConfiguration.put(newAliases);

        // if the mbean update failed, return now
        if (ConfigurationUpdateStatus.SUCCESS != report.getStatus()) {
            return;
        }

        // try updating the alias settings
        try {
            consolidateSettings(newAliases, currentAliases, "addAlias", "removeAlias", "alias");
        } catch (Exception e) {
            newAliases.setErrorMessage(ThrowableUtil.getStackAsString(e));
            report.setErrorMessage("Failed setting resource configuration - see property error messages for details");
            log.info("Failure setting Tomcat VHost aliases configuration value", e);
        }

        // If all went well, persist the changes to the Tomcat server.xml
        try {
            storeConfig();
        } catch (Exception e) {
            report
                .setErrorMessage("Failed to persist configuration change.  Changes will not survive Tomcat restart unless a successful Store Configuration operation is performed.");
        }
    }

4.2.3. Lifecycle Listeners

Some plug-ins need to perform some initialization immediately when they load and some cleanup when they unload. Global initialization and shutdown of a plug-in is performed by its lifecycle listener.
The org.rhq.core.pluginapi.plugin.PluginLifecycleListener class allocates global resources needed by plug-in components and cleans up those resources.
Each plug-in can optionally define one lifecycle listener by specifying a pluginLifecycleListener attribute in the top-level <plugin> element.
<plugin name="Apache"
		displayName="Apache HTTP Server"
		description="Management of Apache web servers"
		package="org.rhq.plugins.apache"
		pluginLifecycleListener="ApachePluginLifecycleListener"
		...

4.2.4. Plug-in Dependencies: Defining Relationships Between Plug-ins

Agent plug-ins can have relationships with other agent plug-ins. These relationships created dependencies between plug-ins, where plug-ins are only operable when other plug-ins are loaded, that allow plug-ins to share classes, or that extend the resource hierarchy by adding additional parent or child resources to an existing resource definition.
A parent plug-in is one that has another plug-in depending on it. A child plug-in is a plug-in that depends on another plug-in.
Agent plug-ins have three ways of defining dependencies:
  1. Required dependencies are set using the <depends> element. Just using <depends> means that the required plug-in must be loaded or the other plug-in will fail to load. Adding the useClasses attribute makes the classes and JAR files for the parent plug-in available to the child plug-in.
  2. An injection plug-in dependency means that a root-level resource runs inside another resource type, and that parent resource is defined as a parent plug-in. This essentially adds a new child to an existing resource type.
  3. An embedded plug-in dependency means that a new parent resource type is added for an existing child. This can allow the child to be extended to share the new parent's classloader (depending on both plug-ins' configuration) or simply expand discovery.
IMPORTANT
Embedded and injection plug-in dependencies are mutually exclusive. They cannot be used in the same plug-in definition.
There is one interesting similarity in all of these plug-in dependency models: Metadata and class definitions flow in only one direction, from a parent plug-in to its dependent plug-in. Information cannot flow in the other direction.

4.2.4.1. Required Plug-in Dependencies

The <depends> element directly under the <plug-in> element defines a parent plug-in that the plug-in depends on and required to be loaded. The <depends> element is what specifies a required dependency. The plug-in will not deploy successfully, unless all <depends> plug-ins are also successfully deployed.
The <depends> element can pull in JARs from the parent plug-in by specifying the useClasses attribute. The useClasses option can be set for only one required dependency in a single plug-in descriptor. If no <depends> element has a useClasses attribute, the last <depends> element specified in the plug-in descriptor, by default, has its useClasses attribute to true.
The <depends> element is used if the plug-in needs access to another plug-in's classes or if the plug-in should only be deployed when another plug-in is also deployed.
TIP
The embedded and injection plug-in dependencies are optional dependencies. If the specified plug-in isn't loaded, then the plug-in simply runs without loading those dependencies. To make an embedded or injection plug-in a required dependency, then set the embedded or injection plug-in as a required plug-in using the <depends> element, as well as the other configuration.

4.2.4.2. Embedded Plug-in Dependencies

An embedded plug-in dependency adds a new parent resource for an existing child resource. The dependent plug-in (for the new parent resource) depends on the child.
With an embedded plug-in dependency, the server or service definition can be a copy of a source resource type found in another plug-in. That copy is defined in the plug-in descriptor by setting the sourcePlugin and sourceType attributes on the resource elements. When a plug-in source is specified, the server or service is copied from the source resource type, which means it has the same metadata as the source, with the exception that the embedded server or service can override the discovery and resource classes and, potentially, have a different name.
An embedded plug-in is an optional dependency.

4.2.4.3. Injection Plug-in Dependencies

A root-level resource type in an agent plug-in can define parent resource types that it can run inside of. This essentially injects the resource type as a child type to another, existing resource. This is an injection plug-in dependency.
The injection plug-in dependency illustrates that a child resource type knows about its parent resource types, but the parents do not know about the child. Knowledge of plug-ins flow down, not up. A parent plug-in's type information is known to its child plug-in, but a parent plug-in does not know anything about the child plug-ins that depend on it.
An injection dependency is a list of allowed parents, within a <runs-inside> element. Each parent is an optional dependency.
<runs-inside>
   <parent-resource-type name="JMX Server" plugin="JMX" />
   <parent-resource-type name="JBoss Server" plugin="JBoss AS" />
</runs-inside>

4.2.5. Class Sharing Between Plug-ins

All agent plug-ins have their own classloader while running in the plug-in container. Each resource in inventory will be assigned a classloader, which can be the same as its plug-in classloader.

Figure 4.1. Agent Components, Together

Agent Components, Together
All plug-in classloaders are isolated from one another, unless the <depends useClasses=""> attribute is set to true. If a plug-in is a direct dependent of another plug-in, and that dependency is defined with <depends useClasses="true">, then that parent plug-in's JAR classes (and all of its parent JARs) are available to the dependent plug-in's classloader.
The most common reason to create that kind of dependency, and share JARs and classes between plug-ins, is because one resource defined in one plug-in is deployed and running in another resource defined in another plug-in. The child plug-in needs a way to connect to its parent resource to perform things like discovery and management of the child resource. By default, all managed resources are assigned a resource classloader that is shared. This classloader can belong to the plug-in or to the parent resource.
When a resource component needs to create a connection to its actual managed resource, that resource's classloader must be different than the normal, shared plug-in classloader. The resource usually needs to have the client JARs necessary to connect to the managed resource within its own classloader, and those client JARs are usually very specific to the version of the resource being managed. The connecting resource should be in charge of creating the connection, since it knows how to do it. When a resource requires its own connection classloader, specify the attribute classLoader="instance" on the resource type and make sure the resource type's discovery component implements the ClassLoaderFacet so it tells the plug-in container where any additional connection classes can be found for the specific version of the specific resource being managed.
In Example 4.2, “classLoader for Plug-in Z”, the Z1.server has a classLoader option set to shared. This means that Z1.server resources share their classloaders with their parent resources, and that classloader may be a resource classloader or a plug-in classloader. Every Z1.server resource uses the same classloader.

Example 4.2. classLoader for Plug-in Z

<plug-in name="Z">

<depends plugin="A" />

<server name="Z1.server" classLoader="shared">
   <runs-inside>
      <parent-resource-type name="B1.server" plugin="B"/>
      <parent-resource-type name="C1.server" plugin="C"/>
   </runs-inside>
</server>

<server name="Z2.server" sourcePlugin="D" sourceType="D1" classLoader="instance">
</server>

<server name="Z3.server" classLoader="instance">
</server>

</plugin>
Normally, setting a classLoader option to instance means that each resource uses its own resource plug-in. However, for Z2.server, the Z2.server plug-in is extended by embedding the values for Plug-in D, so Z2.server resources share their classloaders with their parent plug-in.
Z3.server simply uses its own resource classloader because its classLoader option is set to instance and it has no injected or embedded dependencies. When the classLoader option is set to instance, the ResourceDiscoveryComponent implementation can optionally define a ClassLoaderFacet with a method (getAdditionalClasspathUrls) that returns a List<URL> pointing to additional JARs that should be placed in the resource's classloader. When the plug-in container needs to create a classloader for a resource, it checks if the resource's discovery component implements this facet, and, if so, it gets the additional classpath URLs and adds them to the resource classloader when it creates it.
If a resource type is defined with either an injection or embedded dependency, then its classloader depends on both its classLoader attribute value and its parent's classLoader attribute value.
Resource ClassLoader Parent ClassLoader ClassLoader Description
shared shared The useClasses value must be set to true so that the resource can access both its classes and the parent classes.
instance shared The resource primarily needs its own classes, but it may be beneficial for useclasses to be set to true to so that the child can use parent classes.
shared instance The resource uses only its own classloader.
instance instance The resource uses only its own classloader.
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.