Java Providers
The following are the options available when defining a Java provider:
- Classpath: Java classpath required by implementation class.
- Class loader id: The id of the class loader to use; Use the same id for multiple provider instances using the same code to allow sharing of resources. The value is usually a string equal to the cutsom agent id to guarantee a unique name in the scope of this monitoring session
- Implementation class: The name of the java class with the implementation for this provider.
- Implementation class parameters: Parameters list to be passed to the impplementation class. Each parameter must be between double quotes (e.g. "param1" "param2").
A Java provider is a class that implements the following interface:
/**
* Interface that must be implemented by classes that are used with
* the java provider.
*/
public interface com.ixora.rms.providers.impl.java.JavaProviderImplementation {
/**
* @param parameters parameters required by this instance; they are in the same order
* as they were defined in the provider configuration.
* @param context the execution context (@see com.ixora.rms.providers.impl.java.JavaProviderImplementationContext)
*/
void initialize(String[] parameters, com.ixora.rms.providers.impl.java.JavaProviderImplementationContext context) throws Exception;
/**
* @return the table with values; check the documentation for providers and their associated
* parsers for how the data should be organized in the table
*/
String[][] getValues() throws Exception;
/**
* Cleanup method. This method will be invoked when the provider is disposed of.
* @throws Exception
*/
void cleanup() throws Exception;
}
where the interface com.ixora.rms.providers.impl.java.JavaProviderImplementationContext
is the execution context for the provider and has the following definition:
/**
* Context for classes used for Java providers.
*/
public interface com.ixora.rms.providers.impl.java.JavaProviderImplementationContext {
/**
* The error message will be reported to the console. Use this method
* only for non-fatal errors, otherwise propagate all exceptions.
* @param error
* @param t
*/
void error(String error, Throwable t);
}
You can define a Java provider by following these steps:
- Install a custom agent: "Navigate to Tools" > "Agent Installer" > "Install" > "Custom Agent Installation" > "Agent Template Java" which will install an agent which has the following configuration data available, which is a list of 10 generic parameters:
- Parameter1
- Parameter2
- ...
- Parameter10
- Add a Java provider to your agent created above. Navigate to Tools - Provider Managers. In this dialog select your agent and press 'Add'. A dialog will open where you define your provider. Select the provider with the name 'Java', disable the 'Optional' checkbox. Now you have to fill in the following fields:
- Classpath: the classpath to the jar file with you provider implementation class e.g. C:/Java/myprovider.jar or {home}/lib/myprovider.jar if you want to copy the provider into IxoraRMS_install_folder/lib folder
- Classloader id: MyCustomAgent
- Implementation class name: the name of the class implementing the Java provider
- Defining the parser for the java provider
- In order to compile your class you need to add the following jar files from IxoraRMS/jars folder to your build path:
- RMSCommon.jar
- Provider_java.jar
- IxoraCommon.jar
The following is an example of a Java provider that uses SQL to retrieve performance data.
package com.ixora.tutorials.providers;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
import com.ixora.rms.providers.impl.java.JavaProviderImplementation;
import com.ixora.rms.providers.impl.java.JavaProviderImplementationContext;
import com.ixora.rms.providers.utils.sql.CachedConnection;
import com.ixora.rms.providers.utils.sql.ConnectionCache;
/**
* The implementation of a Java providers that reads data from a MySQL database.
*/
public class MyJavaProvider implements JavaProviderImplementation {
/**
* Execution context; use it to report non-fatal errors to the
* IxoraRMS console.
*/
private JavaProviderImplementationContext fContext;
/** The JDBC driver. It is required by the connection cache. */
private Driver fDriver;
/** The JDBC connection string. */
private String fConnectionString;
/** The JDBC username */
private String fUsername;
/** The JDBC password */
private String fPassword;
/** The operation type */
private String fOperation;
/**
* Use a connection cache which will be shared by all providers
* using this implementation class.
* If you are concern with the number of connections open to the database
* you should use a shared class loader to benefit from connection sharing.
*/
private static ConnectionCache fConnectionCache;
static {
try {
fConnectionCache = new ConnectionCache();
}catch(Exception e) {
e.printStackTrace();
}
}
/**
* @see com.ixora.rms.providers.impl.java.JavaProviderImplementation#initialize(java.lang.String[], com.ixora.rms.providers.impl.java.JavaProviderImplementationContext)
* @param parameters will be the following:
* jdbc connection string
* jdbc driver class name
* username - the jdbc username
* password - the jdbc password
* operation - depending on this value, different values are returned, allowing the same
* implementation class to be used by different java providers; this allows for possible sharing of
* database connections to reduce the cost of monitoring
*/
public void initialize(String[] parameters, JavaProviderImplementationContext context) throws Exception {
if(parameters == null || parameters.length != 5) {
throw new Exception("Invalid parameters");
}
fConnectionString = parameters[0];
String driverClassName = parameters[1];
fUsername = parameters[2];
fPassword = parameters[3];
//fContext = context;
PrintWriter w = new PrintWriter(new OutputStreamWriter(System.out));
DriverManager.setLogWriter(w);
Class.forName(driverClassName);
fDriver = DriverManager.getDriver(fConnectionString);
// Test if the connection is possible
Connection conn = DriverManager.getConnection(fConnectionString, fUsername, fPassword);
conn.close();
}
/**
* @see com.ixora.rms.providers.impl.java.JavaProviderImplementation#getValues()
*/
public String[][] getValues() throws Exception {
CachedConnection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = fConnectionCache.getConnection(
fDriver, fConnectionString, fUsername, fPassword);
statement = connection.getSQLConnection().createStatement();
resultSet = statement.executeQuery(getSQL());
int columnCount = resultSet.getMetaData().getColumnCount();
List<String[]> rows = new LinkedList<String[]>();
while(resultSet.next()) {
String[] row = new String[columnCount];
for(int i = 1; i <= columnCount; i++) {
Object obj = resultSet.getObject(i);
row[i-1] = obj.toString();
rows.add(row);
}
}
return rows.toArray(new String[rows.size()][columnCount]);
} finally {
if(resultSet != null) {
resultSet.close();
}
if(statement != null) {
statement.close();
}
if(connection != null) {
connection.close();
}
}
}
/**
* Based on the configured operation it returns the corresponding SQL.
* Of course of it was that simple you would have used an SQL provider; probably
* depending on the operation specified during initialization a more complex
* type of processing would take place; in this example we assume that different
* operations means just using different SQLs.
* @throws Exception
* @return
*/
private String getSQL() throws Exception {
if("default".equals(fOperation)) {
return "select counter1,counter2,counter3,counter4 from mytable";
}
throw new Exception("Unknown operation: " + fOperation);
}
/**
* @see com.ixora.rms.providers.impl.java.JavaProviderImplementation#cleanup()
*/
public void cleanup() throws Exception {
;// not necessary, the connections in the ConnectionCache will time out if idle
}
}