summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9c8848b)
raw | patch | inline | side by side (parent: 9c8848b)
author | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Mon, 23 Feb 2009 13:57:56 +0000 (14:57 +0100) | ||
committer | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Mon, 23 Feb 2009 13:57:56 +0000 (14:57 +0100) |
bindings/java/org/collectd/api/Collectd.java | patch | blob | history | |
bindings/java/org/collectd/api/CollectdNotificationInterface.java | [new file with mode: 0644] | patch | blob |
src/collectd-java.pod | patch | blob | history | |
src/java.c | patch | blob | history |
diff --git a/bindings/java/org/collectd/api/Collectd.java b/bindings/java/org/collectd/api/Collectd.java
index eb96969a5c7161fec6bd4a379f6484fee95ff5c0..92ddec02f40c8f3de784b7546549b15cb81b9de2 100644 (file)
native public static int registerLog (String name,
CollectdLogInterface object);
+ /**
+ * Java representation of collectd/src/plugin.h:plugin_register_notification
+ */
+ native public static int registerNotification (String name,
+ CollectdNotificationInterface object);
+
/**
* Java representation of collectd/src/plugin.h:plugin_dispatch_values
*/
diff --git a/bindings/java/org/collectd/api/CollectdNotificationInterface.java b/bindings/java/org/collectd/api/CollectdNotificationInterface.java
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * collectd/java - org/collectd/api/CollectdNotificationInterface.java
+ * Copyright (C) 2009 Florian octo Forster
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Florian octo Forster <octo at verplant.org>
+ */
+
+package org.collectd.api;
+
+/**
+ * Interface for objects implementing a notification function.
+ *
+ * @author Florian Forster <octo at verplant.org>
+ * @see Collectd#registerNotification
+ */
+public interface CollectdNotificationInterface
+{
+ public int notification (Notification n);
+}
diff --git a/src/collectd-java.pod b/src/collectd-java.pod
index 72ce0b6939c3545529566aa225b1aa0a3d333b6d..773130acc18e495f3f65bd757ae8219a9c5104e1 100644 (file)
--- a/src/collectd-java.pod
+++ b/src/collectd-java.pod
Corresponds to C<value_list_t>, defined in F<src/plugin.h>.
+=item B<org.collectd.api.Notification>
+
+Corresponds to C<notification_t>, defined in F<src/plugin.h>.
+
=back
In the remainder of this document, we'll use the short form of these names, for
The function does not return any value.
+=head2 notification callback
+
+Interface: B<org.collectd.api.CollectdNotificationInterface>
+
+Signature: I<int> B<notification> (I<Notification> n)
+
+This callback can be used to receive notifications from the daemon.
+
+To signal success, this method has to return zero. Anything else will be
+considered an error condition and cause an appropriate message to be logged.
+
=head2 Example
This short example demonstrates how to register a read callback with the
Returns zero upon success and non-zero when an error occurred.
+=head2 registerNotification
+
+Signature: I<int> B<registerNotification> (I<String> name,
+I<CollectdNotificationInterface> object);
+
+Registers the B<notification> function of I<object> with the daemon.
+
+Returns zero upon success and non-zero when an error occurred.
+
=head2 dispatchValues
Signature: I<int> B<dispatchValues> (I<ValueList>)
diff --git a/src/java.c b/src/java.c
index fc332e50587bc25be8cad182831e3f059ac7733c..2d310c6f4c2947f2df3cf311d8d7f8c496aaa03b 100644 (file)
--- a/src/java.c
+++ b/src/java.c
typedef struct java_plugin_config_s java_plugin_config_t;
/* }}} */
-#define CB_TYPE_CONFIG 1
-#define CB_TYPE_INIT 2
-#define CB_TYPE_READ 3
-#define CB_TYPE_WRITE 4
-#define CB_TYPE_FLUSH 5
-#define CB_TYPE_SHUTDOWN 6
-#define CB_TYPE_LOG 7
+#define CB_TYPE_CONFIG 1
+#define CB_TYPE_INIT 2
+#define CB_TYPE_READ 3
+#define CB_TYPE_WRITE 4
+#define CB_TYPE_FLUSH 5
+#define CB_TYPE_SHUTDOWN 6
+#define CB_TYPE_LOG 7
+#define CB_TYPE_NOTIFICATION 8
struct cjni_callback_info_s /* {{{ */
{
char *name;
user_data_t *ud);
static int cjni_flush (int timeout, const char *identifier, user_data_t *ud);
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);
/*
* C to Java conversion functions
}
return (o_valuelist);
-} /* }}} int ctoj_value_list */
+} /* }}} jobject ctoj_value_list */
+
+/* Convert a notification_t to a org.collectd.api.Notification */
+static jobject ctoj_notification (JNIEnv *jvm_env, /* {{{ */
+ const notification_t *n)
+{
+ jclass c_notification;
+ jmethodID m_constructor;
+ jobject o_notification;
+ int status;
+
+ /* First, create a new Notification instance..
+ * Look up the class.. */
+ c_notification = (*jvm_env)->FindClass (jvm_env,
+ "org.collectd.api.Notification");
+ if (c_notification == NULL)
+ {
+ ERROR ("java plugin: ctoj_notification: "
+ "FindClass (org.collectd.api.Notification) failed.");
+ return (NULL);
+ }
+
+ /* Lookup the `Notification ()' constructor. */
+ m_constructor = (*jvm_env)->GetMethodID (jvm_env, c_notification,
+ "<init>", "()V");
+ if (m_constructor == NULL)
+ {
+ ERROR ("java plugin: ctoj_notification: Cannot find the "
+ "`Notification ()' constructor.");
+ return (NULL);
+ }
+
+ /* Create a new instance. */
+ o_notification = (*jvm_env)->NewObject (jvm_env, c_notification,
+ m_constructor);
+ if (o_notification == NULL)
+ {
+ ERROR ("java plugin: ctoj_notification: Creating a new Notification "
+ "instance failed.");
+ return (NULL);
+ }
+
+ /* Set the strings.. */
+#define SET_STRING(str,method_name) do { \
+ status = ctoj_string (jvm_env, str, \
+ c_notification, o_notification, method_name); \
+ if (status != 0) { \
+ ERROR ("java plugin: ctoj_notification: jtoc_string (%s) failed.", \
+ method_name); \
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_notification); \
+ return (NULL); \
+ } } while (0)
+
+ SET_STRING (n->host, "setHost");
+ SET_STRING (n->plugin, "setPlugin");
+ SET_STRING (n->plugin_instance, "setPluginInstance");
+ SET_STRING (n->type, "setType");
+ SET_STRING (n->type_instance, "setTypeInstance");
+ SET_STRING (n->message, "setMessage");
+
+#undef SET_STRING
+
+ /* Set the `time' member. Java stores time in milliseconds. */
+ status = ctoj_long (jvm_env, ((jlong) n->time) * ((jlong) 1000),
+ c_notification, o_notification, "setTime");
+ if (status != 0)
+ {
+ ERROR ("java plugin: ctoj_notification: ctoj_long (setTime) failed.");
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
+ return (NULL);
+ }
+
+ /* Set the `interval' member.. */
+ status = ctoj_int (jvm_env, (jint) n->severity,
+ c_notification, o_notification, "setSeverity");
+ if (status != 0)
+ {
+ ERROR ("java plugin: ctoj_notification: ctoj_int (setSeverity) failed.");
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
+ return (NULL);
+ }
+
+ return (o_notification);
+} /* }}} jobject ctoj_notification */
/*
* Java to C conversion functions
return (0);
} /* }}} jint cjni_api_register_log */
+static jint JNICALL cjni_api_register_notification (JNIEnv *jvm_env, /* {{{ */
+ jobject this, jobject o_name, jobject o_notification)
+{
+ user_data_t ud;
+ cjni_callback_info_t *cbi;
+
+ cbi = cjni_callback_info_create (jvm_env, o_name, o_notification,
+ CB_TYPE_NOTIFICATION);
+ if (cbi == NULL)
+ return (-1);
+
+ DEBUG ("java plugin: Registering new notification callback: %s", cbi->name);
+
+ memset (&ud, 0, sizeof (ud));
+ ud.data = (void *) cbi;
+ ud.free_func = cjni_callback_info_destroy;
+
+ plugin_register_notification (cbi->name, cjni_notification, &ud);
+
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
+
+ return (0);
+} /* }}} jint cjni_api_register_notification */
+
static void JNICALL cjni_api_log (JNIEnv *jvm_env, /* {{{ */
jobject this, jint severity, jobject o_message)
{
"(Ljava/lang/String;Lorg/collectd/api/CollectdLogInterface;)I",
cjni_api_register_log },
+ { "registerNotification",
+ "(Ljava/lang/String;Lorg/collectd/api/CollectdNotificationInterface;)I",
+ cjni_api_register_notification },
+
{ "log",
"(ILjava/lang/String;)V",
cjni_api_log },
@@ -1424,6 +1537,11 @@ static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{
method_signature = "(ILjava/lang/String;)V";
break;
+ case CB_TYPE_NOTIFICATION:
+ method_name = "notification";
+ method_signature = "(LLorg/collectd/api/Notification;)I";
+ break;
+
default:
ERROR ("java plugin: cjni_callback_info_create: Unknown type: %#x",
type);
DEBUG ("java plugin: cjni_callback_info_destroy (arg = %p);", arg);
+ cbi = (cjni_callback_info_t *) arg;
+
+ /* This condition can occurr when shutting down. */
+ if (jvm == NULL)
+ {
+ sfree (cbi);
+ return;
+ }
+
if (arg == NULL)
return;
return;
}
- cbi = (cjni_callback_info_t *) arg;
-
(*jvm_env)->DeleteGlobalRef (jvm_env, cbi->object);
cbi->method = NULL;
JNIEnv *jvm_env;
cjni_callback_info_t *cbi;
int status;
+ int ret_status;
if (jvm == NULL)
{
cbi = (cjni_callback_info_t *) ud->data;
- status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object,
+ ret_status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object,
cbi->method);
status = cjni_thread_detach ();
return (-1);
}
- return (status);
+ return (ret_status);
} /* }}} int cjni_read */
/* Call the CB_TYPE_WRITE callback pointed to by the `user_data_t' pointer. */
@@ -1934,6 +2060,7 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
cjni_callback_info_t *cbi;
jobject vl_java;
int status;
+ int ret_status;
if (jvm == NULL)
{
@@ -1960,7 +2087,7 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
return (-1);
}
- status = (*jvm_env)->CallIntMethod (jvm_env,
+ ret_status = (*jvm_env)->CallIntMethod (jvm_env,
cbi->object, cbi->method, vl_java);
(*jvm_env)->DeleteLocalRef (jvm_env, vl_java);
@@ -1972,7 +2099,7 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
return (-1);
}
- return (status);
+ return (ret_status);
} /* }}} int cjni_write */
/* Call the CB_TYPE_FLUSH callback pointed to by the `user_data_t' pointer. */
cjni_callback_info_t *cbi;
jobject o_identifier;
int status;
+ int ret_status;
if (jvm == NULL)
{
}
}
- status = (*jvm_env)->CallIntMethod (jvm_env,
+ ret_status = (*jvm_env)->CallIntMethod (jvm_env,
cbi->object, cbi->method, (jint) timeout, o_identifier);
(*jvm_env)->DeleteLocalRef (jvm_env, o_identifier);
return (-1);
}
- return (status);
+ return (ret_status);
} /* }}} int cjni_flush */
/* Call the CB_TYPE_LOG callback pointed to by the `user_data_t' pointer. */
(*jvm_env)->DeleteLocalRef (jvm_env, o_message);
cjni_thread_detach ();
-} /* }}} int cjni_log */
+} /* }}} void cjni_log */
+
+/* Call the CB_TYPE_NOTIFICATION callback pointed to by the `user_data_t'
+ * pointer. */
+static int cjni_notification (const notification_t *n, /* {{{ */
+ user_data_t *ud)
+{
+ JNIEnv *jvm_env;
+ cjni_callback_info_t *cbi;
+ jobject o_notification;
+ int status;
+ int ret_status;
+
+ if (jvm == NULL)
+ {
+ ERROR ("java plugin: cjni_read: jvm == NULL");
+ return (-1);
+ }
+
+ if ((ud == NULL) || (ud->data == NULL))
+ {
+ ERROR ("java plugin: cjni_read: Invalid user data.");
+ return (-1);
+ }
+
+ jvm_env = cjni_thread_attach ();
+ if (jvm_env == NULL)
+ return (-1);
+
+ cbi = (cjni_callback_info_t *) ud->data;
+
+ o_notification = ctoj_notification (jvm_env, n);
+ if (o_notification == NULL)
+ {
+ ERROR ("java plugin: cjni_notification: ctoj_notification failed.");
+ return (-1);
+ }
+
+ ret_status = (*jvm_env)->CallIntMethod (jvm_env,
+ cbi->object, cbi->method, o_notification);
+
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
+
+ status = cjni_thread_detach ();
+ if (status != 0)
+ {
+ ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
+ return (-1);
+ }
+
+ return (ret_status);
+} /* }}} int cjni_notification */
/* Iterate over `java_classes_list' and create one object of each class. This
* will trigger the object's constructors, to the objects can register callback
sfree (java_classes_list);
/* Destroy the JVM */
+ DEBUG ("java plugin: Destroying the JVM.");
(*jvm)->DestroyJavaVM (jvm);
jvm = NULL;
jvm_env = NULL;