db-ojb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From t...@apache.org
Subject cvs commit: db-ojb/src/test/org/apache/ojb/broker PerformanceJdbcFailoverTest.java
Date Thu, 15 May 2003 06:18:51 GMT
thma        2003/05/14 23:18:51

  Added:       src/test/org/apache/ojb/broker
                        PerformanceJdbcFailoverTest.java
  Log:
  add a Testcase to test database failover
  
  Revision  Changes    Path
  1.1                  db-ojb/src/test/org/apache/ojb/broker/PerformanceJdbcFailoverTest.java
  
  Index: PerformanceJdbcFailoverTest.java
  ===================================================================
  package org.apache.ojb.broker;
  
  import junit.framework.TestCase;
  import org.apache.ojb.broker.accesslayer.ConnectionFactory;
  import org.apache.ojb.broker.accesslayer.ConnectionFactoryFactory;
  import org.apache.ojb.broker.metadata.ClassDescriptor;
  import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
  import org.apache.ojb.broker.metadata.MetadataManager;
  import org.apache.ojb.broker.query.Criteria;
  import org.apache.ojb.broker.query.Query;
  import org.apache.ojb.broker.query.QueryByCriteria;
  import org.apache.ojb.broker.util.logging.Logger;
  import org.apache.ojb.broker.util.logging.LoggerFactory;
  
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  
  /**
   * This TestCase contains the OJB performance benchmarks for the
   * JDBC API. The original testcases have been enhanced with 
   * code dealing with db failover situations.
   * @author Thomas Mahler
   */
  public class PerformanceJdbcFailoverTest extends TestCase
  {
      private Logger logger = LoggerFactory.getLogger("failover");;
  
      /**
       * the number of PerformanceArticle objects to work with.
       */
      static int articleCount = 10000;
  
      /**
       * the number of iterations to perform.
       */
      static int iterations = 2;
      
      /**
       * the maximum number of retries if db fails.
       */
      static int maxRetries = 5;
      
      /**
       * the maximum time to wait on db availability.
       */
      static int maxWait = 30000;
      
  
  
      /**
       * the offset value for PerformanceArticle primary keys
       */
      int offsetId = 10000;
      PersistenceBroker broker;
      private PerformanceArticle[] arr;
      private int actualRetries = 0;
  
      /**
       * BrokerTests constructor comment.
       * @param name java.lang.String
       */
      public PerformanceJdbcFailoverTest(String name)
  
      {
          super(name);
      }
  
      /**
       * launches the TestCase.
       * The number of Objects to work with and the number of iterations
       * to be performed can be adjusted by setting them as commandline parameters.
       * @param args the String[] holding the commandline parameters.
       */
      public static void main(String[] args)
      {
          if (args.length > 0)
          {
              articleCount = Integer.parseInt(args[0]);
          }
          if (args.length > 1)
          {
              iterations = Integer.parseInt(args[1]);
          }
  
          String[] arr = {PerformanceJdbcFailoverTest.class.getName()};
          junit.textui.TestRunner.main(arr);
      }
  
      /**
       * setting up the test fixture.
       */
      public void setUp() throws Exception
      {
      	
          broker = PersistenceBrokerFactory.defaultPersistenceBroker();
          clearTable();
  
          arr = new PerformanceArticle[articleCount];
          for (int i = 0; i < articleCount; i++)
          {
              PerformanceArticle a = createArticle(offsetId + i);
              arr[i] = a;
          }
      }
  
      /**
       * tearing down the test fixture.
       */
      public void tearDown()
      {
          broker.close();
      }
  
      /**
       * factory method that createa an PerformanceArticle with a given id.
       * @return the created PerformanceArticle object
       * @param id the primary key value for the new object
       */
      private PerformanceArticle createArticle(int id)
      {
          PerformanceArticle a = new PerformanceArticle();
          a.setArticleId(id);
          a.setArticleName("New Performance Article " + id);
          a.setMinimumStock(100);
          a.setOrderedUnits(17);
          a.setPrice(100.0);
          a.setProductGroupId(1);
          a.setStock(234);
          a.setSupplierId(4);
          a.setUnit("bottle");
          return a;
      }
  
      /**
       * obtain a JDBC Connection. OJB API is used to make this code portable for
       * other target dabases and different lookup methods.
       * @return the Connection to be used
       */
      private Connection getConnection() throws Exception
      {
          Connection conn = null;
          long startToWait = System.currentTimeMillis();
          System.out.print("{..");
          System.out.flush();
          while (true)
          {     	
              try
              {
                  // Use OJB API to obtain JDBC Connection. All settings are read from
                  // the repository.xml file.
                  ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
                  JdbcConnectionDescriptor jcd =
                      MetadataManager.getInstance().connectionRepository().getDescriptor(
                          TestHelper.DEF_KEY);
                  ConnectionFactory cf =
                      ConnectionFactoryFactory.getInstance().createConnectionFactory();
                  conn = cf.lookupConnection(jcd);
                  System.out.println(".} Waited for connection " + (System.currentTimeMillis()
- startToWait) + "msecs");
                  break;
              }
              catch (Throwable t)
              {
  				if ((System.currentTimeMillis() - startToWait) > maxWait)
  				{
  					System.out.print("Timeout exceeded in getConnection(), DB not available!");
  					throw new Exception(t);	
  				}
  				else
  				{
  				}
              }
          }
          return conn;
      }
  
      /**
       * deletes all PerformanceArticle created by <code>insertNewArticles</code>.
       */
      protected void deleteArticles() throws Exception
      {
          Connection conn = getConnection();
  
          // Use the OJB SqlGenerator to generate SQL Statements. All details about
          // Table and column names are read from the repository.xml file.
          ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
          String sql = broker.serviceSqlGenerator().getPreparedDeleteStatement(cld);
  
          logger.debug("delete stmt: " + sql);
  
          long start = System.currentTimeMillis();
          try
          {
              conn.setAutoCommit(false);
              PreparedStatement stmt = conn.prepareStatement(sql);
              for (int i = 0; i < articleCount; i++)
              {
                  PerformanceArticle a = arr[i];
                  stmt.setInt(1, a.articleId);
                  stmt.execute();
              }
              conn.commit();
          }
          catch (Throwable t)
          {
          	actualRetries++;
          	if (actualRetries <= maxRetries)
          	{
          		logger.error("error during db operations:",t);
          		deleteArticles();
          	}
          	else
          	{
              	logger.error(t);
              	fail(t.getMessage());
          	}
          }
          finally
          {
          	try
          	{
          		conn.close();
          	}
          	catch (Throwable ignored)
          	{
          	}	
          }
          long stop = System.currentTimeMillis();
          logger.info("deleting " + articleCount + " Objects: " + (stop - start) + " msec");
      }
  
      /**
       * create new PerformanceArticle objects and insert them into the RDBMS.
       * The number of objects to create is defined by <code>articleCount</code>.
       */
      protected void insertNewArticles() throws Exception
      {
          Connection conn = getConnection();
  
          // Use the OJB SqlGenerator to generate SQL Statements. All details about
          // Table and column names are read from the repository.xml file.
          ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
          String sql = broker.serviceSqlGenerator().getPreparedInsertStatement(cld);
  
          logger.debug("insert stmt: " + sql);
  
          long start = System.currentTimeMillis();
          try
          {
              conn.setAutoCommit(false);
              PreparedStatement stmt = conn.prepareStatement(sql);
  
              for (int i = 0; i < articleCount; i++)
              {
                  PerformanceArticle a = arr[i];
  
                  stmt.setInt(1, a.articleId);
                  stmt.setString(2, a.articleName);
                  stmt.setInt(3, a.supplierId);
                  stmt.setInt(4, a.productGroupId);
                  stmt.setString(5, a.unit);
                  stmt.setDouble(6, a.price);
                  stmt.setInt(7, a.stock);
                  stmt.setInt(8, a.orderedUnits);
                  stmt.setInt(9, a.minimumStock);
  
                  stmt.execute();
              }
              conn.commit();
          }
          catch (Throwable t)
          {
          	actualRetries++;
          	if (actualRetries <= maxRetries)
          	{
          		logger.error("error during db operations:",t);
          		insertNewArticles();
          	}
          	else
          	{
              	logger.error(t);
              	fail(t.getMessage());
          	}
          }
          finally
          {
          	try
          	{
          		conn.close();
          	}
          	catch (Throwable ignored)
          	{
          	}	
          }
          long stop = System.currentTimeMillis();
          logger.info("inserting " + articleCount + " Objects: " + (stop - start) + " msec");
  
      }
  
      protected void clearTable() throws Exception
      {
          Connection conn = getConnection();
      	try
      	{
  	        ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  	        String table = cld.getFullTableName();
  	        String sql = "DELETE FROM " + table;
  	        PreparedStatement stmt = conn.prepareStatement(sql);
  	        stmt.execute();
  	        conn.close();
      	}
          catch (Throwable t)
          {
          	actualRetries++;
          	if (actualRetries <= maxRetries)
          	{
          		logger.error("error during db operations:",t);
          		clearTable();
          	}
          	else
          	{
              	logger.error(t);
              	fail(t.getMessage());
          	}
          }
          finally
          {
          	try
          	{
          		conn.close();
          	}
          	catch (Throwable ignored)
          	{
          	}	
          }
      }
  
      /**
       * read in all the PerformanceArticles from the RDBMS that have
       * been inserted by <code>insertNewArticles()</code>.
       * The lookup is done one by one, that is: a primary key based lookup is used.
       */
      protected void readArticles() throws Exception
      {
          Connection conn = getConnection();
  
          // Use the OJB SqlGenerator to generate SQL Statements. All details about
          // Table and column names are read from the repository.xml file.
          ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
          String sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld);
          logger.debug("select stmt: " + sql);
  
          String colId = cld.getFieldDescriptorByName("articleId").getColumnName();
          String colName = cld.getFieldDescriptorByName("articleName").getColumnName();
          String colSupplier = cld.getFieldDescriptorByName("supplierId").getColumnName();
          String colGroup = cld.getFieldDescriptorByName("productGroupId").getColumnName();
          String colUnit = cld.getFieldDescriptorByName("unit").getColumnName();
          String colPrice = cld.getFieldDescriptorByName("price").getColumnName();
          String colStock = cld.getFieldDescriptorByName("stock").getColumnName();
          String colOrdered = cld.getFieldDescriptorByName("orderedUnits").getColumnName();
          String colMin = cld.getFieldDescriptorByName("minimumStock").getColumnName();
  
          long start = System.currentTimeMillis();
          try
          {
              conn.setAutoCommit(false);
              PreparedStatement stmt = conn.prepareStatement(sql);
              for (int i = 0; i < articleCount; i++)
              {
                  stmt.setInt(1, offsetId + i);
                  ResultSet rs = stmt.executeQuery();
                  rs.next();
  
                  PerformanceArticle a = new PerformanceArticle();
                  a.articleId = rs.getInt(colId);
                  a.articleName = rs.getString(colName);
                  a.supplierId = rs.getInt(colSupplier);
                  a.productGroupId = rs.getInt(colGroup);
                  a.unit = rs.getString(colUnit);
                  a.price = rs.getFloat(colPrice);
                  a.stock = rs.getInt(colStock);
                  a.orderedUnits = rs.getInt(colOrdered);
                  a.minimumStock = rs.getInt(colMin);
              }
          }
          catch (Throwable t)
          {
          	actualRetries++;
          	if (actualRetries <= maxRetries)
          	{
          		logger.error("error during db operations:",t);
          		readArticles();
          	}
          	else
          	{
              	logger.error(t);
              	fail(t.getMessage());
          	}
          }
          finally
          {
          	try
          	{
          		conn.close();
          	}
          	catch (Throwable ignored)
          	{
          	}	
          }
  
  
          long stop = System.currentTimeMillis();
          logger.info("querying " + articleCount + " Objects: " + (stop - start) + " msec");
  
      }
  
      /**
       * read in all the PerformanceArticles from the RDBMS that have
       * been inserted by <code>insertNewArticles()</code>.
       * The lookup is done with a cursor fetch,
       * that is: a between Statement is used to select all inserted PerformanceArticles
       * and Objects are read in by fetching from the cursor (JDBC ResultSet).
       */
      protected void readArticlesByCursor() throws Exception
      {
          Connection conn = getConnection();
  
          Criteria c = new Criteria();
          c.addBetween("articleId", new Integer(offsetId), new Integer(offsetId + articleCount));
          Query query = new QueryByCriteria(PerformanceArticle.class, c);
  
          // Use the OJB SqlGenerator to generate SQL Statements. All details about
          // Table and column names are read from the repository.xml file.
          ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
          String sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld);
  
          logger.debug("select stmt: " + sql);
  
          String colId = cld.getFieldDescriptorByName("articleId").getColumnName();
          String colName = cld.getFieldDescriptorByName("articleName").getColumnName();
          String colSupplier = cld.getFieldDescriptorByName("supplierId").getColumnName();
          String colGroup = cld.getFieldDescriptorByName("productGroupId").getColumnName();
          String colUnit = cld.getFieldDescriptorByName("unit").getColumnName();
          String colPrice = cld.getFieldDescriptorByName("price").getColumnName();
          String colStock = cld.getFieldDescriptorByName("stock").getColumnName();
          String colOrdered = cld.getFieldDescriptorByName("orderedUnits").getColumnName();
          String colMin = cld.getFieldDescriptorByName("minimumStock").getColumnName();
  
  
          int fetchCount = 0;
          long start = System.currentTimeMillis();
          try
          {
              conn.setAutoCommit(false);
              PreparedStatement stmt = conn.prepareStatement(sql);
              stmt.setInt(1, offsetId);
              stmt.setInt(2, offsetId + articleCount);
              ResultSet rs = stmt.executeQuery();
              while (rs.next())
              {
                  fetchCount++;
  
                  PerformanceArticle a = new PerformanceArticle();
                  a.articleId = rs.getInt(colId);
                  a.articleName = rs.getString(colName);
                  a.supplierId = rs.getInt(colSupplier);
                  a.productGroupId = rs.getInt(colGroup);
                  a.unit = rs.getString(colUnit);
                  a.price = rs.getFloat(colPrice);
                  a.stock = rs.getInt(colStock);
                  a.orderedUnits = rs.getInt(colOrdered);
                  a.minimumStock = rs.getInt(colMin);
              }
          }
          catch (Throwable t)
          {
          	actualRetries++;
          	if (actualRetries <= maxRetries)
          	{
          		logger.error("error during db operations:",t);
          		readArticlesByCursor();
          	}
          	else
          	{
              	logger.error(t);
              	fail(t.getMessage());
          	}
          }
          finally
          {
          	try
          	{
          		conn.close();
          	}
          	catch (Throwable ignored)
          	{
          	}	
          }
  
  
          long stop = System.currentTimeMillis();
          logger.info("fetching " + fetchCount + " Objects: " + (stop - start) + " msec");
  
      }
  
      /**
       * updates all PerformanceArticles inserted by <code>insertNewArticles()</code>.
       * All objects are modified and changes are written to the RDBMS with an UPDATE.
       */
      protected void updateExistingArticles() throws Exception
      {
          Connection conn = getConnection();
  
          // Use the OJB SqlGenerator to generate SQL Statements. All details about
          // Table and column names are read from the repository.xml file.
          ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
          String sql = broker.serviceSqlGenerator().getPreparedUpdateStatement(cld);
          logger.debug("update stmt: " + sql);
  
          // update all objects
          for (int i = 0; i < articleCount; i++)
          {
              arr[i].setPrice(arr[i].getPrice() * 1.95583);
          }
  
          long start = System.currentTimeMillis();
          try
          {
              conn.setAutoCommit(false);
              PreparedStatement stmt = conn.prepareStatement(sql);
              for (int i = 0; i < articleCount; i++)
              {
                  PerformanceArticle a = arr[i];
                  stmt.setString(1, a.articleName);
                  stmt.setInt(2, a.supplierId);
                  stmt.setInt(3, a.productGroupId);
                  stmt.setString(4, a.unit);
                  stmt.setDouble(5, a.price);
                  stmt.setInt(6, a.stock);
                  stmt.setInt(7, a.orderedUnits);
                  stmt.setInt(8, a.minimumStock);
                  stmt.setInt(9, a.articleId);
                  stmt.execute();
              }
              conn.commit();
          }
          catch (Throwable t)
          {
          	actualRetries++;
          	if (actualRetries <= maxRetries)
          	{
          		logger.error("error during db operations:",t);
          		updateExistingArticles();
          	}
          	else
          	{
              	logger.error(t);
              	fail(t.getMessage());
          	}
          }
          finally
          {
          	try
          	{
          		conn.close();
          	}
          	catch (Throwable ignored)
          	{
          	}	
          }
          long stop = System.currentTimeMillis();
          logger.info("updating " + articleCount + " Objects: " + (stop - start) + " msec");
  
      }
  
      /**
       * this method is the driver for the complete Benchmark.
       * It performs the following steps:
       *
       * 1.) n objects are created and inserted to the RDBMS.
       * 2.) the created objects are modified. Modifications are written to the RDBMS with
updates.
       * 3.) All objects created in 1.) are read in by primary key based SELECT statements.
       * 4.) Step 3.) is repeated to test caching facilities.
       * 5.) All objects created in 1.) are read by iterating over a ResultSet.
       * 6.) All objects created in 1.) are deleted with n separate DELETE Statements.
       */
      public void testBenchmark()
      {
          try
          {
              logger.info("Test for native JDBC");
              for (int i = 0; i < iterations; i++)
              {
                  logger.info("");
  
                  // store all Article objects
                  insertNewArticles();
  
                  // update all objects
                  updateExistingArticles();
  
                  // querying
                  readArticles();
  
                  readArticles();
  
                  // fetching objects
                  readArticlesByCursor();
  
                  // delete all objects
                  deleteArticles();
              }
          }
          catch (Throwable t)
          {
              logger.error(t);
              fail(t.getMessage());
          }
      }
  
  }
  
  
  

Mime
View raw message