Skip to content

BillingWrite

Function : Billing
BillingWrite - Writes a Billing message record

#include <billing.h>
STATUS LNPUBLIC BillingWrite(

    DWORD  Class,
    WORD  StructType,
    WORD  Len,
    void far *pMessage,
    char far *MQName);
Description :

Use this call to write a billing message record to a message queue. By default the record is written to MQ$Billing. The data in the MQ$Billing queue can then be read by the billing server task.

Only a billing server task can execute BillingWrite(). Typically, the BillingWrite() function is called by an extension manager handler or from within a Lotus Domino Server add-in program.

Parameters : Input : Class - Billing Class values (see BILL_CLASS_xxx).

StructType - Billing Structure type written to the billing queue (see BILL_xxx (structure types)). Note: Custom structure types that are user-defined are also valid.

Len - Size of the billing message to be sent to the message queue.

pMessage - Address of the billing message data structure to be sent to the message queue.

MQName - Name of the message queue. NULL defaults to MQ$Billing.

Output : (routine) -
If the message is written successfully to the Billing queue; NOERROR. If pMessage is not present; ERR_BAD_PARAM. If MQ error; then returns that error (see MQPut function for error details).

Sample Usage :

/* This is a sample Extension Manager Handler for using
   BillingWrite() to bill note creations*/

/* The following are additions/modifications that were made to a
   copy of the supplied C API include file billing.h in order
    to support the user extensions added here.*/

#define BILL_NOTECREATEREC  32001  /* new billing type */

typedef struct
      {
 char      Username[MAXUSERNAME+1];/* Username */
 NOTEID    dbNoteID;               /* Created note id */ 
    TIMEDATE  ReplicaID;              /* Database replica id */
   } NOTECREATEREC;


/* The following is a modified billing message structure taken
    from the C API include file billing.h  Typically, this code
    would replace the respective code that appears in billing.h  */

typedef union
{
   SESSIONREC    sess;
   REPLREC       repl;
   DOCUMENT      doc;
   MAILREC       mail;
   DBREC         db;
   AGENTREC      agent;
   HTTPREQREC    HttpRequest;
   NOTECREATEREC notecreate;
} BILLREC;


/* The following is a sample extension handler that sends billing
   records to the billing message queue after every sucessful 
   NFSNoteUpdate() API call for a created note. The EM registration
   calls are omitted */

STATUS LNCALLBACK BillHandler ( EMRECORD FAR * theData )
{ 

   STATUS     error = NOERROR;
   BILLMSG    BillMsg;
   VARARG_PTR argPtr;

   NOTEHANDLE hNote;                        /* NSFNoteUpdateExtended argument */
   HANDLE     hDb;                          /* Associated DB handle */
   char       Username[MAXUSERNAME+1];      /* Note create user */  
   NOTEID     NoteId;                       /* NOTEID of note */
   DBID       DbId;                         /* DBID of note */
   char       Servername[MAXUSERNAME+1];    /* Server name */  
   DWORD      BillClass; 

/* Check to see if Database billing class is enabled. If not, return without
   sending billing record */

   if (error = BillingGetClass( &BillClass ))

/* Only bill if the API was successful. If not, return without sending 
   billing record. */

      goto Done;

   if ((BOOL)(BillClass & BILL_CLASS_DATABASE))
   {

      if ( theData->Status != NOERROR )
         goto Done;

/* otherwise handle Note Create billing by interpreting NSFNoteUpdateExtended 
calls */

      argPtr = theData->Ap;

/* Before the API:  check to see if the Note ID is equal to zero.   If it is 
   then this means a new note is being created and we should track the output. 
*/

      if ( theData->NotificationType == EM_BEFORE )
      {
         hNote = VARARG_GET (argPtr, HANDLE);   /* save note handle */
         (void) VARARG_GET (argPtr, DWORD);      /* skip update flags */

   /* get NOTEID of input note handle */
         NSFNoteGetInfo(hNote, _NOTE_ID, &NoteId);

   /* if NOTEID = 0, then set for billing */
         if (NoteId == 0)
            gCreatedNote = TRUE;    
         else
            gCreatedNote = FALSE;    

         return ( ERR_EM_CONTINUE ); /* continue;, billing occurs after call */
      }

/* If after the call and a new note was created, fill in the UserName, Note ID, 
   and Replica ID of the created note in the billing record. */

/* NOTE: Since a global is used to determine if a new note was created, this 
         logic assumes that the EM_AFTER handling occurs before a different 
         NSFNoteUpdateExtended EM_BEFORE thread is handled by Domino.  For 
heavily
         loaded systems, it may be necessary to serialize these requests. */

      if (gCreatedNote == TRUE)
      {
         memset( &(BillMsg.rec.notecreate), (char)0, sizeof( 
BillMsg.rec.notecreate ) );
         hNote = VARARG_GET (argPtr, HANDLE);   /* save note handle */
         (void) VARARG_GET (argPtr, DWORD);      /* skip update flags */

   /* get NOTEID of note handle */
         NSFNoteGetInfo(hNote, _NOTE_ID, &NoteId);

   /* get the DBHANDLE for note handle */
         NSFNoteGetInfo(hNote, _NOTE_DB, &hDb);

   /* get DBID associated with the DBHANDLE */
         NSFDbIDGet(hDb, &DbId);

   /* get USERNAME associated with the DBHANDLE */
         (void) NSFDbUserNameGet(hDb, Username, MAXUSERNAME);

   /* if user is the server, then do not bill */
         (void) SECKFMGetUserName(Servername);
         if (!strcmp(Username, Servername))
            goto Done;       

   /* else, set billing message fields with appropriate info*/
         strcpy(BillMsg.rec.notecreate.Username, Username);
         BillMsg.rec.notecreate.dbNoteID = NoteId;  
         BillMsg.rec.notecreate.ReplicaID = DbId;  

   /* and write the billing record */
         error = BillingWrite( (DWORD)BILL_CLASS_DATABASE, 
                               (WORD)BILL_NOTECREATEREC, 
                               sizeof( BillMsg ),
                               &BillMsg,
                               BILL_QUEUE_NAME );
      }
   }

/* Whether or not the Billing the record was written, return the original
   NSFNoteUpdateExtended (EM_AFTER) status back to Domino */    

Done:
   if (theData && theData->NotificationType == EM_BEFORE)
      return( ERR_EM_CONTINUE );
   else
      return( theData->Status );

}
See Also : BillingGetClass BILLMSG BILLREC BILL_CLASS_xxx BILL_xxx (structure types) EMHANDLER