The content subsystem provides a means to inventory and manipulate a collection of content on any resource in the system. The abstraction provided by the content subsystem allows the plugin developer to determine what constitutes a package on a particular resource type, allowing this interpretation to range from a specific file to an arbitrary piece of content provided by the resource. RHQ then provides a framework for inventorying packages on each resource and a robust, flexible means to push new packages out to a resource.
In addition to handling the packages on a particular resource, the content subsystem provides a means of introducing and managing packages on the server. Once packages have been introduced into the server through a particular content source, they can be pushed out to one or more resources. A server-side plugin system allows packages to be exposed into the server through any external source; the plugin acts as an adapter that knows how to convert between the external system and the local RHQ model.
Together, the agent-side inventory and deployment features along with the server-side importing and management of packages from external locations provide a complete solution for content needs.
At the root of the content subsystem is the ability to dynamically introduce domain specific types on top of the platform's generic model. A package type is used to differentiate packages from one another. It is possible that the package type will correspond to a particular file type, however this is not a requirement. It is up to the plugin developer to determine an appropriate categorization of packages it supports.
Each package type is scoped to the resource type in which it is defined. This allows multiple resource types to define a package type with the same name without having a conflict within RHQ.
For example, a plugin may support installing packages onto a Red Hat Linux computer. A package type would be defined to represent an installable package. This package type is not necessarily scoped specifically to RPM files, as it is also possible the plugin would support installing a .bin or .gz file. It is important to think in terms of the overall concept of what packages of a particular type will represent when defining a resource type's supported package types.
A package represents a piece of content that is known to RHQ. A package is of a particular package type. A package may have been discovered as existing on a resource or it may have been introduced into the server from an external package source through a content source. Depending on which of these means the package was introduced to the system through, the bits for the package may or may not be available to RHQ (and thus will dictate if the package can be deployed out to a new resource).
A content source is a means through which packages can be introduced into the server. A package that is initially introduced to the server through this means is not necessarily associated with a resource. Instead, the content source will allow the bits for that package to be retrieved and pushed out to a resource as part of a deploy operation.
A content source is of a particular content source type. Content source types are introduced into the system through server-side pluigns, similar to how resource types are introduced in an agent-side plugin. The content source type, or more generally the server-side plugin in general, acts as an adapter between an external package source and the RHQ domain model. In other words, content source types can be added to support custom package sources and allow RHQ to interact with them regardless of their external location.
For example, a yum content source type understand how to communicate with a yum repository to retrieve a package list and, ultimately, retrieve the bits for a package. When a content source of this type is created in the system, it is configured to look at a particular yum repository. It will then provide packages into the system that can be deployed out to resources in the inventory.
If a custom package source exists, such as an RSS feed for instance, a new server-side plugin can be created that will connect to the RSS feed and parse the package metadata into the RHQ domain model. This extension model allows the generic framework to remain unchanged while adding support for new sources.
A channel is an organizational construct. A channel is a group of packages. These packages can be fed into the channel through one or more content sources. Additionally, a user can manually upload a package (providing some metadata on the package at the same time) into a channel.
One of the major features of the content subsystem is the ability to discover packages that are deployed to resources in the inventory. The plugin container provides the mechanism for automatically scheduling discoveries; the interval at which these discoveries take place is controllable by the plugin developer as part of a package type definition.
A plugin that supports using the content subsystem implements the ContentFacet (see Agent Components for more information). This interface exposes a method to discover packages of a particular type on a resource. The plugin developer implements this method with whatever logic is necessary to detect packages on the resource. On each call to this method, the plugin should return a complete snapshot of packages of that type on that resource. The server will do the necessary logic to determine which packages have been added or deleted. More information on the implementation details of this method can be found in the ContentFacet javadocs.
The discovery report is sent to the server where it is stored in the inventory. The user interface can then query the resource to retrieve a list of currently installed packages.
The code used in the content subsystems is spread across the server side and plugin code
The code containing our domain objects can be found in:
modules/core/domain/src/main/java/org/rhq/core/domain/content
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content
Responsible for storage and retrieval of our domain objects from the database.
modules/enterprise/server/plugins/disk : Content Provider that grabs packages off of a local disk path
modules/enterprise/server/plugins/jboss-software : Content Provider that gets packages from the JBoss CSP feed
modules/enterprise/server/plugins/rhnhosted : Content Provider that gets packages from RHN Hosted
modules/enterprise/server/plugins/url : Content Provider that gets packages from a remote URL
modules/enterprise/server/plugins/yum : Content Provider that gets packages from an existing yum repo
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/plugin/pc/content/
This code is responsible for interpreting the data returned from the Content Providers (Server Side Plugins), mapping it to a domain object and passing off to the Manager Beans to store to the database and filesystem.
modules/plugins/platform/src/main/java/org/rhq/plugins/platform/content/yum/ : The client side yum plugin that manages installation and inventory of packages on a Linux host
modules/core/dbutils/src/main/scripts/dbsetup/content-schema.xml : Schema definition for content tables
modules/core/dbutils/src/main/scripts/dbsetup/content-data.xml : Initial data population for content tables