Oracle9i Application Developer's Guide - XML Release 1 (9.0.1) Part Number A88894-01 |
|
Oracle9iAS Dynamic Services (Dynamic Services or DS) enables developers to take advantage of Web application functionality and content, as services to increase productivity. DS adds web services deployment and management capability to Oracle9i. Developers can use Oracle9i Dynamic Services to compose, catalog, manage, and personalize web services according to user roles, protocols and delivery devices.
This chapter describes the following sections:
Oracle9iAS Dynamic Services (DS) is a Java-based programmatic framework for incorporating, managing, and deploying Internet and Intranet services. It uses the Internet as the information source. It facilitates the rapid incorporation of services from Web sites, local databases, and proprietary systems into applications.
For example, an online financial portfolio application can use DS to integrate Internet financial services, such as stock quotes and exchange rates, from different resource providers to calculate the current value of a portfolio in foreign currency. See also Figure 18-1 and "Dynamic Services Consumer Application: Stock Portfolio Example" .
DS handles dynamic business models with no degradation in service quality.
A DS "service" provides access to information or application functionality through standard Internet protocols, such as, HTTP, JDBC, or SOAP. A "service" can also aggregate other DS services to form a compound service with a specific execution flow. It can include transformations and conditional logic and is accessible through a uniform interface.
Figure 18-1 illustrates a typical Dynamic Services (DS) scenario. This is a workflow of how an application can use DS services to retrieve and manage the data. You simply need to determine the semantics and output formats needed:
DS meets the design criteria needed by application developers in that with DS, developers have:
For further information about Oracle9iAS Dynamic Services:
See:
|
To run Oracle9iAS Dynamic Services you need the following:
<JAVA2_HOME>
is the installation directory of the JDK 1.2.2 or higher, distribution.
Ensure that you have at least a full (typical) installation of Oracle9i.
Figure 18-2 shows an overview of Oracle Dynamic Services (DS) architecture. It shows the following:
DSAdmin
utility (Service Administrator).
Dynamic Services can be deployed in the following ways:
Oracle9iAS Dynamic Services (DS) currently offers deployment modes:
The following lists the DS main components for each of these deployment modes.
You can switch from one environment to another without recompiling or even restarting your application. This gives you a way to try out the various options.
Figure 18-3 shows the Dynamic Services Java deployment view. Oracle9i serves as a registry cache, communicating with the OID Lightweight Directory Access Protocol (LDAP) server hosting the registries. Service Consumer Application contains application logic that uses the services through direct Java calls.
Here, Service Consumer Application uses the DS thick client library, that contains the Dynamic Services Execution Engine. Service providers run in their own servers.
Figure 18-4 shows Oracle Dynamic Services PL/SQL deployment. The Dynamic Services engine runs in the Oracle9i JVM, with its functions exposed as a set of Java stored procedures. Oracle9i database serves as a registry cache. It communicates with Oracle Internet Directory LDAP server which hosts the registries. The Service Consumer Application's logic makes use of the services through PL/SQL calls. Service Providers run in their own servers.
Figure 18-5 shows an Oracle Dynamic Services Java (HTTP/JMS) deployment view. The Dynamic Services engine running in a Dynamic Services gateway (middle tier) supports HTTP, HTTPS, and JMS communication protocols. Oracle9i database serves as a registry cache, communicating with the Oracle Internet Directory LDAP server hosting the registries. The Service Consumer Application's logic, makes use of the services through Dynamic Services' thin Java client library, and executes services remotely in other systems.
Here, service execution requests are forwarded to the Dynamic Services gateway, which executes the service and returns a response. Communication between the service consumer application and the gateway is handled by the Dynamic Services thin client library.
For example, in asynchronous deployment communications (JMS), the DSJMSDriver can allow for asynchronous access to services, in the form of a JMS daemon (using a Dynamic Services gateway). The driver allows request submission asynchronously to an AQ/JMS queue in a remote database. The driver assumes the existence of this JMS daemon running somewhere that listens asynchronously to the same queue where requests are being submitted.
The JMS daemon takes on the role of the Dynamic Services engine. It processes the request, generates a response, and submits the response to another queue that the DSJMSDriver listens to asynchronously.
On the service consumer application side, therefore, listeners can be registered to be informed when the response is returned.
Figure 18-6 illustrates the multiple channels through which DS can be delivered. These include:
Dynamic Services (DS) features include the following:
Dynamic Services' (DS) service management and administration features include:
DS business relationship management can handle such business tasks as:
In forthcoming releases, DS will be managed and administered through Oracle Enterprise Manager.
Dynamic Services' service discovery feature supports run-time Intranet Discovery (LDAP). For example, service descriptors can be stored in Oracle Internet Directory (OID) for security, centralized management, and LDAP lookup. They can be accessed from mirrored Oracle instances for improved runtime performance.
Dynamic Services service execution features include the following:
The following sections and diagrams describe these DS service execution features.
DS Failover services is a prioritized list of backup equivalent services. Figure 18-8 shows an example of failover services used in a stock quote application.
DS allows you to aggregate services and specify which services you need executed in parallel and which services you need executed in series.
For example, Figure 18-9 shows how you can take one or more services, here Service 1 and Service 2, and combine the results by performing operations (here merging or splitting) on them to generate a single result. You can also take the output of one service and input this into another service.
Dynamic Services can execute services according to business requirements. Requirements can be based on service request or user profile properties. Figure 18-10 shows how you can use DS to switch on a specific service(s) for 'gold' customers.
Through the course of executing a DS service, numerous events will be generated that can be captured by the monitoring application. This application will in turn execute other DS services, termed, "monitoring services", depending on the events they receive. Figure 18-11 illustrates an example of this and how the monitored events can trigger a variety of services, including logging, notification, profiling, and billing services.
Dynamic Services (DS) integrates with other Oracle products, including:
Under "Portal Development Kit (PDK)", select the PDK ("click here") then "Integrating Technologies". Read further information under Developing Portlets with Dynamic Services Portlet
The Dynamic Services client library provides service consumers (application developers) with a Java application programming interface (API) that can be used to access the functions of the Dynamic Services engine.
For more information, refer to the sample code in <$ORACLE_HOME>/ds/demo/consumer
directory and to the Javadoc API (apidoc.zip) in <$ORACLE_HOME>/ds/doc/
.
In Dynamic Services, a service is a component within the Internet computing model that delivers a specialized value-added function. A service is bundled into a simple service package and structured as a local directory.
The following are typical tasks you will be using Dynamic Services for:
The Dynamic Services engine uses the Oracle9i database for caching service responses. The caching policy for a given service is controlled through deployment parameters in the service descriptors. Before registering a service, the Service Administrator can review these parameters and modify them as needed. The caching parameters are defined in the SERVICE_HEADER, DEPLOYMENT, and CACHING elements in the service descriptor.
To change the caching parameters of a given service, you must unregister the service and register it again with the new parameter settings. Available caching parameters are:
OSS is an application of Dynamic Services. See Chapter 19, "Oracle Syndication Server (OSS) and XML".
The Dynamic Services software package contains sample code to specifically invoke Yahoo Portfolio service through Dynamic Service engine, using Java. Portfolio service is a service that takes stock symbols as input and give quotes as responses. This service is provided by Yahoo®.
This Dynamic Services software contains the following:
SampleStock.java
: Example java code to invoke a dynamic service in Java.
yapfl_req.xml
: Sample service request file.
Before compiling SampleStock.java
, include the following library in your CLASSPATH:
Compile SampleStock
at the command line as follows:
javac SampleStock.java
To run and test the sample, proper arguments should be given in the command line, as follows:
java SampleStock <HOST_URL> <SID> <SymbolList>
where:
Argument | Description |
---|---|
HOST_URL |
For example, egroup-dev3.us.oracle.com |
SID |
For example, db816 |
SymbolList |
For example, 'ORCL INTC MSFT' |
The output of SampleStock
should be a table of data about requested stocks, such as the following:
|-----+--------------------| | | Time | 12:19PM | | |-------+------------| | | Price | 30 3/16 | |ORCL |-------+------------| | | Change| +0.42% | | |-------+------------| | | Volume| 34,272,000 | |-----+--------------------| | | Time | 12:19PM | | |-------+------------| | | Price | 35 15/64 | |INTC |-------+------------| | | Change| -2.80% | | |-------+------------| | | Volume| 22,499,200 | |-----+--------------------| | | Time | 12:19PM | | |-------+------------| | | Price | 63 | |MSFT |-------+------------| | | Change| +0.10% | | |-------+------------| | | Volume| 24,091,600 | |-----+--------------------|
SampleStock
takes the command line parameters and keeps them in the class data members. Then it calls getQuotes()
to retrieve the quote data.
SampleStock
abstracts the process of executing YahooPortofolio DS service by:
Java.util.Hashtable
.
SampleStock
calls printQuotes()
to display the results in the Hashtable in the format shown above.
import java.io.*; import java.util.*; // imports for handling XML docs import org.w3c.dom.*; import oracle.xml.parser.v2.*; // Dynamic Services imports import oracle.ds.*; import oracle.ds.comm.*; import oracle.ds.registry.*; import oracle.ds.comm.message.*; import oracle.ds.driver.*; import oracle.ds.utils.*; /** * SampleStock code. It opens a Dynamic Service * connection, looks up a stock quote service, * executes it and stores the results in a hash table. */ public class SampleStock implements CommunicationMessageConstants { // Usage message private static final String USAGE = ( "Usage: java SampleStock <HOST_URL> <SID> <Symbol list>\n "+ "where, \n"+ "\tHOST_URL: i.e. egroup-dev3.us.oracle.com\n"+ "\tSID: i,e. db816\n" + "\tSymbol list: i.e. 'ORCL MSFT SEBL'\n" ); // The following are actually the parameters in the // command line and some are hard coded. private static String ms_szJdbcURL; private static String ms_szUsername; private static String ms_szPassword; private static String ms_szServiceID; private static String ms_szSymbolList; // A utility to resolve the NamespacePrefix // In our case, we hard coded the namespace of the prortfolio service static private NSResolver ms_nsResolver = new NSResolver() { public String resolveNamespacePrefix(String szPrefix) { return "http://www.portfolio.org/Portfolio/Response"; } }; /** * The main function */ public static void main(String[] argv) { // Strict: Take only 3 arguments if (argv.length != 3) { System.err.println(USAGE); return; } // Extract the command line arguments int iArgCounter = 0; ms_szJdbcURL = "jdbc:oracle:thin:@" + argv[iArgCounter++] + ":1521:" + argv[iArgCounter++]; ms_szUsername = "dssys"; ms_szPassword = "dssys"; // Hardcoded service ID for "Yahoo StockQuote service" ms_szServiceID = "urn:com.yahoo:finance.portfolio03"; ms_szSymbolList = argv[iArgCounter++]; // Get quotes Hashtable ht = getQuotes(ms_szSymbolList); // Print quotes in a form printQuotes(ht); } // end of main /** * This function abstracts the process of executing the YahooPortofolio DS * service by taking in an input of a list of stock tickers and returning * all the relevant information in a java.util.Hashtable object. * * @param symbolList A white space delimited string containing the stock * symbols ( e.g. "ORCL INTC MSFT" ). * @return A Hashtable indexed by the stock symbol, and each entry of the * Hashtable is also a Hashtable which is indexed by the information * label, i.e. "Time", "Price", "Change", "Volume". */ public static Hashtable getQuotes(String symbolList) { Hashtable ht = new Hashtable(); // If we are to use a session, a header field has to be set DSConnection dsconn = null; try { // First open the connection with the Direct Driver DSDriverManager.registerDriver("oracle.ds.driver.DSDirectDriver"); dsconn = DSDriverManager.getConnection(ms_szJdbcURL); // Connect using your specified username/password dsconn.connect(ms_szUsername, ms_szPassword); System.err.println("==> Opened connection for "+ms_szUsername); // Lookup a service and obtaing the service request/response schemas DService dsServ = dsconn.lookupService(ms_szServiceID); // Make an XML request string from the symbol list String xmlRequest = "<?xml version=\"1.0\"?> \n" + "<!-- Sample request of the Yahoo! portfolio service --> \n" + "<PortfolioReq \n" + " xmlns=\"http://www.portfolio.org/Portfolio/Request\" >\n"; StringTokenizer st = new StringTokenizer(ms_szSymbolList); while (st.hasMoreTokens()) { xmlRequest = xmlRequest + "<Symbol>" + st.nextToken() + "</Symbol>\n"; } xmlRequest = xmlRequest + "</PortfolioReq>\n"; // Create a Request by requesting for a default request context // from our Dynamic Services Connection DSRequest dsReq = dsconn.createDSRequest(ms_szServiceID, new StringReader(xmlRequest)); // Execute synchronously, get the response and print it DSResponse dsResp = null; dsResp = dsconn.executeSynch(dsReq); // Get the result XML StringWriter sw = new StringWriter(); dsResp.writeResponse(sw); // Instantiate a DOM Parser to parse the result // to eventually get a Document DOMParser xmlp = new DOMParser(); xmlp.parse( new StringReader(sw.toString())); XMLDocument xmldoc = xmlp.getDocument(); // Get the list of "Quote" nodes NodeList nlist = xmldoc.getElementsByTagName("Quote"); int nsym = nlist.getLength(); // For each 'Quote' node for (int i = 0 ; i < nsym ; i ++) { XMLNode qnode = (XMLNode) nlist.item(i); // Make an entry from a quote node Hashtable entry = new Hashtable(); entry.put("Time", qnode.valueOf("./P:Time", ms_nsResolver)); entry.put("Price", qnode.valueOf("./P:Price", ms_nsResolver)); entry.put("Change", qnode.valueOf("./P:Change", ms_nsResolver)); entry.put("Volume", qnode.valueOf("./P:Volume", ms_nsResolver)); // Insert into hash table ht.put(qnode.valueOf("./P:Symbol", ms_nsResolver), entry); } // end of for } catch (Exception e) { e.printStackTrace(); } // Clean up job finally { // If I have a valid connection then do clean-up if(dsconn != null) { // Now close the connectin try { dsconn.close(); } catch(Exception e) { e.printStackTrace(); } } } // Return the final result return ht; } // end of getQuotes /** * This function outputs quotes in a Hashable to a form like * |-----+-------------------| * | | Time | 12:19PM | * | |-------+-----------| * | | Price | 30 3/16 | * |ORCL |-------+-----------| * | | Change| +0.42% | * | |-------+-----------| * | | Volume| 34,272,000| * |-----+-------------------| * | | Time | 12:19PM | * | |-------+-----------| * | | Price | 35 15/64 | * |INTC |-------+-----------| * | | Change| -2.80% | * | |-------+-----------| * | | Volume| 22,499,200| * |-----+-------------------| * | | Time | 12:19PM | * | |-------+-----------| * | | Price | 63 | * |MSFT |-------+-----------| * | | Change| +0.10% | * | |-------+-----------| * | | Volume| 24,091,600| * |-----+-------------------| * * @param ht A Java.util.Hastable that is the result of method getQuotes(). */ public static void printQuotes(Hashtable ht) { System.out.println("|-----+-------------------------|"); Enumeration e = ht.keys(); // For each key in the Hashtable while (e.hasMoreElements()) { // Key is a symbol String symbol = (String) e.nextElement(); // Get an entry Hashtable entry = (Hashtable) ht.get(symbol); // -- Time System.out.println("| | Time | " + (String) entry.get("Time") + "\t\t|" ); System.out.println("| |-------+-----------------|"); // -- Price System.out.println("| | Price | " + (String) entry.get("Price") + " \t|" ); System.out.println("|" + symbol + " |-------+-----------------|"); // -- Change System.out.println("| | Change| " + (String) entry.get("Change") + "\t\t|" ); System.out.println("| |-------+-----------------|"); // -- Volume System.out.println("| | Volume| " + (String) entry.get("Volume") + "\t|" ); System.out.println("|-----+-------------------------|"); } // end of while } // end of printQuotes }
Here is some typical XML code for SampleStock.java:
<PortfolioReq xmlns="http://www.portfolio.org/Portfolio/Request"> <Symbol>ORCL</Symbol> <Symbol>INTC</Symbol> </Portfolio>
I am investigating setting up a small language for queueing and sequencing commands. XML has obvious benefits, so I would like to know if anybody is familiar with an existing dtd for that use? This is obviously not difficult, but if a standard DTD already exists, why reinvent the wheel? Desired commands include:
Others may be required in the future.
Dynamic Services allows you to model all the commands you mentioned as XML based services.
You can define these services as well as the flow in which you can execute them. Dynamic Services engine will follow the flow (including sending email because it has SMTP services available inside the engine) and send you a completed response back. The engine is directly callable via Java/PLSQL APIs. You can also use the 'Dynamic Services Gateway' or equivalent, to accept requests over HTTP using SOAP or other SOAP like xml-rpc calls. Almost all parts of the engine are extensible to allow you to plug-in any transformation, protocol or execution flow according to your needs.
You can locate other Frequently Asked Questions (FAQs) with your DS software package at:
$ORACLE_HOME/ds/doc/dsfaq.txt
|
Copyright © 1996-2001, Oracle Corporation. All Rights Reserved. |
|