A reference that describes the code the Agent Builder generates and the code you must add or replace for the resources you want to monitor.
When you create an agent with one or more Java™ API data sources, the Agent Builder generates Java application source code. The code is generated in the agent project and follows the structure of your agent. You must add your own Java code to the generated application. Your code collects data for sampled attribute groups, handles events to be posted to event-based attribute groups, reports errors if problems are encountered, and runs tasks. The generated application supplies the agent with data, but it is sample data, to be replaced with data obtained from the resources you want to monitor.

The generated Java application separates, to a great degree, code that interfaces with the agent from code that interfaces with the resources you are monitoring. It contains files that you modify, and files that you do not modify.
The classes which you can modify are never overwritten by the Agent Builder. The Agent Builder creates them only if they do not exist.
The helper classes and the interface are overwritten each time the Agent Builder is saved. As you modify and save the agent, the helper classes are updated to reflect any structural changes to the Java API attribute groups. The interface and helper classes contain a warning in the header that reminds you not to modify the file.
The main method in MainClass is called when the agent is started. It creates a MainClass instance and then enters the long-running method to receive and handle agent requests.
Most of the initialization and cleanup code must be added to MainClass. In the constructor, add initialization that is needed to create or access your resources. You might want to open connections to remote resources, create handles, or initialize data structures.
Before the agent terminates, the stopDataCollection method is called. If you want to close connections or cleanup before the Java application ends, add that code to the stopDataCollection method.
If initialization is needed only for a particular attribute group, that initialization can be added to the constructor of the attribute group class. Similarly, if any cleanup is needed only for a particular attribute group, that cleanup code can be added to the stopDataCollection method of the attribute group.
Any code in the Java application can use the logger object to write log entries. (The main helper class creates a protected logger object in its constructor. The attribute group helper objects create a protected reference to that logger in their constructors). The logger object uses the Java trace log utility. Errors and detailed trace information can be obtained from the trace log that is created by the logger. The trace information is important for troubleshooting problems with the provider.
When stopDataCollection is called, if you pass the cleanup work to another thread, wait for that thread to finish before you return from the stopDataCollection method. Otherwise, the cleanup work can be abruptly terminated when the process ends because the main thread completed.
| Configured trace level | Java logging trace level | Description |
|---|---|---|
| Off | OFF | No logging is done. |
| Error | SEVERE | Trace problems that occurred in the Java application. |
| Warning | WARNING | Trace errors and potential errors. |
| Information | INFORMATION | Trace important information about the Java application. |
| Minimum Debug | FINE | Trace high-level details necessary to analyze the behavior of the Java application. |
| Medium Debug | FINER | Trace details about the program flow of the Java application. |
| Maximum Debug | FINEST | Trace all details about the Java application. |
| All | ALL | Trace all messages. |
The class for a sampled attribute group (one that collects one or more data rows) contains a collectData method, for example, Sampled_Data.collectData. This method is called whenever data is requested by the agent.
| Tivoli Monitoring type | Data type of attribute field |
|---|---|
| String | String |
| Numeric, 32 bit, no decimal adjustment | int |
| Numeric, 64 bit, no decimal adjustment | long |
| Numeric, non-zero decimal adjustment | double |
| Time stamp | Calendar |
You must collect the data from your resource (Step 1), replacing the sample data that is used in the generated application.
To populate the Attributes object, you can pass the data in using the Attributes constructor (as is done in the generated application). Alternatively use the zero-argument constructor to create an Attributes object and then assign the fields of the attributes object to the attribute values you collected. Fields have the same name as the attributes, though they start with a lowercase letter.
If a sampled attribute group is in a subnode, there are presumably multiple resources that you are monitoring (a different one for each subnode). You must determine which resource to collect data from. There must be one or more configuration properties that identify which resource is being monitored.
For this example, it is assumed that one configuration property, K91_INSTANCE_KEY, contains a value that identifies the resource from which data must be collected.
Alternatively, you might want to do these steps in the attribute group class constructor and establish a direct mapping from instance ID to resource. An example attribute group class constructor is the Sampled_Subnode constructor. This procedure also gives you the opportunity to create handles or open connections that might be used through the life of the agent. Creating handles or open connections can make access to your resources more efficient.
The generated code creates sample resource objects of type MonitoredEntity in the constructor, and adds them to a configurationLookup map. You must remove the MonitoredEntity inner class, and replace the MonitoredEntity objects with objects that access your own resources. If you choose to do the entire lookup procedure in the collectData method, you can remove the configurationLookup map from the class.
An arbitrary subnode property is chosen in the Agent Builder example, in this case K91_INSTANCE_KEY. If not the correct property, or more than one property is needed to identify the correct resource, you must choose the properties to identify the resource.
For attribute groups that generate events, there is no periodic call to a collectDatamethod. Events are sent by your application as your resource posts them.
When an event is detected for a subnode attribute group, the Java application must post the event to the correct subnode.
Take action commands are defined either in the Tivoli Enterprise Portal or by using the tacmd createaction command. The actions can be imported into the agent's Agent Builder project so that they are created when the agent is installed. For more information about importing take action commands, see (Importing application support files).
The generated Java application registers for any actions that begin with the product code of the agent, for example, K91Refresh. This registration is done in the main helper class (MainClassBase) from the registerActionPrefix method. If you want to register other prefixes, or not register for actions at all, override the registerActionPrefix in (MainClassBase).
When the agent wants to run an action which starts with a prefix that your agent registered, the MainClass.takeAction method is called. You add code to call Request.getAction(), do the appropriate action, and then call AgentConnection.sendActionReturnCode to send the return code from your action. A return code of 0 means the action is successful, any other return code means the action failed.
The collectData and takeAction methods can throw any Java exception, so you can allow your collection code to throw exceptions without catching them. The handleException method (for collectData) or handleActionExceptionmethod (for takeAction) is called when the helper class gets the exception.
For collectData exceptions, you must call AgentConnection.sendError when an exception occurs or when there is a problem in data collection. The generated application passes an error code of GENERAL_ERROR. However, you must replace this error code with one defined by your agent that best describes the problem that was encountered. For more information about adding error codes, see Step (13).
For takeAction exceptions, you must call AgentConnection.sendActionReturnCode with a non-zero return code.
A typical response to an exception or other resource error is to send an error code to the agent by calling the AgentConnection.sendError method. An error for an event-based attribute group can be sent at any time. An error for a sampled attribute group can be sent only in response to a collect data request, and in place of a sendData call.
| Error Code | Description |
|---|---|
| NO_ERROR | There are no problems with the attribute group currently. |
| NO_INSTANCES_RETURNED | The Java application responded to a data collection request but provided no data. Not providing data is not an error. It generally indicates that there are no instances of the resource that are being monitored by the attribute group. |
| OBJECT_NOT_FOUND | The agent tried to collect data for an attribute group that is not registered through the client API. This error can mean that the application failed to start or did not initiate the attribute group registration when the agent tried to collect data. |
| OBJECT_CURRENTLY_UNAVAILABLE | The application sent the agent an error code that is not defined in the global list of error codes. |
| GENERAL_ERROR | A problem occurred collecting data from the
application, usually because the application did not reply to the
request within the timeout interval. See the agent trace log for
more details. The application can also specify GENERAL_ERROR as an error code, but it is better if a more detailed error code is defined. |
Certain changes to the agent require you to make corresponding changes to the Java application. If the structural changes are complex, you can delete any or all of the Java source files before you save the agent. You can also delete the files if you want to start over without the customizations you made,
| Agent change | What the Agent Builder does | Manual changes that are needed in the Java source |
|---|---|---|
| Change of the main class package name |
|
|
| Change of the main class name |
|
|
| Addition of a Java API attribute group |
|
Overwrite sample code with custom logic in the attribute group class. |
| Removal of a Java API attribute group | Removes registration from the main helper class. |
|
| Renaming of a Java API attribute group |
|
|
| Addition of an attribute to a Java API attribute group | Updates the Attributes inner class in the attribute group helper class. | Collect data for the new attribute in the attribute group class. |
| Removal of an attribute from a Java API attribute group | Updates the Attributes class in the attribute group helper class. | Remove data collection for the former attribute in the attribute group class. |
| Renaming of an attribute in a Java API attribute group | Updates the attribute name in the Attributes class in the attribute group helper class. | Update any references to the attribute name in the Attributes class (often there are no references because the Attributes constructor, with positional arguments, is used). |
| Reordering of attributes in a Java API attribute group | Updates the attribute order in the Attributes class in the attribute group helper class. | Update the argument order in any calls to the Attributes constructor. |
The Java API is used throughout the generated Java application to communicate with the agent. Often your only direct interaction with the Java API is to modify a parameter of an existing method call. For example, changing a posted error code from GENERAL_ERROR to an error code defined in your agent.
The classes for the Java API are in cpci.jar. The cpci.jar file is automatically added to the Java Build Path of the project when an agent which contains a Java API attribute group is created. The file is also added when an agent that contains a Java API attribute group is imported. The file is also added when a Java API attribute group is added to an existing agent. Thecpci.jar is also automatically packaged with each agent that contains a Java API attribute group and added to the CLASSPATH of the Java application.