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

}

}