Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

...

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.

...

This document is organized in the following sections:

...

...

Application Architecture

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.

...

The business logic and persistence layer form the bulk of the DayTrader application. The TradeServices 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 implemenations implementations on the configuration page by changed the Runtime Mode.

Implementation

Details

TradeDirect
(Default)

Pattern: Servlet-to-JDBC
Runtime Mode: Direct

The TradeDirect class performs CRUD (create, read, update, and delete) operations directly agaist 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 commmitscommits.

TradeJDBC

Pattern: Servlet-to-SessionBean-to-JDBC
Runtime Mode: Session Direct

The TradeJDBC stateless session bean serves as a wrapper for TradeDirect. The session bean assumes control of all transaction management while TradeDirect remains responsible for handleing handling the JDBC operations and connections. This implementation reflects the most commonly used JavaEE application design pattern.

TradeBean

Pattern: Servlet-to-SessionBean-to-EntityBean
Runtime Mode: EJB

The TradeBean stateless session bean uses Caontainer 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.

...

As previously mentioned, all of the primary buisness business operations provided by DayTrader are defined in the TradeServices interface. These operations are discussed further in the following table.

...

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 buisness business logic and persistence layers to perform the desired task. The following table summarizes the business tasks performed by each user operation/action.

...

Daytrader is available in the Apache's subversion repository, run the following command to checkout the source files into the daytrader-1.2 directory.

svn co http://svn.apache.org/repos/asf/geronimo/daytrader/branches/1.2/Image Removed <daytrader_home>

...

  • Start Geronimo by running the following command:
    <geronimo_home>/bin/geronimo start
  • The provided database creation script requires setting the GERONIMO_HOME environment variable. On the same window you start Geronimo run the following command:
    set GERONIMO_HOME=<geronimo_home>
  • Change directory to the directory containing the database creation scripts.
    cd <daytrader_home>/bin/dbscripts/derby
  • Open createDerbyDB script and verify/modify the Derby version to match the one being used by Geronimo ( e.g. <geronimo_home>/repository/org/apache/derby/derby/10.1.3.1 ). Once you verified the versions match run the script.
    createDerbyDB
    You sould see a scree similar to the one illustrated below.
    No FormatbgColor#000000borderStylesolid D:\daytrader-1.2\bin\dbscripts\derby>createDerbyDB.bat "Invoking IJ command line tool to create the database and tables...please wait" ij version 10.1 ij> ij> ERROR 42Y55: 'DROP TABLE' cannot be performed on 'HOLDINGEJB' because it does not exist. ij> ERROR 42Y55: 'DROP TABLE' cannot be performed on 'ACCOUNTPROFILEEJB' because it does not exist. ij> ERROR 42Y55: 'DROP TABLE' cannot be performed on 'QUOTEEJB' because it does not exist. ij> ERROR 42Y55: 'DROP TABLE' cannot be performed on 'KEYGENEJB' because it does not exist. ij> ERROR 42Y55: 'DROP TABLE' cannot be performed on 'ACCOUNTEJB' because it does not exist. ij> ERROR 42Y55: 'DROP TABLE' cannot be performed on 'ORDEREJB' because it does not exist. ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> 0 rows inserted/updated/deleted ij> ij> Table creation complete
  • You can verify the database was created by pointing your browser to the Geronimo Administration Console and clicking on DB Manager.
  • The last step in this configuration is to update the deployment plan. Edit the daytrader-1.2-beta-plan.xml deployment plan located in the <daytrader_home>\plans directory and replace ge-activemq-rar/1.2-beta/rar with ge-activemq-rar/1.2/rar.

...

You should see a deployment confirmation screen similar to the one shown below.noformat

bgColor#000000borderStylesolid D:\geronimo-tomcat-j2ee-1.2\bin>deploy --user system --password manager deploy \daytrader-1.2\modules\ear\target\daytrader-ear-1.2-SNAPSHOT.ear \daytrader-1.2\plans\daytrader-1.2-beta-plan.xml Using GERONIMO_BASE: D:\geronimo-tomcat-j2ee-1.2 Using GERONIMO_HOME: D:\geronimo-tomcat-j2ee-1.2 Using GERONIMO_TMPDIR: D:\geronimo-tomcat-j2ee-1.2\var\temp Using JRE_HOME: C:\Java\jdk1.5.0_06\jre Deployed geronimo/daytrader/1.2-SNAPSHOT/car `-> web.war @ http://localhost:8080/daytrader `-> `-> dt-ejb.jar `-> geronimo/daytrader-wsapp-client/1.2-SNAPSHOT/car `-> geronimo/daytrader-streamer-client/1.2-SNAPSHOT/car `-> TradeDataSource `-> TradeJMS

Daytrader is now ready for testing.

...

  • Access the application pointing your browser to http://localhost:8080/daytraderImage Removed



  • Click on the Configuration tab.
  • Click on (Re)-populate DayTrader Database to generate the sample data, this will open a new window showing the progress.
    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.

...

Primitive

Description

PingHtml

PingHtml is the most basic operation providing access to a simple "Hello World" page of static HTML.

Explicit GC

Invoke Garbage Collection on AppServer. Reports heap statistics after the GC has completed.

PingServlet

PingServlet tests fundamental dynamic HTML creation through server side servlet processing.

PingServletWriter

PingServletWriter extends PingServlet by using a PrintWriter for formatted output vs. the output stream used by PingServlet.

PingServlet2Include

PingServlet2Include tests response inclusion. Servlet 1 includes the response of Servlet 2.

PingServlet2Servlet

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.

PingJSP

PingJSP tests a direct call to JavaServer Page providing server-side dynamic HTML through JSP scripting.

PingJSPEL

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.

PingServlet2JSP

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.

PingHTTPSession1

PingHTTPSession1 - SessionID 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.

PingHTTPSession2

PingHTTPSession2 session create/destroy further extends the previous test by invalidating the HTTP Session on every 5th user access. This results in testing HTTPSession create and destroy.

PingHTTPSession3

PingHTTPSession3 large session object 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.

PingJDBCRead

PingJDBCRead tests fundamental servlet to JDBC access to a database performing a single-row read using a prepared SQL statmentstatement.

PingJDBCWrite

PingJDBCRead tests fundamental servlet to JDBC access to a database performing a single-row write using a prepared SQL statmentstatement.

PingServlet2JNDI

PingServlet2JNDI tests the fundamental J2EE operation of a servlet allocating a JNDI context and performing a JNDI lookup of a JDBC DataSource.

...

Primitive

Description

PingServlet2SessionEJB

PingServlet2SessionEJB tests key function of a servlet call to a stateless SessionEJB. The SessionEJB performs a simple calculation and returns the result.

PingServlet2EntityEJBLocal
PingServlet2EntityEJBRemote

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 Local version uses the EJB Local interface while the Remote version uses the Remote EJB interface.
(Note: PingServlet2EntityEJBLocal will fail in a multi-tier setup where the Trade Web and EJB apps are seperatedseparated.)

PingServlet2Session2Entity

This tests the full servlet to Session EJB to Entity EJB path to retrieve a single row from the database.

PingServlet2Session2
EntityCollection

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

PingServlet2Session2CMROne2One

This test drives an Entity EJB to get another Entity EJB's data through an EJB 2.0 CMR One to One relationship

PingServlet2Session2CMROne2Many

This test drives an Entity EJB to get another Entity EJB's data through an EJB 2.0 CMR One to Many relationship

PingServlet2Session2JDBC

This tests the full servlet to Session EJB to JDBC path to retrieve a single row from the database.

PingServlet2Session2
JDBCCollection

This test extends the previous JDBC test by calling a Session EJB to JDBC path which returns multiple rows from the database.

PingServlet2MDBQueue

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.
Note: Not intended for performance testing.

PingServlet2MDBTopic

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.
Note: Not intended for performance testing.

PingServlet2TwoPhase

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.

...

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.

  • Point your browser to http://localhost:8080/daytraderImage Removed
  • Click on Configuration.
  • Click on Configure DayTrader run-time parameters.
  • Select EJB from Run-Time Mode.
  • Seclect JSP-Images from WebInterface.
  • Set Primitive Iteration to 100.
  • Click on Update Config.
  • Click on Primitives.
  • Click on PingServlet2EntityEJBLocal.

...

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.

...

  • on Trading & Portfolios.
  • Accept the default user and password and click on Login.
  • You should now be able to begin trading!

Image Added

Additional details for configuring and running Daytrader can be found in the application FAQ available by pointing your web browser to http://localhost:8080/daytrader

Back to square one

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.

  • Point your browser to http://localhost:8080/daytrader
  • Click on Configuration.
  • Click on Reset DayTrader (to be done before each run).
  • Click on (Re)-populate DayTrader Database.

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.

Image Removed

Launching the application clients

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.

Streamer application client

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. From the Daytrader Home page click on Configuration and then click

  • Point your browser to http://localhost:8080/daytrader
  • Click on Configuration.
  • Click on Configure DayTrader run-time parameters.
  • Make sure you select the Publish Quote Updates checkbox.

To start the Streamer application client run the following command.

<geronimo_home>/bin/java -jar client.jar geronimo/daytrader-streamer-client/1.2-SNAPSHOT/car

Web Services application client

<geronimo_home>/bin/java -jar client.jar geronimo/daytrader-wsapp-client/1.2-SNAPSHOT/car