/**
* Java API to internal functions of collectd.
*
+ * All functions in this class are {@code static}. You don't need to create an
+ * object of this class (in fact, you can't). Just call these functions
+ * directly.
+ *
* @author Florian Forster <octo at verplant.org>
*/
public class Collectd
{
+
+ /**
+ * Constant for severity (log level) "error".
+ *
+ * @see CollectdLogInterface
+ */
public static final int LOG_ERR = 3;
+
+ /**
+ * Constant for severity (log level) "warning".
+ *
+ * @see CollectdLogInterface
+ */
public static final int LOG_WARNING = 4;
+
+ /**
+ * Constant for severity (log level) "notice".
+ *
+ * @see CollectdLogInterface
+ */
public static final int LOG_NOTICE = 5;
+
+ /**
+ * Constant for severity (log level) "info".
+ *
+ * @see CollectdLogInterface
+ */
public static final int LOG_INFO = 6;
+
+ /**
+ * Constant for severity (log level) "debug".
+ *
+ * @see CollectdLogInterface
+ */
public static final int LOG_DEBUG = 7;
+ /**
+ * Return value of match methods: No match.
+ *
+ * This is one of two valid return values from match callbacks, indicating
+ * that the passed {@link DataSet} and {@link ValueList} did not match.
+ *
+ * Do not use the numeric value directly, it is subject to change without
+ * notice!
+ *
+ * @see CollectdMatchInterface
+ */
public static final int FC_MATCH_NO_MATCH = 0;
+
+ /**
+ * Return value of match methods: Match.
+ *
+ * This is one of two valid return values from match callbacks, indicating
+ * that the passed {@link DataSet} and {@link ValueList} did match.
+ *
+ * Do not use the numeric value directly, it is subject to change without
+ * notice!
+ *
+ * @see CollectdMatchInterface
+ */
public static final int FC_MATCH_MATCHES = 1;
+ /**
+ * Return value of target methods: Continue.
+ *
+ * This is one of three valid return values from target callbacks, indicating
+ * that processing of the {@link ValueList} should continue.
+ *
+ * Do not use the numeric value directly, it is subject to change without
+ * notice!
+ *
+ * @see CollectdTargetInterface
+ */
public static final int FC_TARGET_CONTINUE = 0;
+
+ /**
+ * Return value of target methods: Stop.
+ *
+ * This is one of three valid return values from target callbacks, indicating
+ * that processing of the {@link ValueList} should stop immediately.
+ *
+ * Do not use the numeric value directly, it is subject to change without
+ * notice!
+ *
+ * @see CollectdTargetInterface
+ */
public static final int FC_TARGET_STOP = 1;
+
+ /**
+ * Return value of target methods: Return.
+ *
+ * This is one of three valid return values from target callbacks, indicating
+ * that processing of the current chain should be stopped and processing of
+ * the {@link ValueList} should continue in the calling chain.
+ *
+ * Do not use the numeric value directly, it is subject to change without
+ * notice!
+ *
+ * @see CollectdTargetInterface
+ */
public static final int FC_TARGET_RETURN = 2;
/**
* Java representation of collectd/src/plugin.h:plugin_register_config
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdConfigInterface
*/
native public static int registerConfig (String name,
CollectdConfigInterface object);
/**
* Java representation of collectd/src/plugin.h:plugin_register_init
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdInitInterface
*/
native public static int registerInit (String name,
CollectdInitInterface object);
/**
* Java representation of collectd/src/plugin.h:plugin_register_read
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdReadInterface
*/
native public static int registerRead (String name,
CollectdReadInterface object);
/**
* Java representation of collectd/src/plugin.h:plugin_register_write
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdWriteInterface
*/
native public static int registerWrite (String name,
CollectdWriteInterface object);
/**
* Java representation of collectd/src/plugin.h:plugin_register_flush
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdFlushInterface
*/
native public static int registerFlush (String name,
CollectdFlushInterface object);
/**
* Java representation of collectd/src/plugin.h:plugin_register_shutdown
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdShutdownInterface
*/
native public static int registerShutdown (String name,
CollectdShutdownInterface object);
/**
* Java representation of collectd/src/plugin.h:plugin_register_log
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdLogInterface
*/
native public static int registerLog (String name,
CollectdLogInterface object);
/**
* Java representation of collectd/src/plugin.h:plugin_register_notification
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdNotificationInterface
*/
native public static int registerNotification (String name,
CollectdNotificationInterface object);
/**
* Java representation of collectd/src/filter_chain.h:fc_register_match
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdMatchFactoryInterface
*/
native public static int registerMatch (String name,
CollectdMatchFactoryInterface object);
/**
+ * Java representation of collectd/src/filter_chain.h:fc_register_target
+ *
+ * @return Zero when successful, non-zero otherwise.
+ * @see CollectdTargetTargetInterface
+ */
+ native public static int registerTarget (String name,
+ CollectdTargetFactoryInterface object);
+
+ /**
* Java representation of collectd/src/plugin.h:plugin_dispatch_values
+ *
+ * @return Zero when successful, non-zero otherwise.
*/
native public static int dispatchValues (ValueList vl);
/**
* Java representation of collectd/src/plugin.h:plugin_dispatch_notification
+ *
+ * @return Zero when successful, non-zero otherwise.
*/
native public static int dispatchNotification (Notification n);
/**
* Java representation of collectd/src/plugin.h:plugin_get_ds
+ *
+ * @return The appropriate {@link DataSet} object or {@code null} if no such
+ * type is registered.
*/
native public static DataSet getDS (String type);
*/
native private static void log (int severity, String message);
+ /**
+ * Prints an error message.
+ */
public static void logError (String message)
{
log (LOG_ERR, message);
} /* void logError */
+ /**
+ * Prints a warning message.
+ */
public static void logWarning (String message)
{
log (LOG_WARNING, message);
} /* void logWarning */
+ /**
+ * Prints a notice.
+ */
public static void logNotice (String message)
{
log (LOG_NOTICE, message);
} /* void logNotice */
+ /**
+ * Prints an info message.
+ */
public static void logInfo (String message)
{
log (LOG_INFO, message);
} /* void logInfo */
+ /**
+ * Prints a debug message.
+ */
public static void logDebug (String message)
{
log (LOG_DEBUG, message);
} /* void logDebug */
-
} /* class Collectd */
/* vim: set sw=2 sts=2 et fdm=marker : */
static void cjni_log (int severity, const char *message, user_data_t *ud);
static int cjni_notification (const notification_t *n, user_data_t *ud);
-static int cjni_match_create (const oconfig_item_t *ci, void **user_data);
-static int cjni_match_destroy (void **user_data);
-static int cjni_match_match (const data_set_t *ds, const value_list_t *vl,
+/* Create, destroy, and match/invoke functions, used by both, matches AND
+ * targets. */
+static int cjni_match_target_create (const oconfig_item_t *ci, void **user_data);
+static int cjni_match_target_destroy (void **user_data);
+static int cjni_match_target_invoke (const data_set_t *ds, value_list_t *vl,
notification_meta_t **meta, void **user_data);
/*
return (0);
} /* }}} jint cjni_api_register_notification */
-static jint JNICALL cjni_api_register_match (JNIEnv *jvm_env, /* {{{ */
- jobject this, jobject o_name, jobject o_match)
+static jint JNICALL cjni_api_register_match_target (JNIEnv *jvm_env, /* {{{ */
+ jobject this, jobject o_name, jobject o_match, int type)
{
- match_proc_t proc;
int status;
const char *c_name;
c_name = (*jvm_env)->GetStringUTFChars (jvm_env, o_name, 0);
if (c_name == NULL)
{
- ERROR ("java plugin: cjni_api_register_match: "
+ ERROR ("java plugin: cjni_api_register_match_target: "
"GetStringUTFChars failed.");
return (-1);
}
- status = cjni_callback_register (jvm_env, o_name, o_match, CB_TYPE_MATCH);
+ status = cjni_callback_register (jvm_env, o_name, o_match, type);
if (status != 0)
{
(*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name);
return (-1);
}
- memset (&proc, 0, sizeof (proc));
- proc.create = cjni_match_create;
- proc.destroy = cjni_match_destroy;
- proc.match = cjni_match_match;
+ if (type == CB_TYPE_MATCH)
+ {
+ match_proc_t m_proc;
+
+ memset (&m_proc, 0, sizeof (m_proc));
+ m_proc.create = cjni_match_target_create;
+ m_proc.destroy = cjni_match_target_destroy;
+ m_proc.match = (void *) cjni_match_target_invoke;
+
+ status = fc_register_match (c_name, m_proc);
+ }
+ else if (type == CB_TYPE_TARGET)
+ {
+ target_proc_t t_proc;
+
+ memset (&t_proc, 0, sizeof (t_proc));
+ t_proc.create = cjni_match_target_create;
+ t_proc.destroy = cjni_match_target_destroy;
+ t_proc.invoke = cjni_match_target_invoke;
+
+ status = fc_register_target (c_name, t_proc);
+ }
+ else
+ {
+ ERROR ("java plugin: cjni_api_register_match_target: "
+ "Don't know whether to create a match or a target.");
+ (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name);
+ return (-1);
+ }
- status = fc_register_match (c_name, proc);
if (status != 0)
{
- ERROR ("java plugin: cjni_api_register_match: "
- "fc_register_match failed.");
+ ERROR ("java plugin: cjni_api_register_match_target: "
+ "%s failed.",
+ (type == CB_TYPE_MATCH) ? "fc_register_match" : "fc_register_target");
(*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name);
return (-1);
}
(*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name);
return (0);
+} /* }}} jint cjni_api_register_match_target */
+
+static jint JNICALL cjni_api_register_match (JNIEnv *jvm_env, /* {{{ */
+ jobject this, jobject o_name, jobject o_match)
+{
+ return (cjni_api_register_match_target (jvm_env, this, o_name, o_match,
+ CB_TYPE_MATCH));
} /* }}} jint cjni_api_register_match */
+static jint JNICALL cjni_api_register_target (JNIEnv *jvm_env, /* {{{ */
+ jobject this, jobject o_name, jobject o_target)
+{
+ return (cjni_api_register_match_target (jvm_env, this, o_name, o_target,
+ CB_TYPE_TARGET));
+} /* }}} jint cjni_api_register_target */
+
static void JNICALL cjni_api_log (JNIEnv *jvm_env, /* {{{ */
jobject this, jint severity, jobject o_message)
{
"(Ljava/lang/String;Lorg/collectd/api/CollectdMatchFactoryInterface;)I",
cjni_api_register_match },
+ { "registerTarget",
+ "(Ljava/lang/String;Lorg/collectd/api/CollectdTargetFactoryInterface;)I",
+ cjni_api_register_target },
+
{ "log",
"(ILjava/lang/String;)V",
cjni_api_log },
"Lorg/collectd/api/CollectdMatchInterface;";
break;
+ case CB_TYPE_TARGET:
+ method_name = "createTarget";
+ method_signature = "(Lorg/collectd/api/OConfigItem;)"
+ "Lorg/collectd/api/CollectdTargetInterface;";
+ break;
+
default:
ERROR ("java plugin: cjni_callback_info_create: Unknown type: %#x",
type);
type_str = "match";
break;
+ case CB_TYPE_TARGET:
+ type_str = "target";
+ break;
+
default:
type_str = "<unknown>";
}
} /* }}} int cjni_notification */
/* Callbacks for matches implemented in Java */
-static int cjni_match_create (const oconfig_item_t *ci, /* {{{ */
+static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */
void **user_data)
{
JNIEnv *jvm_env;
cjni_callback_info_t *cbi_factory;
const char *name;
jobject o_ci;
+ int type;
size_t i;
cbi_ret = NULL;
BAIL_OUT (-1);
}
+ /* Find out whether to create a match or a target. */
+ if (strcasecmp ("Match", ci->key) == 0)
+ type = CB_TYPE_MATCH;
+ else if (strcasecmp ("Target", ci->key) == 0)
+ type = CB_TYPE_TARGET;
+ else
+ {
+ ERROR ("java plugin: cjni_match_target_create: Can't figure out whether "
+ "to create a match or a target.");
+ BAIL_OUT (-1);
+ }
+
/* This is the name of the match we should create. */
name = ci->values[0].value.string;
cbi_factory = NULL;
for (i = 0; i < java_callbacks_num; i++)
{
- if (java_callbacks[i].type != CB_TYPE_MATCH)
+ if (java_callbacks[i].type != type)
continue;
if (strcmp (name, java_callbacks[i].name) != 0)
/* Nope, no factory for that name.. */
if (cbi_factory == NULL)
{
- ERROR ("java plugin: cjni_match_create: "
+ ERROR ("java plugin: cjni_match_target_create: "
"No such match factory registered: %s",
name);
BAIL_OUT (-1);
o_ci = ctoj_oconfig_item (jvm_env, ci);
if (o_ci == NULL)
{
- ERROR ("java plugin: cjni_match_create: ctoj_oconfig_item failed.");
+ ERROR ("java plugin: cjni_match_target_create: "
+ "ctoj_oconfig_item failed.");
BAIL_OUT (-1);
}
cbi_ret = (cjni_callback_info_t *) malloc (sizeof (*cbi_ret));
if (cbi_ret == NULL)
{
- ERROR ("java plugin: cjni_match_create: ctoj_oconfig_item failed.");
+ ERROR ("java plugin: cjni_match_target_create: malloc failed.");
BAIL_OUT (-1);
}
memset (cbi_ret, 0, sizeof (*cbi_ret));
cbi_ret->object = NULL;
+ cbi_ret->type = type;
/* Lets fill the callback info structure.. First, the name: */
cbi_ret->name = strdup (name);
if (cbi_ret->name == NULL)
{
- ERROR ("java plugin: cjni_match_create: strdup failed.");
+ ERROR ("java plugin: cjni_match_target_create: strdup failed.");
BAIL_OUT (-1);
}
cbi_factory->object, cbi_factory->method, o_ci);
if (cbi_ret->object == NULL)
{
- ERROR ("java plugin: cjni_match_create: CallObjectMethod failed.");
+ ERROR ("java plugin: cjni_match_target_create: CallObjectMethod failed.");
BAIL_OUT (-1);
}
cbi_ret->class = (*jvm_env)->GetObjectClass (jvm_env, cbi_ret->object);
if (cbi_ret->class == NULL)
{
- ERROR ("java plugin: cjni_match_create: GetObjectClass failed.");
+ ERROR ("java plugin: cjni_match_target_create: GetObjectClass failed.");
BAIL_OUT (-1);
}
/* Lookup the `int match (DataSet, ValueList)' method. */
cbi_ret->method = (*jvm_env)->GetMethodID (jvm_env, cbi_ret->class,
- "match", "(Lorg/collectd/api/DataSet;Lorg/collectd/api/ValueList;)I");
+ /* method name = */ (type == CB_TYPE_MATCH) ? "match" : "invoke",
+ "(Lorg/collectd/api/DataSet;Lorg/collectd/api/ValueList;)I");
if (cbi_ret->method == NULL)
{
- ERROR ("java plugin: cjni_match_create: GetMethodID failed.");
+ ERROR ("java plugin: cjni_match_target_create: GetMethodID failed.");
BAIL_OUT (-1);
}
cjni_thread_detach ();
- DEBUG ("java plugin: cjni_match_create: Successfully created a `%s' match.",
- cbi_ret->name);
+ DEBUG ("java plugin: cjni_match_target_create: "
+ "Successfully created a `%s' %s.",
+ cbi_ret->name, (type == CB_TYPE_MATCH) ? "match" : "target");
/* Success! */
return (0);
#undef BAIL_OUT
-} /* }}} int cjni_match_create */
+} /* }}} int cjni_match_target_create */
-static int cjni_match_destroy (void **user_data) /* {{{ */
+static int cjni_match_target_destroy (void **user_data) /* {{{ */
{
cjni_callback_info_destroy (*user_data);
*user_data = NULL;
return (0);
-} /* }}} int cjni_match_destroy */
+} /* }}} int cjni_match_target_destroy */
-static int cjni_match_match (const data_set_t *ds, /* {{{ */
- const value_list_t *vl, notification_meta_t **meta, void **user_data)
+static int cjni_match_target_invoke (const data_set_t *ds, /* {{{ */
+ value_list_t *vl, notification_meta_t **meta, void **user_data)
{
JNIEnv *jvm_env;
cjni_callback_info_t *cbi;
if (jvm == NULL)
{
- ERROR ("java plugin: cjni_match_match: jvm == NULL");
+ ERROR ("java plugin: cjni_match_target_invoke: jvm == NULL");
return (-1);
}
o_vl = ctoj_value_list (jvm_env, ds, vl);
if (o_vl == NULL)
{
- ERROR ("java plugin: cjni_match_match: ctoj_value_list failed.");
+ ERROR ("java plugin: cjni_match_target_invoke: ctoj_value_list failed.");
cjni_thread_detach ();
return (-1);
}
o_ds = ctoj_data_set (jvm_env, ds);
if (o_ds == NULL)
{
- ERROR ("java plugin: cjni_match_match: ctoj_value_list failed.");
+ ERROR ("java plugin: cjni_match_target_invoke: ctoj_value_list failed.");
cjni_thread_detach ();
return (-1);
}
ret_status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object, cbi->method,
o_ds, o_vl);
- DEBUG ("java plugin: cjni_match_match: Method returned %i.", ret_status);
+ DEBUG ("java plugin: cjni_match_target_invoke: Method returned %i.", ret_status);
+
+ /* If we're executing a target, copy the `ValueList' back to our
+ * `value_list_t'. */
+ if (cbi->type == CB_TYPE_TARGET)
+ {
+ value_list_t new_vl;
+
+ memset (&new_vl, 0, sizeof (new_vl));
+ status = jtoc_value_list (jvm_env, &new_vl, o_vl);
+ if (status != 0)
+ {
+ ERROR ("java plugin: cjni_match_target_invoke: "
+ "jtoc_value_list failed.");
+ }
+ else /* if (status == 0) */
+ {
+ /* plugin_dispatch_values assures that this is dynamically allocated
+ * memory. */
+ sfree (vl->values);
+
+ /* This will replace the vl->values pointer to a new, dynamically
+ * allocated piece of memory. */
+ memcpy (vl, &new_vl, sizeof (*vl));
+ }
+ } /* if (cbi->type == CB_TYPE_TARGET) */
status = cjni_thread_detach ();
if (status != 0)
ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
return (ret_status);
-} /* }}} int cjni_match_match */
+} /* }}} int cjni_match_target_invoke */
/* Iterate over `java_callbacks' and call all CB_TYPE_INIT callbacks. */
static int cjni_init_plugins (JNIEnv *jvm_env) /* {{{ */
if (jvm == NULL)
{
- ERROR ("java plugin: cjni_match_match: jvm == NULL");
+ ERROR ("java plugin: cjni_init: jvm == NULL");
return (-1);
}