Implementation
Rather than build a module to fetch stock quotes, OTN developers
used an existing Web Service. The Web Service WSDL URL is http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl,
and that's just about all the developers need to access the service. Here's
why: Oracle9i JDeveloper provides a wizard that can parse the WSDL file
and generate the Java code that a client needs to invoke the service's methods.
In this case, the generated Java class is StockQuoteServiceStub.
It provides code for connecting to the service and wrapper methods that a client
can call to interact with the service. Following is some of the code from the
generated stub class that connects to the service and wraps the getQuote
method.
/** * Generated by the Oracle9i JDeveloper Web Services Stub/Skeleton Generator. * Date Created: Fri Apr 19 15:45:47 IST 2002 * WSDL URL: http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl * * net.xmethods.services.stockquote.StockQuote web service */ public class StockQuoteServiceStub { public String endpoint = "http://66.28.98.121:9090/soap"; private OracleSOAPHTTPConnection m_httpConnection = null;
public StockQuoteServiceStub() { m_httpConnection = new OracleSOAPHTTPConnection(); } public Float getQuote(String symbol) throws Exception { Float returnVal = null; URL endpointURL = new URL(endpoint); Call call = new Call(); call.setSOAPTransport(m_httpConnection); call.setTargetObjectURI("urn:xmethods-delayed-quotes"); call.setMethodName("getQuote"); call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); Vector params = new Vector(); params.addElement(new Parameter("symbol", String.class, symbol, null)); call.setParams(params); Response response = call.invoke(endpointURL, "urn:xmethods-delayed-quotes#getQuote"); if(!response.generatedFault()) { Parameter result = response.getReturnValue(); returnVal = (Float)result.getValue(); } else { Fault fault = response.getFault(); throw new SOAPException(fault.getFaultCode(), fault.getFaultString()); } return returnVal; }
Because the FBS uses several Web Services, the developers
chose to centralize most of the service-related client code in one class, WebServicesHelper.
Following is some of the code from WebServicesHelper
that calls the getQuote method provided by the remote Web Service.
public class WebServicesHelper {
...
public WebServicesHelper() {
...
// Initialize stock quote service stub stockService = new StockQuoteServiceStub(); }
public StockRate fetchStockRate(String symbol) throws WebServiceAccessException { float rate; try { rate = stockService.getQuote(symbol).floatValue(); } catch (Exception ex) { throw new WebServiceAccessException(" Stock Quote service error : " + ex.toString()); } return new StockRate(symbol, new Date(), rate, (float) (rate + 0.5)); }
To demonstrate a different apporach, the FBS accesses another
third-party Web Service via an API provided by that third party. Specifically,
the FBS uses Google Search APIs to fetch financial news. Here is the code from
WebServicesHelper.java
that makes the connection and fetches the data.
package oracle.otnsamples.ibfbs.admin.helper;
...
import com.google.soap.search.GoogleSearch; import com.google.soap.search.GoogleSearchFault; import com.google.soap.search.GoogleSearchResult; import com.google.soap.search.GoogleSearchResultElement;
...
public class WebServicesHelper { private GoogleSearch search = null;
...
public WebServicesHelper() { // Initialize Google Search and set the key search = new GoogleSearch(); search.setKey(ConnectionParams.googleSearchKey); // Initialize stock quote service stub stockService = new StockQuoteServiceStub(); }
/** * This method retrieves the latest news for a particular symbol by accessing * the news webservice. * * @param symbol Stock symbol * @param maxResults maximum number of results for the symbol * @return news news for given symbol * @exception WebServiceAccessException if accessing webservice fails * @since 1.0 */ public Collection fetchLatestNews(String symbol, String companyName, int maxResults) throws WebServiceAccessException { ArrayList newsList = new ArrayList(); News news = null; Date today = new Date(); int julianDate = this.toJulian(today); // Set the search string search.setQueryString(new StringBuffer().append("intitle:") .append(companyName) .append(" finance stock news") .append(" daterange:") .append(julianDate-30) .append("-") .append(julianDate).toString()); // Set the maximum number of results returned search.setMaxResults(maxResults); try { // Search GoogleSearchResult searchResult = search.doSearch(); GoogleSearchResultElement[] result = searchResult.getResultElements(); // Number of matching results int noofresults = searchResult.getEndIndex(); for (int i = 0; i < noofresults; i++) { news = new News(null, today, symbol, removeHTML(result[i].getTitle()), URLEncoder.encode(result[i].getURL())); newsList.add(news); } } catch (GoogleSearchFault ex) { throw new WebServiceAccessException(" Stock News service error : " + ex.toString()); } return newsList; }
Each instance of the FBS represents a unique stock exchange.
When an FBS user buys or sells a particular stock, the order is sent to the
corresponding stock exchange as a simplified message. If the stock is not traded
in the current exchange, the FBS forwards the order to another FBS, and so on
until the trade is executed. FBS instances pass orders around via Web Services.
See ExchangeStub.java,
Exchange.java,
ExchangeHome.java,
ExchangeBean.java,
and Exchange.wsdl for implemenation
details.
|