geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Geronimo v2.2 > daytrader - a more complex application
Date Sat, 17 Oct 2009 02:37:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=GMOxDOC22&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="http://cwiki.apache.org/confluence/display/GMOxDOC22/daytrader+-+a+more+complex+application">daytrader - a more complex application</a></h2>
    <h4>Page  <b>added</b> by             <a href="http://cwiki.apache.org/confluence/display/~chirunhua@gmail.com">Runhua Chi</a>
    </h4>
         <br/>
    <div class="notificationGreySide">
         <style type='text/css'>/*<![CDATA[*/
table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color: #f0f0f0}
table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}
table.ScrollbarTable td.ScrollbarParent {text-align: center;border: none;}
table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}

/*]]>*/</style><div class="Scrollbar"><table class='ScrollbarTable'><tr><td class='ScrollbarPrevIcon'><a href="/confluence/display/GMOxDOC22/Customer+Simple+ejb+application+with+a+JPA+entity"><img border='0' align='middle' src='/confluence/images/icons/back_16.gif' width='16' height='16'></a></td><td width='33%' class='ScrollbarPrevName'><a href="/confluence/display/GMOxDOC22/Customer+Simple+ejb+application+with+a+JPA+entity">Customer Simple ejb application with a JPA entity</a>&nbsp;</td><td width='33%' class='ScrollbarParent'><sup><a href="/confluence/display/GMOxDOC22/Sample+applications"><img border='0' align='middle' src='/confluence/images/icons/up_16.gif' width='8' height='8'></a></sup><a href="/confluence/display/GMOxDOC22/Sample+applications">Sample applications</a></td><td width='33%' class='ScrollbarNextName'>&nbsp;<a href="/confluence/display/GMOxDOC22/dbtester+-+DB+Pool+Testing+sample+application">dbtester - DB Pool Testing sample application</a></td><td class='ScrollbarNextIcon'><a href="/confluence/display/GMOxDOC22/dbtester+-+DB+Pool+Testing+sample+application"><img border='0' align='middle' src='/confluence/images/icons/forwd_16.gif' width='16' height='16'></a></td></tr></table></div>

<p>DayTrader is benchmark application built around the paradigm of an online stock trading system. Originally developed by IBM as the Trade Performance Benchmark Sample, DayTrader was donated to the Apache Geronimo community in 2005. This application allows users to login, view their portfolio, lookup stock quotes, and buy or sell stock shares. With the aid of a Web-based load driver such as Mercury LoadRunner, Rational Performance Tester, or Apache JMeter, the real-world workload provided by DayTrader can be used to measure and compare the performance of Java Platform, Enterprise Edition (Java EE) application servers offered by a variety of vendors. </p>

<p>In addition to the full workload, the application also contains a set of primitives used for functional and performance testing of various Java EE components and common design patterns.</p>

<p>This document is organized in the following sections:</p>

<div>
<ul>
    <li><a href='#daytrader-amorecomplexapplication-ApplicationArchitecture'>Application Architecture</a></li>
<ul>
    <li><a href='#daytrader-amorecomplexapplication-PresentationLayer'>Presentation Layer</a></li>
    <li><a href='#daytrader-amorecomplexapplication-BusinessLogicandPersistenceLayer'>Business Logic and Persistence Layer</a></li>
    <li><a href='#daytrader-amorecomplexapplication-BusinessObjectsandRelationships'>Business Objects and Relationships</a></li>
    <li><a href='#daytrader-amorecomplexapplication-BusinessOperations%28asdefinedinTradeServices%29'>Business Operations (as defined in TradeServices)</a></li>
    <li><a href='#daytrader-amorecomplexapplication-UserInerface%28UI%29Operations'>User Inerface (UI) Operations</a></li>
</ul>
    <li><a href='#daytrader-amorecomplexapplication-Gettingthesource'>Getting the source</a></li>
    <li><a href='#daytrader-amorecomplexapplication-BuildingDaytrader'>Building Daytrader</a></li>
    <li><a href='#daytrader-amorecomplexapplication-ConfiguringDaytrader'>Configuring Daytrader</a></li>
    <li><a href='#daytrader-amorecomplexapplication-DeployingDaytrader'>Deploying Daytrader</a></li>
    <li><a href='#daytrader-amorecomplexapplication-Populatingsampledata'>Populating sample data</a></li>
    <li><a href='#daytrader-amorecomplexapplication-RunningDaytrader'>Running Daytrader</a></li>
<ul>
    <li><a href='#daytrader-amorecomplexapplication-WebContainerpingsuite'>Web Container ping suite</a></li>
    <li><a href='#daytrader-amorecomplexapplication-EJBContainerpingsuite'>EJB Container ping suite</a></li>
    <li><a href='#daytrader-amorecomplexapplication-ConfigureDayTraderruntime'>Configure DayTrader run-time</a></li>
<ul>
    <li><a href='#daytrader-amorecomplexapplication-MiscellaneousSettings'>Miscellaneous Settings</a></li>
</ul>
    <li><a href='#daytrader-amorecomplexapplication-RunningPrimitives'>Running Primitives</a></li>
    <li><a href='#daytrader-amorecomplexapplication-Gonetrading%21%21%21'>Gone trading !!!</a></li>
    <li><a href='#daytrader-amorecomplexapplication-Backtosquareone'>Back to square one</a></li>
</ul>
    <li><a href='#daytrader-amorecomplexapplication-Launchingtheapplicationclients'>Launching the application clients</a></li>
<ul>
    <li><a href='#daytrader-amorecomplexapplication-Streamerapplicationclient'>Streamer application client</a></li>
    <li><a href='#daytrader-amorecomplexapplication-WebServicesapplicationclient'>Web Services application client</a></li>
</ul>
</ul></div>

<h1><a name="daytrader-amorecomplexapplication-ApplicationArchitecture"></a>Application Architecture</h1>
<p>DayTrader is built on a core set of Java EE technologies that includes Java Servlets and JavaServer Pages (JSPs) for the presentation layer and Java database connectivity (JDBC), Java Message Service (JMS), Enterprise JavaBeans (EJBs) and Message-Driven Beans (MDBs) for the back-end business logic and persistence layer. The following diagram provides a high-level overview of the full workload application architecture.</p>

<p><span class="error">Unable to render embedded object: File (daytrader_simple_arch.gif) not found.</span></p>

<h2><a name="daytrader-amorecomplexapplication-PresentationLayer"></a>Presentation Layer</h2>
<p>The presentation layer consists of several Java Servlets and JSPs that loosely adhere to a Model-View-Controller (MVC) design pattern. <em>TradeAppServlet</em> is the primary controller servlet responsible for recieving incoming client requests, triggering the desired business logic, and forwarding responses to the appropriate JSP page. Additional servlets and JSPs are used to configure the DayTrader runtime options and manage the supporting database. </p>

<h2><a name="daytrader-amorecomplexapplication-BusinessLogicandPersistenceLayer"></a>Business Logic and Persistence Layer</h2>
<p>The business logic and persistence layer form the bulk of the DayTrader application. The <em>TradeServices</em> interface defines the core set of business operations available in the application, such as register, login, getHoldings, buy, completeOrder, logout, etc. DayTrader provides three different implementations of these services, corresponding to three commonly used JavaEE application design patterns. These implementations are discussed below. Users can switch between these implementations on the configuration page by changed the Runtime Mode.</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Implementation  </th>
<th class='confluenceTh'> Details </th>
</tr>
<tr>
<td class='confluenceTd'> <b>TradeDirect</b> <br clear="all" /> (Default) </td>
<td class='confluenceTd'> <b>Pattern:</b> Servlet-to-JDBC<br clear="all" /> <b>Runtime Mode:</b> Direct<br clear="all" /> <br clear="all" /> The <em>TradeDirect</em> class performs CRUD (create, read, update, and delete) operations directly against the supporting database using custom JDBC code. Database connections, commits, and rollbacks are managed manually in the code. JTA user transactions are used to coordinate 2-phase commits. </td>
</tr>
<tr>
<td class='confluenceTd'> <b>TradeJDBC</b> </td>
<td class='confluenceTd'> <b>Pattern:</b> Servlet-to-SessionBean-to-JDBC<br clear="all" /> <b>Runtime Mode:</b> Session Direct <br clear="all" /> <br clear="all" /> The <em>TradeJDBC</em> stateless session bean serves as a wrapper for TradeDirect. The session bean assumes control of all transaction management while TradeDirect remains responsible for handling the JDBC operations and connections. This implementation reflects the most commonly used JavaEE application design pattern. </td>
</tr>
<tr>
<td class='confluenceTd'> <b>TradeBean</b> </td>
<td class='confluenceTd'> <b>Pattern:</b> Servlet-to-SessionBean-to-EntityBean<br clear="all" /> <b>Runtime Mode:</b> EJB<br clear="all" /> <br clear="all" /> The <em>TradeBean</em> stateless session bean uses Container Managed Persistence (CMP) entity beans to represent the business objects. The state of these objects is completely managed by the application servers EJB container. </td>
</tr>
</tbody></table>

<p>Another subtle component of this layer involves the Java Messaging Service (JMS). JMS is used within DayTrader for two specific purposes, asynchronously processing buy/sell orders, and publishing quote price updates. The following table discusses these operations in further detail.</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Operation </th>
<th class='confluenceTh'> Details </th>
</tr>
<tr>
<td class='confluenceTd'> Asynchrounous Order Processing </td>
<td class='confluenceTd'> When a buy or sell operation is performed, an order request is placed on the TradeBroker JMS queue using a client connection. The TradeBrokerMDB consumes messages on this queue and completes the buy or sell operation. </td>
</tr>
<tr>
<td class='confluenceTd'> Quote Price Updates </td>
<td class='confluenceTd'> As stocks are traded, the associated quote prices are updated in the database and published to a JMS topic. The TradeStreamerMDB subscribes to these updates consuming  the price updates messages, but does nothing more with them. The TradeStreamer JavaEE client that is bundled with DayTrader can be started to view the quote prices updates in real time. </td>
</tr>
</tbody></table>

<h2><a name="daytrader-amorecomplexapplication-BusinessObjectsandRelationships"></a>Business Objects and Relationships</h2>
<p>The following diagram represents the database schema and associated business objects. Container managed relationships (CMRs) are also depicted in the diagram.</p>

<p><b>Create diagram and add here</b></p>

<h2><a name="daytrader-amorecomplexapplication-BusinessOperations%28asdefinedinTradeServices%29"></a>Business Operations (as defined in TradeServices)</h2>
<p>As previously mentioned, all of the primary business operations provided by DayTrader are defined in the TradeServices interface. These operations are discussed further in the following table.</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> TradeServices Operation </th>
<th class='confluenceTh'> Details </th>
</tr>
<tr>
<td class='confluenceTd'> login </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> logout </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> buy </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> sell </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getMarketSummary </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> queueOrder </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> completeOrder </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> cancelOrder </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> orderCompleted </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getOrders </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getClosedOrders </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> createQuote </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getQuote </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getAllQuotes </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> updateQuotePriceVolume </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getHoldings </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getHolding </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getAccountData </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> getAccountProfileData </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> updateAccountProfile </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> register </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> resetTrade </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
</tbody></table>

<h2><a name="daytrader-amorecomplexapplication-UserInerface%28UI%29Operations"></a>User Inerface (UI) Operations</h2>
<p>The DayTrader JSP/Servlet-based web client provides a basic set of operations that one would expect to find in any stock trading and portfolio management application. These high level user operations trigger specific business operations (defined above) within the business logic and persistence layers to perform the desired task. The following table summarizes the business tasks performed by each user operation/action.</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Client (UI) Operation </th>
<th class='confluenceTh'> Flow of Business Operations </th>
</tr>
<tr>
<td class='confluenceTd'> Register </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> Login </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> View Account </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> View Account Profile </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> Update Account Profile </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> View Portfolio </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> Sell Holding </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> View Quotes </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> Buy Stock </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
<tr>
<td class='confluenceTd'> Logout </td>
<td class='confluenceTd'>&nbsp;</td>
</tr>
</tbody></table>

<h1><a name="daytrader-amorecomplexapplication-Gettingthesource"></a>Getting the source</h1>
<p>Daytrader is available in the Apache's subversion repository, run the following command to checkout the source files into the <b>daytrader-2.0</b> directory.</p>

<p><b><tt>svn co <a href="http://svn.apache.org/repos/asf/geronimo/daytrader/trunk/" rel="nofollow">http://svn.apache.org/repos/asf/geronimo/daytrader/trunk/</a> &lt;daytrader_home&gt;</tt></b></p>

<p><b>&lt;daytrader_home&gt;</b> could be any directory dedicated to hold daytrader-2.0.</p>

<p>This process may take several minutes depending on the machine and network connectivity speed.</p>

<h1><a name="daytrader-amorecomplexapplication-BuildingDaytrader"></a>Building Daytrader</h1>
<p>Once all the sources get checked out the next step is to build Daytrader. Daytrader requires Maven 2 for building the binaries.</p>

<p>From the <b>&lt;daytrader_home&gt;</b> directory run the following command.</p>

<p><b><tt>mvn install</tt></b></p>

<p>This process will take a couple of minutes. The binaries will be generated in the corresponding <b>target</b> directory for each of the modules in the <b>modules</b> directory.</p>

<h1><a name="daytrader-amorecomplexapplication-ConfiguringDaytrader"></a>Configuring Daytrader</h1>
<p>By default Daytrader requires a database to be created using the embedded Derby database that is shipped with Geronimo. Typically, the provided deployment plan files are configured to create such database (DaytraderDatabase) on Apache Derby during deployment. However, scripts are provided within the <b>&lt;daytrader_home&gt;/bin/dbscripts/derby</b> directory to create this database manually. Note that at this point this step <b>optional</b>, you can still create the required database after deploying Daytrader and using the <b>(Re)-create  DayTrader Database Tables and Indexes</b> link from the application's <b>Configuration Utility</b> page.</p>

<p>Independently on whether you use the command line scripts or the web based option, you will need the tables created before getting to the <a href="#daytrader-amorecomplexapplication-Populatingsampledata">Populating sample data</a> section.</p>

<p>The puspose of this section is to show you how to use the provided scripts to create the required <b>DaytraderDatabase</b> so, if needed, you can adapt them to your specific configuration environment. Additional scripts for different databases are also provided.</p>

<ul>
	<li>Start Geronimo by running the following command:
<br clear="all" />
  <b><tt>&lt;geronimo_home&gt;/bin/geronimo start</tt></b>
<br clear="all" /></li>
	<li>The provided database creation script requires setting the <b>GERONIMO_HOME</b> environment variable. On the same window you start Geronimo run the following command:
<br clear="all" />
<b><tt>set GERONIMO_HOME=&lt;geronimo_home&gt;</tt></b>
<br clear="all" /></li>
	<li>Change directory to the directory containing the database creation scripts.
<br clear="all" />
<b><tt>cd &lt;daytrader_home&gt;/bin/dbscripts/derby</tt></b>
<br clear="all" /></li>
	<li>Open <b><tt>createDerbyDB</tt></b> script and verify/modify the Derby version to match the one being used by Geronimo ( e.g. &lt;geronimo_home&gt;/repository/org/apache/derby/derby/10.2.2.0 ). Once you verified the versions match run the script.
<br clear="all" />
<b><tt>createDerbyDB</tt></b>
<br clear="all" />
You sould see a scree similar to the one illustrated below.<br/>
<font color="white">
<div class="preformatted panel" style="background-color: #000000;border-style: solid;border-width: 1px;"><div class="preformattedContent panelContent" style="background-color: #000000;">
<pre>D:\daytrader-2.0\bin\dbscripts\derby&gt;createDerbyDB.bat
"Invoking IJ command line tool to create the database and tables...please wait"
ij version 10.2.2.0
ij&gt; ij&gt; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'HOLDINGEJB' because it does not exist.
ij&gt; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'ACCOUNTPROFILEEJB' because it does not exist.
ij&gt; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'QUOTEEJB' because it does not exist.
ij&gt; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'KEYGENEJB' because it does not exist.
ij&gt; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'ACCOUNTEJB' because it does not exist.
ij&gt; ERROR 42Y55: 'DROP TABLE' cannot be performed on 'ORDEREJB' because it does not exist.
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; 0 rows inserted/updated/deleted
ij&gt; ij&gt; Table creation complete
</pre>
</div></div></font></li>
	<li>You can verify the database was created by pointing your browser to the Geronimo Administration Console and clicking on <b>DB Manager</b>.</li>
	<li>The last step in this configuration is to update the deployment plan.  Edit the <b><tt>daytrader-g-2.0-SNAPSHOT-plan.xml</tt></b> deployment plan located in the <b>&lt;daytrader_home&gt;\plans</b> directory and replace <b><tt>ge-activemq-rar/1.2-beta/rar</tt></b> with <b><tt>ge-activemq-rar/1.2/rar</tt></b>.</li>
</ul>


<p>You are now ready to deploy the application.</p>

<h1><a name="daytrader-amorecomplexapplication-DeployingDaytrader"></a>Deploying Daytrader</h1>
<p>So far we have retrieved the source file, built, configured, created a database and updated the deployment plan. Now it is time to install the Daytrader application in Geronimo.</p>

<p>There are basically two ways to deploy an application in Geronimo, either using the Geronimo Administration Console or the command line based deployer tool. For this example we will be using the command line based option.</p>

<p>From the <b>&lt;geronimo_home&gt;/bin</b> directory run the following command:</p>

<p><b><tt>deploy --user system --password manager deploy &lt;daytrader_home&gt;\modules\ear\target\daytrader-ear-2.0-SNAPSHOT.ear &lt;daytrader_home&gt;\plans\daytrader-g-2.0-SNAPSHOT-plan.xml</tt></b></p>

<p>The first <b><tt>deploy</tt></b> is the script that calls the deployer tool, then we pass the user name and password. The second <b><tt>deploy</tt></b> is the actual command option for deploying the <b><tt>daytrader-ear-2.0-SNAPSHOT.ear</tt></b> EAR using the <b><tt>daytrader-g-2.0-SNAPSHOT-plan.xml</tt></b> deployment plan specifically. In your own application you could call this plan <tt>geronimo-application.xml</tt> and place it in the <tt>META-INF</tt> directory within you EAR file and you will not need to expressly specify the deployment plan from the command line.</p>

<p>You should see a deployment confirmation screen similar to the one shown below.</p>

<p><font color="white">
<div class="preformatted panel" style="background-color: #000000;border-style: solid;border-width: 1px;"><div class="preformattedContent panelContent" style="background-color: #000000;">
<pre>D:\geronimo-tomcat6-javaee5-2.1\bin&gt;deploy --user system --password manager deploy \daytrader-2.0\modules\ear\target\daytrader-ear-2.0-SNAPSHOT.ear \daytrader-2.0\plans\daytrader-g-2.0-SNAPSHOT-plan.xml
Using GERONIMO_BASE:   D:\geronimo-tomcat6-javaee5-2.1
Using GERONIMO_HOME:   D:\geronimo-tomcat6-javaee5-2.1
Using GERONIMO_TMPDIR: D:\geronimo-tomcat6-javaee5-2.1\var\temp
Using JRE_HOME:        C:\Java\jdk1.5.0_06\jre
    Deployed geronimo/daytrader/2.0-SNAPSHOT/car
      `-&gt; web.war @ http://localhost:8080/daytrader
      `-&gt; dt-ejb.jar
      `-&gt; geronimo/daytrader-wsapp-client/2.0-SNAPSHOT/car
      `-&gt; geronimo/daytrader-streamer-client/2.0-SNAPSHOT/car
      `-&gt; TradeDataSource
      `-&gt; TradeJMS
</pre>
</div></div></font></p>

<p>Daytrader is now ready for testing.</p>

<h1><a name="daytrader-amorecomplexapplication-Populatingsampledata"></a>Populating sample data</h1>
<p>With the application deployed and started (starts by default when you deploy it) the next step before using Daytrader is to populate sample data to the database we created before. The following steps illustrate how.</p>

<ul>
	<li>Access the application pointing your browser to <a href="http://localhost:8080/daytrader" rel="nofollow">http://localhost:8080/daytrader</a>
<br clear="all" /> <br clear="all" />
<span class="error">Unable to render embedded object: File (daytrader.jpg) not found.</span>
<br clear="all" /> <br clear="all" /></li>
	<li>Click on the <b>Configuration</b> tab.</li>
	<li>Click on <b>(Re)-populate  DayTrader Database</b> to generate the sample data, this will open a new window showing the progress.<br/>
The initial population size consists of 200 accounts and 400 stock quotes. These values can be updated via the "Configure DayTrader run-time parameters" link on the "Configuration" tab.</li>
</ul>


<h1><a name="daytrader-amorecomplexapplication-RunningDaytrader"></a>Running Daytrader</h1>
<p>Daytrader can be run in number of configurations and also provides a suite of web primitives to ease testing. Each of these primitives singularly test key operations in the enterprise Java programming model. Some of these can be configured to run repeateadly based on the configuration settings that we will cover later on. The following sections describe more in detail these primitives test suite.</p>

<h2><a name="daytrader-amorecomplexapplication-WebContainerpingsuite"></a>Web Container ping suite</h2>
<p>The following table describe the Web container related set of primitives. Those primitives that can be set to run multiple times are <b>highlighted</b>.</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Primitive		</th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'>PingHtml  		</td>
<td class='confluenceTd'> PingHtml is the most basic operation providing access to a simple "Hello World" page of static HTML. </td>
</tr>
<tr>
<td class='confluenceTd'>Explicit GC 		</td>
<td class='confluenceTd'> Invoke Garbage Collection on AppServer. Reports heap statistics after the GC has completed. </td>
</tr>
<tr>
<td class='confluenceTd'>PingServlet 		</td>
<td class='confluenceTd'> PingServlet tests fundamental dynamic HTML creation through server side servlet processing. </td>
</tr>
<tr>
<td class='confluenceTd'>PingServletWriter 	</td>
<td class='confluenceTd'> PingServletWriter extends PingServlet by using a PrintWriter for formatted output vs. the output stream used by PingServlet. </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2Include</b> 	</td>
<td class='confluenceTd'> PingServlet2Include tests response inclusion. Servlet 1 includes the response of Servlet 2. </td>
</tr>
<tr>
<td class='confluenceTd'>PingServlet2Servlet 	</td>
<td class='confluenceTd'> PingServlet2Servlet tests request dispatching. Servlet 1, the controller, creates a new JavaBean object forwards the request with the JavaBean added to Servlet 2. Servlet 2 obtains access to the JavaBean through the Servlet request object and provides dynamic HTML output based on the JavaBean data. </td>
</tr>
<tr>
<td class='confluenceTd'>PingJSP 		</td>
<td class='confluenceTd'> PingJSP tests a direct call to JavaServer Page providing server-side dynamic HTML through JSP scripting. </td>
</tr>
<tr>
<td class='confluenceTd'>PingJSPEL 		</td>
<td class='confluenceTd'> PingJSPEL tests a direct call to JavaServer Page providing server-side dynamic HTML through JSP scripting and the usage of the new JSP 2.0 Expression Language. </td>
</tr>
<tr>
<td class='confluenceTd'>PingServlet2JSP 	</td>
<td class='confluenceTd'> PingServlet2JSP tests a commonly used design pattern, where a request is issued to servlet providing server side control processing. The servlet creates a JavaBean object with dynamically set attributes and forwards the bean to the JSP through a RequestDispatcher The JSP obtains access to the JavaBean and provides formatted display with dynamic HTML output based on the JavaBean data. </td>
</tr>
<tr>
<td class='confluenceTd'>PingHTTPSession1 	</td>
<td class='confluenceTd'> PingHTTPSession1 - <b><tt>SessionID</tt></b> tests fundamental HTTP session function by creating a unique session ID for each individual user. The ID is stored in the users session and is accessed and displayed on each user request. </td>
</tr>
<tr>
<td class='confluenceTd'>PingHTTPSession2 	</td>
<td class='confluenceTd'> PingHTTPSession2 <b><tt>session create/destroy</tt></b> further extends the previous test by invalidating the HTTP Session on every 5th user access. This results in testing HTTPSession create and destroy. </td>
</tr>
<tr>
<td class='confluenceTd'>PingHTTPSession3 	</td>
<td class='confluenceTd'> PingHTTPSession3 <b><tt>large session object</tt></b> tests the servers ability to manage and persist large HTTPSession data objects. The servlet creates a large custom java object. The class contains multiple data fields and results in 2048 bytes of data. This large session object is retrieved and stored to the session on each user request. </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingJDBCRead</b> 	</td>
<td class='confluenceTd'> PingJDBCRead tests fundamental servlet to JDBC access to a database performing a single-row read using a prepared SQL statement. </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingJDBCWrite</b> 	</td>
<td class='confluenceTd'> PingJDBCRead tests fundamental servlet to JDBC access to a database performing a single-row write using a prepared SQL statement. </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2JNDI</b> 	</td>
<td class='confluenceTd'> PingServlet2JNDI tests the fundamental J2EE operation of a servlet allocating a JNDI context and performing a JNDI lookup of a JDBC DataSource. </td>
</tr>
</tbody></table>

<h2><a name="daytrader-amorecomplexapplication-EJBContainerpingsuite"></a>EJB Container ping suite</h2>
<p>The following table describe the EJB container related set of primitives. Those primitives that can be set to run multiple times are <b>highlighted</b>.</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Primitive				</th>
<th class='confluenceTh'> Description </th>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2SessionEJB</b>  		</td>
<td class='confluenceTd'> PingServlet2SessionEJB tests key function of a servlet call to a stateless SessionEJB. The SessionEJB performs a simple calculation and returns the result. </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2EntityEJBLocal</b>		<br clear="all" />	 
<b>PingServlet2EntityEJBRemote</b>		</td>
<td class='confluenceTd'> PingServlet2EntityEJB tests key function of a servlet call to an EJB 2.0 Container Managed Entity. In this test the EJB entity represents a single row in the database table. The <b><tt>Local version</tt></b> uses the EJB Local interface while the <b><tt>Remote version</tt></b> uses the Remote EJB interface. <br clear="all" /> (Note: PingServlet2EntityEJBLocal will fail in a multi-tier setup where the Trade Web and EJB apps are separated.) </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2Session2Entity</b>		</td>
<td class='confluenceTd'> This tests the full servlet to Session EJB to Entity EJB path to retrieve a single row from the database. </td>
</tr>
<tr>
<td class='confluenceTd'>PingServlet2Session2			<br clear="all" />
<b>EntityCollection</b> 			</td>
<td class='confluenceTd'> This test extends the previous EJB Entity test by calling a Session EJB which uses a finder method on the Entity that returns a collection of Entity objects. Each object is displayed by the servlet </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2Session2CMROne2One</b> 	</td>
<td class='confluenceTd'> This test drives an Entity EJB to get another Entity EJB's data through an EJB 2.0 CMR One to One relationship </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2Session2CMROne2Many</b> 	</td>
<td class='confluenceTd'> This test drives an Entity EJB to get another Entity EJB's data through an EJB 2.0 CMR One to Many relationship </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2Session2JDBC</b> 		</td>
<td class='confluenceTd'> This tests the full servlet to Session EJB to JDBC path to retrieve a single row from the database. </td>
</tr>
<tr>
<td class='confluenceTd'>PingServlet2Session2			<br clear="all" />
<b>JDBCCollection</b> 			</td>
<td class='confluenceTd'> This test extends the previous JDBC test by calling a Session EJB to JDBC path which returns multiple rows from the database. </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2MDBQueue</b> 		</td>
<td class='confluenceTd'> PingServlet2MDBQueue drives messages to a Queue based Message Driven EJB (MDB).Each request to the servlet posts a message to the Queue. The MDB receives the message asynchronously and prints message delivery statistics on each 100th message. <br clear="all" /> <b><tt>Note: Not intended for performance testing.</tt></b> </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2MDBTopic</b> 		</td>
<td class='confluenceTd'> PingServlet2MDBTopic drives messages to a Topic based Publish/Subscribe Message Driven EJB (MDB).Each request to the servlet posts a message to the Topic. The TradeStreamMDB receives the message asynchronously and prints message delivery statistics on each 100th message. Other subscribers to the Topic will also receive the messages.  <br clear="all" /> <b><tt>Note: Not intended for performance testing.</tt></b> </td>
</tr>
<tr>
<td class='confluenceTd'><b>PingServlet2TwoPhase</b> 		</td>
<td class='confluenceTd'> PingServlet2TwoPhase drives a Session EJB which invokes an Entity EJB with findByPrimaryKey (DB Access) followed by posting a message to an MDB through a JMS Queue (Message access). These operations are wrapped in a global 2-phase transaction and commit. </td>
</tr>
</tbody></table>

<h2><a name="daytrader-amorecomplexapplication-ConfigureDayTraderruntime"></a>Configure DayTrader run-time</h2>
<p>So now you know what set of primitives are available and which of those can be set to run multiple times. The following table describes what parameters are available from the Daytrader <b>Configuration Utilities</b> to set the runtime parameters.</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Parameter		</th>
<th class='confluenceTh'> Option	</th>
<th class='confluenceTh'> Description	</th>
</tr>
<tr>
<td class='confluenceTd'> Run-Time Mode		</td>
<td class='confluenceTd'> EJB		<br clear="all" />
			  Direct	<br clear="all" />
			  SessionDirect	<br clear="all" />
			  JPA		</td>
<td class='confluenceTd'> Run Time Mode determines server implementation of the TradeServices to use in the DayTrader application Enterprise Java Beans including Session, Entity and Message beans or Direct mode which uses direct database and JMS access. </td>
</tr>
<tr>
<td class='confluenceTd'> Order-Processing Mode	</td>
<td class='confluenceTd'> Synchronous	<br clear="all" />
			  Asynchronous_2-Phase </td>
<td class='confluenceTd'> Order Processing Mode determines the mode for completing stock purchase and sell operations. Synchronous mode completes the order immediately. Asychronous_2-Phase performs a 2-phase commit over the EJB Entity/DB and MDB/JMS transactions. </td>
</tr>
<tr>
<td class='confluenceTd'> Access Mode		</td>
<td class='confluenceTd'> Standard	<br clear="all" />
			  WebServices	</td>
<td class='confluenceTd'> Access Mode determines the protocol used by the DayTrader Web application to access server side services. The Standard mode uses the default Java RMI protocol. The Web Services mode uses the Axis implementation of Web Services including SOAP, WSDL and UDDI. </td>
</tr>
<tr>
<td class='confluenceTd'> Scenario Workload Mix	</td>
<td class='confluenceTd'> Standard	<br clear="all" />
			  High-Volume	</td>
<td class='confluenceTd'> This setting determines the runtime workload mix of DayTrader operations when driving the benchmark through TradeScenarioServlet. </td>
</tr>
<tr>
<td class='confluenceTd'> WebInterface		</td>
<td class='confluenceTd'> JSP		<br clear="all" />
			  JSP-Images	</td>
<td class='confluenceTd'> This setting determines the Web interface technology used, JSPs or JSPs with static images and GIFs. </td>
</tr>
</tbody></table>

<h3><a name="daytrader-amorecomplexapplication-MiscellaneousSettings"></a>Miscellaneous Settings</h3>
<table class='confluenceTable'><tbody>
<tr>
<td class='confluenceTd'> DayTrader Max Users	<br clear="all" />
Trade Max Quotes	</td>
<td class='confluenceTd'> By default the DayTrader database is populated with 50 users (uid:0 - uid:49) and 100 quotes (s:0 - s:99). </td>
</tr>
<tr>
<td class='confluenceTd'> Primitive Iteration	</td>
<td class='confluenceTd'> By default the DayTrader primitives are execute one operation per web request. Change this value to repeat operations multiple times per web request. </td>
</tr>
<tr>
<td class='confluenceTd'> Publish Quote Updates	</td>
<td class='confluenceTd'> Publish quote price changes to a JMS topic. Needed for running the <a href="#daytrader-amorecomplexapplication-Streamerapplicationclient">Streamer application client</a>. </td>
</tr>
<tr>
<td class='confluenceTd'> Enable long run support</td>
<td class='confluenceTd'> Enable long run support by disabling the show all orders query performed on the Account page. </td>
</tr>
<tr>
<td class='confluenceTd'> Enable operation trace <br clear="all" />
Enable full trace	</td>
<td class='confluenceTd'> Enable DayTrader processing trace messages. </td>
</tr>
</tbody></table>

<h2><a name="daytrader-amorecomplexapplication-RunningPrimitives"></a>Running Primitives</h2>
<p>So far we saw what primitives are available, which of those can be set to run multiple iterations and how to configure the application runtime parameters.</p>

<ul>
	<li>Point your browser to <a href="http://localhost:8080/daytrader" rel="nofollow">http://localhost:8080/daytrader</a></li>
	<li>Click on <b>Configuration</b>.</li>
	<li>Click on <b>Configure DayTrader run-time parameters</b>.</li>
	<li>Select <b>EJB</b> from <b>Run-Time Mode</b>.</li>
	<li>Seclect <b>JSP-Images</b> from <b>WebInterface</b>.</li>
	<li>Set <b>Primitive Iteration</b> to <b><tt>100</tt></b>.</li>
	<li>Click on <b>Update Config</b>.</li>
	<li>Click on <b>Primitives</b>.</li>
	<li>Click on <b>PingServlet2EntityEJBLocal</b>.</li>
</ul>


<p>With these settings, every time you hit <b>PingServlet2EntityEJBLocal</b> or refresh the page that primitive will get executed <b><tt>100</tt></b> times. When doing performance analysis, being able to "play" with these parameters is very valuable. This helps you track down execution times of these very specific functions. When used combined with a load simulation tool, the different configurations will assist you with the fine tuning of the server based on the specific needs of your environment.</p>

<h2><a name="daytrader-amorecomplexapplication-Gonetrading%21%21%21"></a>Gone trading !!!</h2>
<p>We just saw how to run singular functions/operations tests via the available primitives. The very same settings you configured for running those primitives also affect the GUI for trading simulation.</p>

<ul>
	<li>Point your browser to <a href="http://localhost:8080/daytrader" rel="nofollow">http://localhost:8080/daytrader</a></li>
	<li>Click on <b>Trading &amp; Portfolios</b>.</li>
	<li>Accept the default user and password and click on <b>Login</b>.</li>
	<li>You should now be able to begin trading!</li>
</ul>


<p><span class="error">Unable to render embedded object: File (daytrader_2a.jpg) not found.</span></p>

<p>Additional details for configuring and running Daytrader can be found in the application <b>FAQ</b> available by pointing your web browser to <a href="http://localhost:8080/daytrader" rel="nofollow">http://localhost:8080/daytrader</a></p>

<h2><a name="daytrader-amorecomplexapplication-Backtosquareone"></a>Back to square one</h2>
<p>After you performed some tests and want to run a new set from scratch you will need to reset the runtime configuration and transaction data from the database.</p>

<ul>
	<li>Point your browser to <a href="http://localhost:8080/daytrader" rel="nofollow">http://localhost:8080/daytrader</a></li>
	<li>Click on <b>Configuration</b>.</li>
	<li>Click on <b>Reset DayTrader (to be done before each run)</b>.</li>
	<li>Click on <b>(Re)-populate  DayTrader Database</b>.</li>
</ul>


<p>These simple steps are all you need to start a new set of tests on Daytrader however, you may still want to restart the server depending on the type of tests you are running.</p>

<h1><a name="daytrader-amorecomplexapplication-Launchingtheapplicationclients"></a>Launching the application clients</h1>
<p>DayTrader provides two J2EE application clients, the DayTrader Streamer and a web services application. The Streamer application client uses a JMS topic to subscribe to quote price updates as stocks are bought and sold. These updates are tracked and used to determine if database collisions occur while updating the quote prices in the database. The web services application client simply provides a thick client for accessing DayTrader services using a web services interface.</p>

<h2><a name="daytrader-amorecomplexapplication-Streamerapplicationclient"></a>Streamer application client</h2>
<p>In order for the quote price updates to get published to the JMS topic, the "Publish Quote Updates" flag on the configuration page must be enabled.</p>

<ul>
	<li>Point your browser to <a href="http://localhost:8080/daytrader" rel="nofollow">http://localhost:8080/daytrader</a></li>
	<li>Click on <b>Configuration</b>.</li>
	<li>Click on <b>Configure DayTrader run-time parameters</b>.</li>
	<li>Make sure you select the <b>Publish Quote Updates</b> checkbox.</li>
</ul>


<p>To start the Streamer application client run the following command.</p>

<p><b><tt>&lt;geronimo_home&gt;/bin/java -jar client.jar geronimo/daytrader-streamer-client/2.0-SNAPSHOT/car</tt></b></p>

<p><span class="error">Unable to render embedded object: File (daytrader_3.jpg) not found.</span></p>

<h2><a name="daytrader-amorecomplexapplication-WebServicesapplicationclient"></a>Web Services application client</h2>
<p><b><tt>&lt;geronimo_home&gt;/bin/java -jar client.jar geronimo/daytrader-wsapp-client/2.0-SNAPSHOT/car</tt></b></p>
    </div>
    <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
       </div>
       <a href="http://cwiki.apache.org/confluence/display/GMOxDOC22/daytrader+-+a+more+complex+application">View Online</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/GMOxDOC22/daytrader+-+a+more+complex+application?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
           </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message