Oracle Application Server Wireless Java API Reference
B14043-01


Package oracle.wireless.billing

OracleAS Wireless Billing Integration Framework provides an extensible and flexible framework to model billable services, capture billable actions, and integrate with any billing engine.

See:
          Description

Interface Summary
BillingContext The billing context.
BillingDataCollector Public interface to collect the component specific billing data and construct the Service detail record with appropriate extended attributes This class is initialized using singleton pattern.
BillingDriver The Billing Driver which interfaces with the external billing system The driver is component specific.

 

Class Summary
BillingController Billing controller handles the billing system interaction for the components
BillingDataCollectorImpl Reference implementation of the Public BillingDataCollector interface The extended attributes deemed relevant are set based on the component type The customer can plug in his own implementation This class is initialized using singleton pattern.
BillingLoader  
BillingManager Billing manager provides the helper funtinalities to create and lookup service detail records
BillingResult Contains the response from the billing system to a billing authorization request
BillingTransaction Billing Transaction encapsulates the SDRs associated with a billing transaction A billing transaction is created using the Billing Transaction manager.
BillingTransactionManager Billing Transaction Manager is factory to create a transaction A billing transaction can be created at any stage in the Business flow.
ServiceDetailRecord The ServiceDetailRecord is used by Oracle 9iASW to provide the billing system the information regarding a billable service accessed by a user service access.

 

Exception Summary
BillingException This is generated when the billing driver incase of any exceptions while interfacicng with the external biling system

 

Package oracle.wireless.billing Description

OracleAS Wireless Billing Integration Framework provides an extensible and flexible framework to model billable services, capture billable actions, and integrate with any billing engine.

1.1 Concepts

Billable Action--Customer actions which should be tracked, authorized and reported to the billing system. Typical examples are premium service access, mobile content download, alert subscription and message delivery.
 

Billing Context--A marker interface whose implementation object provides all the data related to a given billable action. OracleAS Wireless has the following objects predefined as Billing Context:

Service Detail Record (SDR)--A generic object that captures all the billing-specific attributes from the billing context for a given billable action. The attributes are of two types: mandatory and extended. Mandatory attributes are user information, service information and component information. Extended attributes contain the component-specific information.


 

Billing Collector--An extensible object that processes the BillingContext and generates the corresponding service detail record.

Billing Driver--A Java interface defined by OracleAS Wireless; it interacts with an external billing system to handle a given billable action. A billable action is usually handled in two steps:

2 Using the Billing Integration Framework

 

2.1 Billable Actions and Billing System Interaction

 

2.1.1 Default Billable Actions

OracleAS Wireless defines the following billable actions:

2.1.2 Custom Billable Actions

OracleAS Wireless billing integration framework allows users to introduce custom billable actions to meet their business needs. Following are the steps to introduce a new billable action:

Use the following code segment to trigger a new billable action for a preService call:

// Suppose your BillingContext Object is foo 
BillingController controller =  BillingController.getInstance(); 
if (controller.isBillingEnabled() ) 
 { 
       try { 
             BillingResult result = controller.preService(foo); 
            if ( result != null ){ 
               ServiceDetailRecord sdr = result.getServiceDetailRecord(); 
               if (result.getResultCode() != BillingResult.FAILED) { //Succeed 
                 // Add your logic here 
               } 
              else { // Failed 
                    // Add your logic here to handle preService failure 
                    //BillingException e = new BillingException(failure message); 
                    // e.setResult(result);
                    // throw e;

              } 
          } 
      } catch (BillingException be) { 
               //Handle Billing Execption here 
         }

Use the following code segment to trigger a new billable action for postService call:

// Suppose your BillingContext Object is foo 
BillingController controller =  BillingController.getInstance(); 
if (controller.isBillingEnabled() ) 
 { 
       try { 
             BillingResult result = controller.postService(foo); 
            if ( result != null ){ 
               ServiceDetailRecord sdr = result.getServiceDetailRecord(); 
               if (result.getResultCode() != BillingResult.FAILED) { //Succeed 
                 // Add your logic here 
               } 
              else { // Failed 
                    // Add your logic here to handle postService failure 
              } 
          } 
      } catch (BillingException be) { 
               //Handle Billing Execption here
         }

3 BillingLoader Utility


The BillingLoader Utility is a batch utility to download, purge and upload billing transaction records. For more information on BillingLoader Utility, see Oracle IAS Wireless Administrator's Guide.

4 Billing Collector and Service Detail Record

A billable operation for every component is split into 2 parts: a pre-event and post-event. An SDR is generated for both the pre- and post- events. The billing data collector class is used to create one SDR for each pre- or post- service call.

When the pre-service SDR is passed to the billing system, the billing system is expected to set a unique Billing Reference ID and return the SDR as part of the billing result.

The returned pre-service billing reference ID is extracted by OracleAS Wireless. It is set in the post service SDR of the same billable operation so that the external billing system can maintain state between the pre- and post- event of any single billable operation based on the billing reference ID.

Only the post service billing event SDR is logged to the database, unless the driver starts-up a transaction by setting the transaction ID attribute in the SDR which it returns after the pre-service. If the transaction ID is set, then the pre-service SDRs are also logged. You can identify the pre and post service SDRs based on the LOG_TYPE column which will be either PRE_SERVICE or POST_SERVICE.

The SDR ID is an internal ID used as a primary key in our tables. You can look up a particular SDR based on the SDR ID.

There is normally only one SDR ID for every post-service event, unless the driver starts up a transaction (in which case the pre-service SDR is logged).

4.1 Default Billing Collector Implementation

The BillingCollector implementation object is responsible for processing the BillingContext for a given billable action. It generates an appropriate Service Detail Record for the billing driver to process. OracleAS Wireless includes a default BillingCollector implementation named BillingCollectorImpl which handles the following BillingContext objects:

4.2 Service Detail Record ID Versus Billing Reference ID


Service Detail Record ID is defined by the Billing Collector. The default format is [Component Name: Random Key]. The Billing Reference ID is obtained from the billing system. In the pre-bill case, it is usually defined as the authorization ID.

4.3 Extend Default Billing Collector

OracleAS Wireless billing integration framework enables users to extend the default billing collector implementation for various reasons:

To ignore a billable action base on the context data. Simply return a null object from the createServiceDetailRecord call based on your business logic.


Specify your extended Billing Collector using Oracle Enterprise Manager:

EM > Wireless Server: Site Administration > Billing Framework > Billing Collector Class name

4.4 Maintaining Transaction Context on Multi-part Requests

A typical wireless request spans multiple entities (a multi-part request). For example, an Async request may originate at the Messaging Server, forwarded to the Async Listener, which invokes a Runtime service and then returns the result back to the user through the Messaging Server. The Billing Rules may demand a billing at each stage of the transaction, but the pricing may vary depending on the context of the request. To support such a scenario, it is necessary to maintain the history of the request's path (available resources to the Billing Driver [or Data Collector]), where the Billing Rules are enforced.

When the request changes, the transaction needs to be reset by the driver in the preservice. The default billing collector implementation stores transaction id information as a thread local variable and caches it in the thread unless reset. For example, in the Asynch Servlet case, since subsequent requests are also processed in the context of the same thread, Async servlet retains the previous transaction id unless its reset by the collector or driver.

In a typical scenario, a asych request arrives through the messaging layer. In order for the billing layer to link this messaging request with the asynch request and the subsequent messaging response, the message id is carried forward. The MESSAGE_ID extended attribute of the incoming message should match the ASK_IN_MSGID of the Asynch request and this should match the LINKED_MESSAGE_ID attribute of the outgoing message. This is how the incoming message id is carried forward when the request is serviced.

4.4.1 Creating and Assigning Billing Transactions

The Billing Driver (or Data Collector) can assign a given Service Detail Record to be part of a transaction. For example, the pre-service call implementation of the Billing Driver can contain the following lines to add the SDR to a newly created transaction.

           BillingTransaction Trans = 
BillingTransactionManager.getInstance().createTransaction();
          Trans.getId(); // if its XYZ say       
           sdr.setTransaction(Trans);

This creates a new transaction and adds the Service Detail Record to it. The subsequent service detail records can be added to the same transaction by retaining the transaction ID. The point at which a new transaction needs to be created should be decided by the driver or collector writer.

Here is the pseudo-code for subsequent Service Detail Records:

            BillingTransaction Trans = 
BillingTransactionManager.getInstance().lookupTransaction (XYZ);
          Trans.getId(); // if its XYZ say       
          Trans.addSdr(sdr); // OR sdr.setTransaction(Trans);

The past Service Detail Records for this transaction can be looked-up using the BillingTransaction public APIs (see BillingTransaction's getServiceDetailRecords()).

4.4.2 Logging Rules for Service Detail Records

A Service Detail Record, which is part of a transaction, is implicitly logged to the database as soon as the call BillingResult is returned from the BillingDriver implementation. The BillingController inspects the Service Detail Record and does this automatically.

The SDR's part of this transaction is available for lookup (see BillingTransaction's getServiceDetailRecords()). If the SDR is not part of a transaction, then its logging is deferred to the logging framework, to be accomplished in the background.

4.4.3 Maintaining Transaction State in a Single-Thread Multi-part Request

If all subsequent requests of a multi-part request are done in the context of the same Java Thread, the transaction information can be stored in the Thread as a Thread Local object and referenced later for a subsequent request. The Default implementation of the BillingDataCollector (oracle.wirless.billing.BillingDataCollectorImpl) provides just that. The transaction APIs for setting and getting are available through the BillingController object.

  /**
   * Returns the current billing transaction
   * @return BillingTransaction the current billing transaction
   */
public BillingTransaction getCurrentTransaction();

/** Sets the transaction for the current transaction
 * @param transaction the current transaction
 */
public void setCurrentTransaction(BillingTransaction transaction);

5 Billing Driver


To integrate OracleAS Wireless billing integration with an external billing system, the system integrator must provide a Java implementation class which implements the BillingDriver interface. To set your driver:

EM > Wireless Server: Site Administration > Billing Framework > Billing Driver Provider (Driver Class Name)

The desired behavior of the Billing Driver implementation is as follows:

6 Billing Integration Scenario

6.1 Handling Prebilling

Here is an implementation example of handling prebilling:

6.2 Handling Postbilling


Here is an implementation example of handling postbilling:

7 A Sample BillingDataCollector Implemenation

The following code snippet is sample billing data collector. The main purpose of this sample is illlustrate the following (see code documentation below to locate the annotations)

The customer can plug in his own implementation. This class is initialized using singleton pattern. The implementation must have a method like public static BillingDataCollector getInstance()

public class DownloadBillingDataCollectorImpl extends BillingDataCollectorImpl { // subclassing default collector to over-ride behavior

MetaLocator m = MetaLocator.getInstance();

ModelFactory f = m.getModelFactory();

ModelServices s = m.getModelServices();

/**

* reference implementation : to store transaction id

*/

private static ThreadLocal transactionInfo = new ThreadLocal();

private static DownloadBillingDataCollectorImpl instance = new DownloadBillingDataCollectorImpl();


/**
* providing a getInstance method for runtime class instantiation
*/

public static BillingDataCollector getInstance() {

System.out.println("Using DownloadBillingDataCollectorImpl");

return instance;

}

public ServiceDetailRecord createServiceDetailRecord(BillingContext context) {

ServiceDetailRecord sdr = null;

// changing the behavior for the provisioning (j2me) download case
// the default behavior is the one provided by the oracle.wireless.billing.BillingDataCollectorImpl class file

if (context instanceof oracle.panama.model.UserDownloadStatus) {

System.out.println("Provisioning case: ");

try {

oracle.panama.model.UserDownloadStatus uds = (oracle.panama.model.UserDownloadStatus)context;

if(UserDownloadStatus.STATUS_NOTIFIED_SUCCESS.equals(uds.getStatus())) {

return null;

// check to ignore billing if status is UserDownloadStatus.STATUS_NOTIFIED_SUCCESS

// Thus postService billing is called both after jar download completes and notify completes.
// We are handling it when download completes i.e when status is UserDownloadStatus.STATUS_COMPLETE

}

System.out.println("Provisioning case: status = "+uds.getStatus()+" mime type = "+uds.getMimeType());

java.sql.Timestamp accessTime = null;

BillingManager manager = BillingManager.getInstance();

sdr = manager.createServiceDetailRecord(uds.getUser().getName()
, uds.getService().getName()
, accessTime
, BillingContext.PROVISIONING_COMPONENT);

sdr.setExtendedData("APPLICATION_NAME", uds.getApplication().getName());

sdr.setExtendedData("CONTENT_NAME", uds.getContent().getName());

String size = null;

String mimetype = uds.getMimeType();

if (mimetype.equals(ApplicationContentLocator.MIME_TYPE_JAD)){

mimetype = ApplicationContentLocator.MIME_TYPE_JAR;

}

size = Long.toString(uds.getContent().getContentItemByMimeType(mimetype).getDataLength());

sdr.setExtendedData("CONTENT_SIZE",size);

sdr.setExtendedData("CONTENT_VERSION", uds.getContent().getVersion());

if (uds.getDevice() != null)

sdr.setExtendedData("USER_DEVICE_NAME", uds.getDevice().getName());

sdr.setExtendedData("MIME_TYPE", uds.getMimeType());

sdr.setExtendedData("CURRENT_NUMBER_OF_DOWNLOADS", (new Long(uds.getNumberOfDownloads())).toString());

} catch (BillingException be) {

L.e("Billing Exception during Provisioning SDR creation : "+be.getMessage());

}

} else {

sdr = super.createServiceDetailRecord(context);

}

// if the transaction id is set (by application integrator's logic) then set the value in the SDR

if(super.getCurrentTransaction() != null && super.getCurrentTransaction().getId() != null) {

if(sdr.getTransactionId() == null) {// don't reset transaction id in SDR if already set

sdr.setTransaction(super.getCurrentTransaction());

}

}

if(sdr != null) System.out.println("Returning SDR : component = "+sdr.getComponentName()+", Type = "+sdr.getType());

return sdr;

}

}



Oracle Application Server Wireless Java API Reference
B14043-01


Copyright © 2004 Oracle Corporation. All Rights Reserved.