Previous Contents Index Next |
iPlanet Calendar Server 5.0 Programmer's Reference |
Chapter 5 Event Notification Service API Reference
This chapter details the ENS API; it is divided into four main sections:
Publisher API
Publisher API Functions List
This chapter includes a description of the following Publisher functions, listed in Table 5-1:
Subscriber API Functions List
This chapter includes a description of following Subscriber functions, listed in Table 5-2:
Table 5-2 ENS Subscriber API Functions List
Generic callback function acknowledging an asynchronous call.
Synchronous callback; called upon receipt of a notification.
Publish and Subscribe Dispatcher Functions List
This chapter includes a description of the following Publish and Subscribe Dispatcher functions, listed in Table 5-3:
The Publisher API consists of one definition and nine functions:
publisher_t
Syntax
typedef struct enc_struct publisher_t;
[Return to Publisher API List]
[Top of Chapter 5]
Purpose.
Generic callback function invoked by ENS to acknowledge an asynchronous call.
Syntax
typedef void (*publisher_cb_t) (void *arg, int rc, void *data);
">
Parameters
Returns
Nothing.
[Return to Publisher API List]
[Top of Chapter 5]
Purpose
Creates a new asynchronous publisher.
Syntax
void publisher_new_a (pas_dispatcher_t *disp,
void *worker,
const char *host,
unsigned short port,
publisher_cb_t cbdone,
void *cbarg);
Application worker. If not NULL, grouped with existing workers created by ENS to service this publisher session. Used to prevent multiple threads from accessing the publisher data at the same time.
The callback invoked when the publisher has been successfully create, or could not be created.
">
Parameters
Returns
Nothing. It passes the new active publisher as third argument of cbdone callback.
[Return to Publisher API List]
[Top of Chapter 5]
Purpose
Creates a new synchronous publisher.
Syntax
publisher_t *publisher_new_s (pas_dispatcher_t *disp,
void *worker,
const char *host,
unsigned short port);
Application worker. If not NULL, grouped with existing workers created by ENS to service this publisher session. Used to prevent multiple threads from accessing the publisher data at the same time.
">
Parameters
Application worker. If not NULL, grouped with existing workers created by ENS to service this publisher session. Used to prevent multiple threads from accessing the publisher data at the same time.
Returns
A new active publisher (publisher_t).
[Return to Publisher API List]
[Top of Chapter 5]
Purpose
Sends an asynchronous notification to the notification service.
Syntax
void publish_a (publisher_t *publisher,
const char *event_ref,
const char *data,
unsigned int datalen,
publisher_cb_t cbdone,
publisher_cb_t end2end_ack,
void *cbarg,
unsigned long timeout);
The event reference. This is a URI identifying the modified resource.
The event data. The body of the notification message. It must be MIME object. It is opaque to the notification service, which merely relays it to the events' subscriber.
The callback invoked when the data has been accepted or deemed unacceptable by the notification service. What makes a notification acceptable depends on the protocol used. The protocol may choose to use the transport acknowledgment (TCP) or use its own acknowledgment response mechanism.
The callback function invoked after acknowledgment from the consumer peer (in an RENL) has been received. Used only in the context of an RENL.
">
Parameters
Returns
Nothing.
[Return to Publisher API List]
[Top of Chapter 5]
Purpose
Sends a synchronous notification to the notification service.
Syntax
int publish_s (publisher_t *publisher,
const char *event_ref,
const char *data,
unsigned int datalen);
The event reference. This is a URI identifying the modified resource.
The event data. The body of the notification message. It must be a MIME object. It is opaque to the notification service, which relays it to the events' subscriber.
">
Parameters
Returns
Zero if successful; a failure code if unsuccessful. If an RENL, the call does not return until the consumer has completely processed the notification and has successfully acknowledged it.
[Return to Publisher API List]
[Top of Chapter 5]
Purpose
Terminates a publish session.
Syntax
void publisher_delete (publisher_t *publisher);
">
Parameters
Returns
Nothing.
[Return to Publisher API List]
[Top of Chapter 5]
Purpose
Creates a subscriber using the credentials of the publisher.
Syntax
struct subscriber_struct * publisher_get_subscriber(publisher_t *publisher);
The publisher whose credentials are used to create the subscriber.
">
Parameters
The publisher whose credentials are used to create the subscriber.
Returns
The subscriber, or NULL if the creation failed. If the creation failed, use the subscriber_new to create the subscriber.
[Return to Publisher API List]
[Top of Chapter 5]
Purpose
Declares an RENL, which enables the end2end_ack invocation. After this call returns, the end2end_ack argument is invoked when an acknowledgment notification matching the specified publisher and subscriber is received.
Syntax
void renl_create_publisher (publisher_t *publisher,
const char *renl_id,
const char *subscriber,
publisher_cb_t cbdone,
void *cbarg);
The unique RENL identifier. This allows two peers to be able to set up multiple RENL's between them.
">
Parameters
The unique RENL identifier. This allows two peers to be able to set up multiple RENL's between them.
Returns
Nothing.
[Return to Publisher API List]
[Top of Chapter 5]
Purpose
This cancels an RENL. This does not prevent more notifications being sent, but should a client acknowledgment be received, the end2end_ack argument of publish will no longer be invoked. All RENL's are automatically destroyed when the publisher is deleted. Therefore, this function does not need to be called to free RENL-related memory before deleting a publisher.
Syntax
void renl_cancel_publisher (renl_t *renl);
">
Parameters
Returns
Nothing.
[Return to Publisher API List]
[Top of Chapter 5]
The Subscriber API includes two definitions and ten functions:
subscriber_t
Syntax
typedef struct enc_struct subscriber_t;
[Return to Subscriber API List]
[Top of Chapter 5]
Syntax
typedef struct subscription_struct subscription_t;
[Return to Subscriber API List]
[Top of Chapter 5]
Purpose
Generic callback function invoked by ENS to acknowledge an asynchronous call.
Syntax
typedef void (*subscriber_cb_t) (void *arg,
int rc,
void *data);
">
Parameters
Returns
Nothing
[Return to Subscriber API List]
[Top of Chapter 5]
Purpose
Subscriber callback; called upon receipt of a notification.
Syntax
typedef void (*subscriber_notify_cb_t) (void *arg,
char *event,
char *data,
int datalen);
The event reference (URI). The notification event reference matches the subscription, but may contain additional information called event attributes, such as a uid.
">
Parameters
The event reference (URI). The notification event reference matches the subscription, but may contain additional information called event attributes, such as a uid.
Returns
Zero if successful, non-zero otherwise.
[Return to Subscriber API List]
[Top of Chapter 5]
Purpose
Creates a new asynchronous subscriber.
Syntax
void subscriber_new_a (pas_dispatcher_t *disp,
void *worker,
const char *host,
unsigned short port,
subscriber_cb_t cbdone,
void *cbarg);
Application worker. If not NULL, grouped with existing workers created by ENS to service this subscriber session. Used to prevent multiple threads from accessing the subscriber data at the same time. Only usable if the caller creates and dispatches the GDisp context.
The callback invoked when the subscriber session becomes active and subscriptions can be issued.
">
Parameters
Returns
Nothing. It passes the new active subscriber as third argument of cbdone callback.
[Return to Subscriber API List]
[Top of Chapter 5]
Purpose
Creates a new synchronous subscriber.
Syntax
subscriber_t *subscriber_new_s (pas_dispatcher_t *disp,
const char *host,
unsigned short port);
Publish and subscribe dispatcher returned by pas_dispatcher_new.
Application worker. If not NULL, grouped with existing workers created by ENS to service this publisher session. Used to prevent multiple threads from accessing the publisher data at the same time. Only usable if the caller creates and dispatches the GDisp context.
">
Parameters
Returns
A new active subscriber (subscriber_t).
[Return to Subscriber API List]
[Top of Chapter 5]
Establishes an asynchronous subscription.
Syntax
void subscribe_a (subscriber_t *subscriber,
const char *event_ref,
subscriber_notify_cb_t notify_cb,
void *notify_arg,
subscriber_cb_t cbdone,
void *cbarg):
The event reference. This is a URI identifying the event's source.
The callback invoked upon receipt of a notification matching this subscription.
The first argument of notify_arg. May be called at any time, by any thread, while the subscription is still active.
Called when an unsubscribe completes. It has three Parameters:
">
Parameters
Returns
Nothing.
[Return to Subscriber API List]
[Top of Chapter 5]
Cancels an asynchronous subscription.
Syntax
void unsubscribe_a (subscriber_t *subscriber,
subscription_t *subscription,
subscriber_cb_t cbdone,
void *cbarg);
Called when an unsubscribe completes. It has three parameters:
">
Parameters
Called when an unsubscribe completes. It has three parameters:
Returns
Nothing.
[Return to Subscriber API List]
[Top of Chapter 5]
Purpose
Terminates a subscriber.
Syntax
void subscriber_delete (subscriber_t *subscriber);
">
Parameters
Returns.
[Return to Subscriber API List]
[Top of Chapter 5]
Purpose
Creates a publisher, using the credentials of the subscriber.
Syntax
struct publisher_struct *subscriber_get_publisher (subscriber_t *subscriber);
The subscriber whose credentials are used to create the publisher.
">
Parameters
The subscriber whose credentials are used to create the publisher.
Returns
The publisher, or NULL if creation failed. In case the creation fails, use the publisher_new.
[Return to Subscriber API List]
[Top of Chapter 5]
Purpose
Creates the subscription part of an RENL.
Syntax
renl_t *renl_create_subscriber (subscription_t *subscription,
const char *renl_id,
const char *publisher);
The unique RENL identifier. This allows two peers to be able to set up multiple RENL's between them.
">
Parameters
The unique RENL identifier. This allows two peers to be able to set up multiple RENL's between them.
Returns
The opaque RENL object.
[Return to Subscriber API List]
[Top of Chapter 5]
Purpose
This cancels an RENL. It does not cancel a subscription. It tells ENS not to acknowledge any more notifications received for this subscription. It destroys the RENL object, the application may no longer use this RENL. All RENLs are automatically destroyed when the subscription is canceled. Therefore, this function does not need to be called to free RENL-related memory before deleting a subscriber.
Syntax
void renl_cancel_subscriber (renl_t *renl);
">
Parameters
Returns
Nothing.
[Return to Subscriber API List]
[Top of Chapter 5]
Publish and Subscribe Dispatcher API
The Publish and Subscribe Dispatcher API includes one definition and four functions:
Purpose
A publish and subscribe dispatcher.
Syntax
typedef struct pas_dispatcher_struct pas_dispatcher_t;
[Top of Chapter 5]
Purpose
Creates or advertises a dispatcher
Syntax
pas_dispatcher_t *pas_dispatcher_new (void *disp);
The dispatcher context. If NULL,to start dispatching notifications, the application must call pas_dispatch.
">
Parameters
The dispatcher context. If NULL,to start dispatching notifications, the application must call pas_dispatch.
Returns
The dispatcher to use when creating publishers or subscribers (pas_dispatcher_t).
[Return to Publish and Subscribe Dispatcher API]
[Top of Chapter 5]
Purpose
Destroys a dispatcher created with pas_dispatcher_new.
Syntax
void pas_dispatcher_delete (pas_dispatcher_t *disp);
">
Parameters
Returns
Nothing.
[Return to Publish and Subscribe Dispatcher API]
[Top of Chapter 5]
Purpose
Starts the dispatch loop of an event notification environment. It has no effect if the application uses its own thread pool.
Syntax
void pas_dispatch (pas_dispatcher_t *disp);
">
Parameters
Returns
Nothing.
[Return to Publish and Subscribe Dispatcher API]
[Top of Chapter 5]
Purpose
Stops the dispatch loop of an event notification environment started with pas_dispatch. It has no effect if an application-provided dispatcher was passed to pas_dispatcher_new.
Syntax
void pas_shutdown (pas_dispatcher_t *disp);
">
Parameters
Returns
[Return to Publish and Subscribe Dispatcher API]
[Top of Chapter 5]
Sample Code
iPlanet Calendar Server ships with a complete ENS implementation. If you wish to customize it, you may use these APIs to do so. The following four code samples, a simple publisher and subscriber pair, and a reliable publisher and subscriber pair, illustrate how to use the API. The sample code is provided with the product in the following directory:/opt/SUNWics5/cal/csapi/samples/ens
Simple Publisher and Subscriber
This sample code pair establishes a simple interactive asynchronous publisher and subscriber.
Publisher Code Sample
/*
* Copyright 2000 by Sun Microsystems, Inc.
* All rights reserved
*
* apub : simple interactive asynchronous publisher using
*
* Syntax:
* apub host port
*/#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 _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;
}static void _publish_ack(void *arg, int rc, void *ignored)
{
(void *)ignored;printf("Publish failed with status %d\n", rc);
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://yoyo.com/xyz",message,
message_len,
_publish_ack, NULL, (void *)message, 0);
return;
}
}
return;
}main(int argc, char **argv)
{
unsigned short port = 7997;
char host[256];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);
Subscriber Code Sample
/*
* Copyright 1997 by Sun Microsystems, Inc.
* All rights reserved
*
* asub : example asynchronous subscriber
*
* Syntax:
* asub host port
*/#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");
} 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://yoyo.com/xyz",
_handle_notify, NULL,
_subscribe_ack, NULL);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);
Reliable Publisher and Subscriber
This sample code pair establishes a reliable asynchronous publisher and subscriber.
Reliable Publisher Sample
/*
* Copyright 2000 by Sun Microsystems, Inc.
* All rights reserved
*
* rpub : simple *reliable* interactive asynchronous publisher.
* It is designed to be used in combination with rsub,
* the reliable subscriber.
*
* Syntax:
* rpub host port
*/#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 renl_t *_renl;printf("\nUsage:\n rpub host port\n");
static void _exit_error(const char *msg)
{
printf("%s\n", msg);
exit(1);
}static void _call_shutdown()
{
_shutdown = 1;
pas_shutdown(disp);
}static void _renl_create_cb(void *arg, int rc, void *ignored)
{
(void *)arg;
(void *)ignored;if (!_publisher)
{
printf("Failed to create RENL - status %d\n", rc);
_call_shutdown();
return;
}static void _publisher_new_cb(void *arg, int rc, void *enc)
{
_publisher = (publisher_t *)enc;if (!_publisher)
{
printf("Failed to create publisher - status %d\n", rc);
_call_shutdown();
return;
}renl_create_publisher(_publisher, "renl_id", NULL,
_renl_create_cb,NULL);static void _recv_ack(void *arg, int rc, void *ignored)
{
(void *)ignored;if (rc < 0)
{
printf("Acknowledgment Timeout\n");
} else if ( rc == 0) {
printf("Acknowledgment Received\n");
}
fflush (stdout);static void _read_stdin()
{
static char input[1024];printf("rpub> ");
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);/* five seconds timeout */
publish(_publisher, "enp://yoyo.com/xyz",
message, message_len,
NULL, _recv_ack, message, 5000);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, _publisher_new_cb,
NULL);
Reliable Subscriber Sample
/*
* Copyright 1997 by Sun Microsystems, Inc.
* All rights reserved
*
* asub : example asynchronous subscriber
*
* Syntax:
* asub host port
*/#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");
_renl = renl_create_subscriber(_subscription, "renl_id", NULL);
} 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://yoyo.com/xyz",_handle_notify,
NULL,_subscribe_ack, NULL);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");
Previous Contents Index Next
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.
Last Updated February 20, 2001