Sun Java System Communications Services 6 2004Q2 Event Notification Service Guide |
Chapter 4
Messaging Server Specific InformationThis chapter describes the Messaging Server specific items you need to use the ENS APIs.
This chapter contains these sections:
Event Notification Types and ParametersFor Messaging Server, there is only one event reference, which can be composed of several parameters. There are various types of event notifications. Table 4-1 lists the event types supported by Messaging Server and gives a description of each:
The following applies to the above supported event types:
- For NewMsg and UpdateMsg, message pay load is turned off by default to prevent overloading ENS. For information on how to enable the payload, see Payload. No other event types support a payload.
- Event notifications can be generated for changes to the INBOX alone, or to the INBOX and all other folders. The following configuration variable allows for INBOX only (value = 0), or for both the INBOX and all other folders (value = 1):
local.store.notifyplugin.noneInbox.enable
- The NewMsg notification is issued only after the message is deposited in the user mailbox (as opposed to “after it was accepted by the server and queued in the message queue”).
- Every notification carries several pieces of information (called parameters) depending on the event type, for example, NewMsg indicates the IMAP uid of the new message. For details on the parameters each event type takes, see Available Parameters for Each Event Type.
- Events are not generated for POP3 client access.
- All event types can be suppressed by issuing XNOTNOTIFY. For example, an IMAP script used for housekeeping only (the users are not meant to be notified) might issue it to suppress all events.
Parameters
iBiff uses the following format for the ENS event reference:
enp://127.0.0.1/store?param=value¶m1=value1¶m2=value2
The event key enp://127.0.0.1/store has no significance other than its uniqueness as a string. For example, the hostname portion of the event key has no significance as a hostname. It is simply a string that is part of the URI. However, the event key is user configurable. The list of iBiff event reference parameters is listed in Table 4-2 and Table 4-3 that follow.
The second part of the event reference consists of parameter-value pairs. This part of the event reference is separated from the event key by a question mark (?). The parameter and value are separated by an equals sign (=). The parameter-value pairs are separated by an ampersand (&). Note that there can be empty values, for which the value simply does not exist.
Table 4-2 describes the mandatory event reference parameters that need to be included in every notification.
Table 4-3 describes optional event reference parameters, which might be seen in the event depending on the event type (see Table 4-4).
Note
Subscribers should allow for undocumented parameters when parsing the event reference. This allows for future compatibility when new parameters are added.
Table 4-4 shows the parameters that are available for each event type. For example, to see which parameters apply to a TrashMsg event, look in the column header for “ReadMsg, TrashMsg” and then note that these events can use numDel, numMsgs, numSeen, and userValidity.
Payload
ENS allows a payload for two event types: NewMsg, and UpdateMsg; the other event types do not carry a payload. The payload portion of these two notifications can contain any of the following data:
The amount and type of data sent as the payload of the ENS event is determined by the confiuration parameters found in Table 4-5.
Note that both parameters are set to zero as the default so that no header or body data is sent with ENS notifications.
Examples
The following example shows a NewMsg event reference (it is actually a single line that is broken up to several lines for readability):
enp://127.0.0.1/store?evtType=NewMsg×tamp=1047488403000&
hostname=eman&process=imta&pid=476&mailboxName=testuser&numMsgs=16 &uidValidity=1046993605&imapUid=62&size=877&hdrLen=814
In this example, for the DeleteMsg event. Messages marked as deleted by IMAP or HTTP were expunged. The user would not see the message in the folder any more.
enp://127.0.0.1/store?evtType=DeleteMsg×tamp=1047488588000&
hostname=eman&process=imapd&pid=419&mailboxName=testuser&
numMsgs=6&uidValidity=1046993605&imapUid=61&lastUid=62
And a third example shows a ReadMsg event. Message was marked as Seen by IMAP or HTTP.
enp://127.0.0.1/store?evtType=ReadMsg×tamp=1047488477000&
hostname=eman&process=imapd&pid=419&mailboxName=testuser&
uidValidity=1046993605&numSeen=11&numDel=9&numMsgs=16
Sample CodeThe following two code samples illustrate how to use the ENS API. The sample code is provided with the product in the following directory:
msg_server_base/examples
How to Use the Sample Code
- Before running the makefile, set your library search path to include the directory:
msg_server_base/lib
- Compile the code using the Makefile.sample.
- Run apub and asub as follows in separate windows:
apub localhost 7997
asub localhost 7997
Whatever is typed into the apub window should appear on the asub window. If you use the default settings, all iBiff notifications should appear in the asub window.
Sample Publisher
This sample code provides a simple interactive asynchronous publisher.
/*
* Copyright 2000 by Sun Microsystems, Inc.
* All rights reserved
*/
/*
*
* apub
* --
* a simple interactive asynchronous publisher
* --
*
* This simplistic program publishes events using the hard-coded
* event reference
* enp://127.0.0.1/store
* and the data entered at the prompt as notification payload.
* Enter "." to end the program.
*
* If you happen to run the corresponding subscriber, asub, on the
* same notification server, you will notice the sent data printed
* out in the asub window.
* Syntax:
* $ apub <host> <port>
* where
* <host> is the notification server hostname
* <port> is the notification server IP port number
*/#include <stdlib.h>
#include <stdio.h>#include "pasdisp.h"
#include "publisher.h"static pas_dispatcher_t *disp = NULL;
static publisher_t *_publisher = NULL;
static int _shutdown = 0;
static void _read_stdin();static void _exit_usage()
{
printf("\nUsage:\n apub host port\n");
exit(5);
}static void _exit_error(const char *msg)
{
printf("%s\n", msg);
exit(1);
}static void _call_shutdown()
{
_shutdown = 1;
pas_shutdown(disp);
}static void _open_ack(void *arg, int rc, void *enc)
{
_publisher = (publisher_t *)enc;
(void *)arg;if (!_publisher) {
printf("Failed to create publisher with status %d\n", rc);
_call_shutdown();
return;
}
_read_stdin();
return;
}static void _publish_ack(void *arg, int rc, void *ignored)
{
(void *)ignored;
free(arg)
if (rc != 0) {
printf("Publish failed with status %d\n", rc);
_call_shutdown();
return;
}_read_stdin();
return;
}static void _read_stdin()
{
static char input[1024];
printf("apub> ");
fflush(stdout);
while (!_shutdown) {
if ( !fgets(input, sizeof(input), stdin) ) {
continue;
} else {
char *message;
unsigned int message_len;
input[strlen(input) - 1] = 0; /* Strip off the \n */
if (*input == ’.’ && input[1] == 0) {
publisher_delete(_publisher);
_call_shutdown();
break;
}
message = strdup(input);
message_len = strlen(message);
publish(_publisher, "enp://127.0.0.1/store",
message, message_len,
_publish_ack, NULL, (void *)message, 0);
return;
}
}
return;
}main(int argc, char **argv)
{
unsigned short port = 7997;
char host[256];
if (argc < 2) _exit_usage();
if (*(argv[1]) == ’0’) {
strcpy(host, "127.0.0.1");
}else {
strcpy(host, argv[1]);
}
if (argc > 2) {
port = (unsigned short)atoi(argv[2]);
}
disp = pas_dispatcher_new(NULL);
if (disp == NULL) _exit_error("Can’t create publisher");
publisher_new_a(disp, NULL, host, port, _open_ack, disp);
pas_dispatch(disp);
_shutdown = 1;
pas_dispatcher_delete(disp);
exit(0);
}Sample Subscriber
This sample code provides a simple subscriber.
/*
* Copyright 1997 by Sun Microsystems, Inc.
* All rights reserved
*
*//*
*
* asub
* --
* a simple subscriber
* --
*
* This simplistic program subscribes to events matching the
* hard-coded event reference:
* enp://127.0.0.1/store
* It subsequently received messages emitted by the apub processes
* if any are being used, and prints the payload of each received
* notification to stdout.
*
* Syntax
* $ asub <host> <port>
* where
* <host> is the notification server hostname
* <port> is the notification server IP port number
*/#include <stdlib.h>
#include <stdio.h>#include "pasdisp.h"
#include "subscriber.h"static pas_dispatcher_t *disp = NULL;
static subscriber_t *_subscriber = NULL;
static subscription_t *_subscription = NULL;
static renl_t *_renl = NULL;static void _exit_usage()
{
printf("\nUsage:\n asub host port\n");
exit(5);
}static void _exit_error(const char *msg)
{
printf("%s\n", msg);
exit(1);
}static void _subscribe_ack(void *arg, int rc, void *subscription)
{
(void)arg;
if (!rc) {
_subscription = subscription;
printf("Subscription successful\n");
subscriber_keepalive(_subscriber, 30000);
}else {
printf("Subscription failed - status %d\n", rc);
pas_shutdown(disp);
}
}static void _unsubscribe_ack(void *arg, int rc, void *ignored)
{
(void *)ignored;
(void *)arg;
if (rc != 0) {
printf("Unsubscribe failed - status %d\n", rc);
}
subscriber_delete(_subscriber);
pas_shutdown(disp);
}static int _handle_notify(void *arg, char *url, char *str, int len)
{
(void *)arg;
printf("[%s] %.*s\n", url, len, (str) ? str : "(null)");
return 0;
}static void _open_ack(void *arg, int rc, void *enc)
{
_subscriber = (subscriber_t *)enc;
(void *)arg;
if (rc) {
printf("Failed to create subscriber with status %d\n", rc);
pas_shutdown(disp);
return;
}subscribe(_subscriber, "enp://127.0.0.1/store",
_handle_notify, NULL,
_subscribe_ack, NULL);
return;
}static void _unsubscribe(int sig)
{
(int)sig;
unsubscribe(_subscriber, _subscription, _unsubscribe_ack, NULL);
}main(int argc, char **argv)
{
unsigned short port = 7997;
char host[256];
if (argc < 2) _exit_usage();
if (*(argv[1]) == ’0’) {
strcpy(host, "127.0.0.1");
}else {
strcpy(host, argv[1]);
}
if (argc > 2) {
port = (unsigned short)atoi(argv[2]);
} disp = pas_dispatcher_new(NULL);
if (disp == NULL) _exit_error("Can’t create publisher");
subscriber_new_a(disp, NULL, host, port, _open_ack, NULL);
pas_dispatch(disp);
pas_dispatcher_delete(disp);
exit(0);
}
Implementation NotesThe current implementation does not provide security on events that can be subscribed to. Thus, a user could register for all events, and portions of all other users’ mail. Because of this it is strongly recommended that the ENS subscriber be on the “safe” side of the firewall at the very least.