Oracle9iAS Wireless Developer's Guide Release 2 (9.0.2) Part Number A90485-02 |
|
Each section of this document presents a different topic. These sections include:
The Oracle9iAS Wireless alert system provides you with extensible and scalable solutions to develop mobile alert services. An alert service generates alert message delivery events from a content source based on certain conditions such as a value-based predicate. For example, sending a stock quote to a user when the stock price has reached a predefined value. A condition can also be a time-based predicate with or without a value-based predicate. For example, a user can request the stock market index every day at 8 am, or a stock market index every day at 8 am, if the index has reached a predefined value. The delivery mechanism of the alert message is through Oracle9iAS Wireless message gateway, which allows notification to be sent through WAP push, Email, SMS messages, Instant Messaging or voice.
The alert engine architecture is described in Figure 12-1.
At design time, each master alert service selects a content descriptor, known as data feeder as its content source and becomes a subscriber to a content arrival event from that content source. Upon the content arrival event, which is generated by either data feeders or by custom applications, the alert engine notifies all the content event handlers whose associated master alert services have subscribed to the content arrival event. The content event handler in turn evaluates all the user alert subscriptions to locate the interested alert subscribers. Once the list of alert subscribers has been determined, the message formatter generates the outgoing alert message by either applying the message formatting template to the content or invoking the message formatter hook with the content and alert subscriber information. Finally, the alert message dispatcher communicates with the Oracle9iAS Wireless message gateway to deliver the message to the alert subscriber's device address.
The end user creates alert subscriptions using either the Oracle9iAS Wireless Content Manager or the Oracle9iAS Wireless alert subscription APIs. If a master alert service is set to be time base enabled, the user can specify the time and the frequency for the alert subscriptions to be evaluated. The time event handler requests the content from the data feeder based on the user time base setting and generates content arrival event for the content event handler.
When you create a master alert service, you (a service designer) must first describe the data content on which the alert service is built. Oracle9iAS Wireless enables you to define the data content using a data feeder. The data feeder module defines a given content in two forms: input parameters and output parameters. For example, a stock quote content can be defined as having a stock ticker as its input parameter and having price, volume, change, and change percentage as its output parameters. Furthermore, the data feeder module allows you to define the data mapping between any content source and the data feeder's input and output parameters so that contents can be retrieved automatically from any content source to Oracle9iAS Wireless.
Defining a master service requires you to provide the following information:
For example, if you are building an alert service based on a stock feed which has a stock ticker as its input parameter and price and change as its output parameters, you can define the message template as follows:
<SimpleText> Stock Alert for &ticker; Price: &price; Change: &change; </SimpleText>
You can refer to any data feeder input/output parameters in the template using the notation of &<parameter name>; , which is similar to the XML entity notation. When the notification message is generated at runtime, all references to the data feeder's parameter are replaced by the actual content values. In addition, the developer can use the following tokens in the template to generate a personalized message:
Developers wishing to generate more sophisticated notification messages with customized logic base on the runtime contents can supply a Java class which implements Java interface AlertMessageFormatter
or AlertPersonalMessageFormatter
for generic or personalized message respectively.
Note: Alert message device transcoding is not supported in current release of Oracle9iAS Wireless. However, the feature will be supported in the future releases |
In some cases, the designer may wish to apply customized business logic before the notification message can be delivered to the subscriber. For example, some may want to interface with the billing system before any notification can be sent to the subscriber. Oracle9iAS Wireless alert engine allows the developer to supply a Java class which implements the Java interface AlertSubscriberFilter for additional subscriber filtering logic.
Generally, you create a master alert service using the Webtool's Service Designer. The Service Designer provides you with a wizard that guides you through each step for creating a master alert service. For more information, see the Oracle9iAS Wireless Getting Started and System Guide.
The following code segment illustrates how to create a Master Alert Service using Oracle9iAS Wireless public APIs. This example shows how to use a stock quote feed and generate a stock alert for subscribers when a stock price reaches beyond or below the subscriber's predefined values.
MetaLocator m = MetaLocator.getInstance(); ModelFactory f = m.getModelFactory(); ModelServices s = m.getModelServices(); // use feed locator get the datafeeder information DataFeeder df = s.lookupDataFeeder("StockFeed") try { // create a master alert with time base disabled stockMS = f.createMasterAlertService("StockAlert", false, " Stock Master Alert", df); stockMS.save(); } catch (PanamaException pe) { System.out.println(pe.toString()); } FeedMetaData fmdPrice = df.getOutputParameter("price"); AlertConditionType actGT = s.getAlertConditionTypeByName("GT"); // add some conditions to the master alert AlertConditionMeta m1 = stockMS.addConditionDefinition("price_max", fmdPrice, actGT, "30"); AlertConditionType actLT = s.getAlertConditionTypeByName("LT"); AlertConditionMeta m2 = stockMS.addConditionDefinition("price_min", fmdPrice, actLT, "15"); // Set up alert message template StringBuffer messageTemplate = new StringBuffer("<SimpleText> \n"); messageTemplate.append("Stock Alert for &ticker; : \n"); messageTemplate.append("Price: &price; \n"); messageTemplate.append("Change: &change; \n"); messageTemplate.append("</SimpleText>"); stockMS.setFormattedXMLTemplate(messageTemplate.toString()); // any create/update operation must be committed with the save. Alert object do not use the // wireless caching/persistence framework stockMS.save(); // Lookup condition definitions AlertConditionMeta[] acm = stockMS.getConditionDefinitions(); for (int i=0; i<acm.length; ++i) { System.out.println("Condition info : "+i+" id = "+acm[i].getId()+" Name = "+acm[i].getConditionName()); } // lookup input parameters. The input parameters get copied from datafeeder. // However the user can set default values AlertInputParamMeta[] aipm = (AlertInputParamMeta[])mas.getInputParameters(); for (int i=0; i<aipm.length; ++i) { System.out.println("Param info : "+i+" id = "+aipm[i].getId()); } * On Section 12.1.10.2, in the code segment, please replace the following code: try{ eng.andleFeedContent("StockFeed",content); }catch (PanamaException e){ // handle the exception } with the following new code segment: try{ eng.handleFeedContent("StockFeed",content); }catch (PanamaException e){ // handle the exception }
Once the master alert service has been defined, the designer can create user-accessible alert services based on the master alert service. Oracle9iAS Wireless allows the designer to create and manage alert services through the following:
Generally, you use the Webtool's Content Manager to create an alert service based on an existing master alert service. The Content manager guides you each step in creating an alert service. For more information on using the content manager, see the Oracle9iAS Wireless Getting Started and System Guide.
The following code segment illustrates how to create an alert service using Oracle9iAS Wireless public APIs. The use case is to create a stock alert service for master alert service StockAlert under a topic named Stock Topic. The alert service also sets the caption of the service for the trigger condition price_max, which is defined in the master alert service.
MetaLocator m = MetaLocator.getInstance(); ModelFactory f = m.getModelFactory(); ModelServices s = m.getModelServices(); Topic A = null; // create a topic named StockTopic associated with an alert service stock alert try { A = f.createTopic("StockTopic", null); A.save(); MasterAlertService mas = s.lookupMasterAlertService("StockAlert"); AlertService as = f.createAlertService("stock alert ", mas); AlertConditionMeta[] conds = as.getConditionDefinitions(); for ( index=0;index<conds.length; index++){ if (conds[index].getConditionName().equals("price_max") ){ conds[index].setCaption("above"); } } as.save(); A.addService(as); A.save(); } catch (Exception e) { L.e("createTopic failed :"+e.toString()); }
Once an alert service is created and assigned to a user group, the user belonging to the group can create or modify alert subscriptions as follows:
Users generally manage their alert subscriptions using the Wireless Customization. For more information, see the Oracle9iAS Wireless Getting Started and System Guide.
Managing alert subscriptions using Oracle9iAS Wireless public API is illustrated by way of the following example:
Following code segment illustrates how to create an alert subscription for John using Oracle9iAS Wireless public APIs:
ModelServices s = m.getModelServices(); AlertService as = s.lookupAlertService("stock alert"); //lookup user User u = m.lookupUser("John"); UserAlertSubscription subs = as.addUserAlertSubscription(u); AlertInputParamValue[] apv = subs.getInputParameters(); for(int i=0; apv!=null && i<apv.length; i++) { if(apv[i].getParamName().equals("ticker")) { apv[i].setValue("ORCL"); } } // get/set new conditions for the subscription AlertConditionValue[] acv = subs.getConditions(); for(int i=0; acv!=null && i<acv.length; i++) { if(acv[i].getConditionName().equals("price_max") ){ acv[i].setValue("15"); break; } } subs.setHour(10); subs.setMinute(30); // get frequency from model services AlertTimeFrequency[] af = getAlertTimeFrequencies(); for(int i=0; i<af.length; ++i) { if(af[i].getFrequencyCode().equals(AlertTimeFrequency.DAILY)){ subs.setFrequency(af[i]); } } // any create/update operation must be committed with the save. Alert objects // do not use the wireless caching/persistence framework subs.save(); //... get all subscriptions //retrieving subscsription UserAlertSubscription[] mysubs = as.getUserAlertSubscriptions(u); for (int i=0;i<mysubs.length;i++){ AlertInputParamValue[] params = mysubs[i].getInputParameters(); System.out.println("Sub ID: "+mysubs[i].getId()); System.out.print("Params: "); for (int j =0;j<params.length;j++){ System.out.print(params[j].getParamType()+"="+params[j].getValue()+" "); } System.out.print("\n"); AlertConditionValue[] conds = mysubs[i].getConditions(); System.out.print("Conds: "); for (int j =0;j<conds.length;j++){ System.out.print(conds[j].getConditionName()+"="+conds[j].getValue()+" "); } System.out.print("\n"); }
A user must register a valid device to receive alert notifications. Furthermore, the user must select a device address for a given alert service. The device address must have the following attributes:
For detail information regarding Device Address, please refer to the developer guide for Oracle9iAS Wireless core objects.
To set the user device address selection to a given alert service programmatically, use the API setUserAlertDevice(DeviceAddress deviceAddress)
which is defined under interface AlertService
.
To deploy a master alert service, a system manager creates (or updates) an alert instance, adds the newly created master alert service to the alert instance and then starts the alert instance. See the Oracle9iAS Wireless Getting Started and System Guide for more information managing the Oracle9iAS Wireless system and starting and stopping an alert engine process.
This section describes the methods of pushing contents to the Oracle9iAS Wireless alert engine for notification delivery. These methods include:
If a designer of an master alert service chooses to use the Oracle9iAS Wireless data feeder module to retrieve data content, also known as the "POLL" model, the data feeder automatically notifies the alert engine of the content arrival event. The alert engine then evaluates all the user subscriptions with the newly arrived content to deliver alert message to the appropriate subscriber device addresses.
If the designer chooses to use the "PUSH" model by defining a pass-through data feeder, or the designer wishes to deliver contents to the alert engine programmatically from an application, the designer uses the alert engine public APIs to notify alert engine of the content arrival event.
The following code segment illustrates how to notify alert engine using Java APIs:
AlertEngine eng = AlertEngineLocator.getInstance().getAlertEngine(); Hashtable content = new Hashtable(); content.put("ticker","ORCL"); content.put("price","16"); content.put("change","1"); try{ eng.andleFeedContent("StockFeed",content); }catch (PanamaException e){ // handle the exception
The Data Feeder is the agent that downloads content. The data feeder runs periodically, independently of service invocations. The feed framework is designed to download content for a Oracle9iAS Wireless process. The downloaded content can be used both for asynchronous alerts as well as cached data for synchronous services.
The download schedule for the data feeder is maintained in the update policy for that data feeder. The update policy determines the update interval, or how often the data feeder runs. The update policy can the time of day, and which days of the week to run the data feeder.
Each data feeder has a content provider, which is the source of the content. The content provider maintains information about the URI of the content, the protocol to use for downloading the content, and the format of the data to be downloaded.
When specifying a feed, the user sets up a metadata definition of the content to be downloaded using feed parameters. These parameters are instances of the data type, FeedMetaData
. Feed parameters have an underlying SQL data type chosen from a predefined set of types, defined in oracle.panama.feed.FeedUtil
.
Feed Input Parameters are input parameters particular to a content provider. They specify the data used when requesting data from the content provider. For example, when downloading data from a content provider using HTTP, the input parameters will be used either to construct a GET URL or as POST parameters in the HTTP request.
Feed Output Parameters define the data type of the output from the content provider.
The runtime behavior of the data feeder can be customized with the FeedDownloadHook
and the FeedDataFilterHook
.
The FeedDownloadHook
is used to customize the URI used when downloading content. For example, in a HTTP download, the input parameters are, by default, used to construct a GET URL, with the input parameters used as GET HTTP parameters. In some cases, however, the base URL depends on the input parameters. In such a case, the URL would be http://www.ahost.com/input_param_1/input_param2/index.html. The behavior for constructing the URL can be overridden with a custom FeedDownloadHook
to achieve the desired result.
The FeedDataFilterHook
is used to do additional processing on the downloaded content. As each row of data is downloaded, the data filter hook gets invoked on each row. This allows the feed implementer to perform special processing, such as splitting a single output parameter into several output parameters.
The pass-through data feeder is a datafeeder that accesses local content through user-defined Java code. Consequently, a pass-through data feeder has neither a content Provider nor an update policy. Similarly, the FeedDownloadHook
and the FeedDataFilterhook
are not relevant for a pass-through data feeder. The feed metadata still needs to be set up for a pass-through data feeder.
You can create a data feeder using the Webtools Service designer, or programatically.
Creating a data feeder can be broken into the following steps:
createFeedDefinition
. This method creates the feed metadata definition in the repository, which is required to use the feed and the feed cache table. Once the feed definition has been created, feed parameters cannot be deleted, only renamed.
the Webtool's Service Designer provides you with a wizard to guide you through each step of the creation process. For more information, see the Oracle9iAS Wireless Getting Started and System Guide.
A pass-through datafeeder requires that you specify the classname of the pass-through datafeeder to use. It does not require all the information that a regular datafeeder needs: in particular, the protocol and format to use is irrelevant.
The following code creates a pass-through datafeeder:
ModelFactory mf = MetaLocator.getInstance().getModelFactory(); // Create a named datafeeder
PassthroughDataFeeder df = mf. createPassThroughDataFeeder ("stock_passthrough") // Set the class name to use for implementation
df.setClassName("fully.qualified.package.and.Class"); // Create input parameters
FeedMetaData fmi = df.createMetaData("sym", "TEXT_30");
df.addInputParameter(fmi): // Create output parameters
FeedMetaData fmo1 = df.createMetaData("price", "NUMBER");
df.addOutputParameter(fmo1);
FeedMetaData fmo2 = df.createMetaData("change", "NUMBER");
df.addOutputParameter(fmo2);
// Finalize the feed -- create feed definition
// in repository df.createFeedDefinition();
Oracle9iAS Wireless includes the sample200.xml. This sample file contains a datafeeder for retrieving stock quotes over HTTP. The stock quotes are in XML format; the sample datafeeder includes the stylesheet for extracting the relevant values from the XML input feed.
In order to create this data feeder programmatically, you would use the following code:
ModelFactory mf = MetaLocator.getInstance().getModelFactory(); // Create a named datafeeder
DataFeeder df = mf.createDataFeeder("stock_screamingmedia"); // Set content provider parameters
ContentProviderInfo cpi = df.getContentProviderInfo(); cpi.setProtoolType(ContentProviderInfo.PROTOCOL_HTTP); cpi.setPrimarySource("http://www.screamingmedia.com/"); cpi.setFormatType(ContentProviderInfo.FORMAT_XML); // Create input parameters FeedMetaData fmi = df.createMetaData("sym", "TEXT_30");
df.addInputParameter(fmi): // Set the parameters for this parameter and content provider
Map paramOptions = new Hashtable();
paramOptions.put(ContentProviderInfo.COLUMN_NUMBER, 1);
cpi.setParamArguments(fmi, paramOptions);
// Create output parameters FeedMetaData fmo1 = df.createMetaData("price", "NUMBER");
df.addOutputParameter(fmo1);
paramOptions.put(ContentProviderInfo.COLUMN_NUMBER, 2);
cpi.setParamArguments(fmo1, paramOptions);
FeedMetaData fmo2 = df.createMetaData("change", "NUMBER");
df.addOutputParameter(fmo2);
paramOptions.put(ContentProviderInfo.COLUMN_NUMBER, 3);
cpi.setParamArguments(fmo2, paramOptions); // Finalize the feed -- create feed definition in repository
// create cache table as needed df.createFeedDefinition();
sample200.xml. also includes a datafeeder for retrieving stock quotes over HTTP that downloads the stocks in the comma-separated variable (CSV) format.
The following code illustrates how to create this data feeder programmatically.
ModelFactory mf = MetaLocator.getInstance().getModelFactory(); // Create a named datafeeder
DataFeeder df = mf.createDataFeeder("stock_yahoo") // Set content provider parameters
ContentProviderInfo cpi = df.getContentProviderInfo();
cpi.setProtocolType(ContentProviderInfo.PROTOCOL_HTTP);
cpi.setPrimarySource("http://quotes.yahoo.com/quote");
cpi.setFormatType(ContentProviderInfo.FORMAT_DELIMITED); // Create input parameters
FeedMetaData fmi = df.createMetaData("sym", "TEXT_30");
df.addInputParameter(fmi): // Set the parameters for this parameter and
// content provider
Map paramOptions = new Hashtable();
paramOptions.put(ContentProviderInfo.COLUMN_NUMBER, 1);
cpi.setParamArguments(fmi, paramOptions);
// Create output parameters
FeedMetaData fmo1 = df.createMetaData("price", "NUMBER");
df.addOutputParameter(fmo1);
paramOptions.put(ContentProviderInfo.COLUMN_NUMBER, 2);
cpi.setParamArguments(fmo1, paramOptions);
FeedMetaData fmo2 = df.createMetaData("change", "NUMBER");
df.addOutputParameter(fmo2);
paramOptions.put(ContentProviderInfo.COLUMN_NUMBER, 3);
cpi.setParamArguments(fmo2, paramOptions);
// Finalize the feed -- create feed definition
// in repository, create cache table as needed df.createFeedDefinition();
The data feeder only downloads content which has a specified input parameter. Input parameter values can be set either implicitly or programmatically. Input values can be added implicitly by adding an alert topic subscription. The following code illustrates how to add an alert programmatically:
// Look up existing data feeder
DataFeeder df = ModelServices.getInstance().lookupDataFeeder("stock_yahoo"); // Want to add input params for ORCL
Map params = new Hashtable();
params.put("sym", "ORCL"); df.setData(params);
One primary use of the data feeder is to download cached data for use with regular synchronous services. Downloaded data can be accessed using the datafeeder method getData()
. This method takes an argument as a map, which is a name-value mapping of the parameters which get values. The following code example illustrates how you can retrieve current price and change given a stock symbol:
ModelServices ms = MetaLocator.getInstance().getModelServices();
DataFeeder df = ms.lookupDataFeeder("stock_yahoo");
Map params = new Hashtable();
params.put("sym", "ORCL");
Map values = df.getData(params);
Iterator i = values.keys(); while(i.hasMore()) {
String key = (String)i.next();
String val = (String)values.get(key);
System.out.println(key + " = " + val);
}
Running this code we while get the following output:
sym = ORCL
price = 18.75
change = 0.5
System managers start a data feeder process. Oracle9iAS Wireless engine. Like other processes, the system manager must set up a process of the datafeeder in order to run it. For more information, see the Oracle9iAS Wireless Getting Started and System Guide.
The external name is the name used when retrieving content from a content provider. This mechanism is intended for cases where the external representation of the parameter name changes after the feed has been built, such as when one changes to another content provider. The external name is optional; if it is not specified, then the internal name is used.
You specify a caption to use for the input parameter. This is for documentation purposes only.
There are cases where an input parameter has been defined, but is not relevant when retrieving content. If the special constant __NONE__ is used for the external parameter name that input parameter will be ignored when constructing the download URL or POST request.
By default, feeds run continuously when started. Each feed has an associated update policy, which can be used to fine-tune the running of the feed, such as the time of day to start and stop the feed, the days which to run and the interval between feed runs.
The following code sets the update policy of the example data feeder to run on weekdays between 9 am and 5 pm.
ModelServices ms = MetaLocator.getInstance().getModelServices();
DataFeeder df = ms.lookupDataFeeder("stock_yahoo");
UpdatePolicy up = df.getUpdatePolicy(); up.setStartTime(9,0,0);
up.setEndTime(17,0,0);
up.setUpdateDays(UPDATE_WORKDAYS);
// Set update interval to 300 seconds, i.e. update every
// 5 minutes
up.setUpdateInterval(300);
When accessing datafeeds with XML content, you must specify a XSLT stylesheet that will transform the input XML to a common XML format.
The common XML format consists of a feed result (<omfeed_result>
), which has a number (zero or more) of datarows (<omfeed_datarow>)
, each one consists of one or more named datacolumns (<omfeed_datacolumn>
). The name of the data column is matched with the parameters defined for the feed. Each output parameter should have a corresponding data column. This code sample illustrates the output of a stock feed:
<?xml version="1.0"?>
<market-data>
<quote-set> <quote symbol="ORCL" name="ORACLE CORPORATION" type="stock" exchange-code="NASDAQ" last="32.000000" close="28.562500" close-flag="closed" change="3.4375" percent-change="12.04%" volume="56362800" open="30.0" high="32.4375" low="29.9375" bid="32.0" ask="32.0625" bid-size="36" ask-size="90" high-52-week="46.468998" low-52-week="15.438" shares-outstanding="5629833" pe-ratio="29.299999" volatlity="16.150000" yield="0.000000" earnings-per-share="1.092000" status="ok"/> </quote-set>
</market-data>
The stylesheet for transforming this result would then look like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="quote-set"> <omfeed_result> <xsl:for-each select="quote"> <omfeed_datarow> <omfeed_datacolumn> <xsl:attribute name="name">sym</xsl:attribute> <xsl:value-of select="@symbol"/> </omfeed_datacolumn> <omfeed_datacolumn> <xsl:attribute name="name">price</xsl:attribute> <xsl:value-of select="@last"/> </omfeed_datacolumn> <omfeed_datacolumn> <xsl:attribute name="name">change</xsl:attribute> <xsl:value-of select="@change"/> </omfeed_datacolumn> </omfeed_datarow> </xsl:for-each> </omfeed_result> </xsl:template>
|
Copyright © 2002 Oracle Corporation. All Rights Reserved. |
|