KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > PerformanceJdbcFailoverTest


1 package org.apache.ojb.broker;
2
3 import junit.framework.TestCase;
4 import org.apache.ojb.broker.accesslayer.ConnectionFactory;
5 import org.apache.ojb.broker.accesslayer.ConnectionFactoryFactory;
6 import org.apache.ojb.broker.metadata.ClassDescriptor;
7 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
8 import org.apache.ojb.broker.metadata.MetadataManager;
9 import org.apache.ojb.broker.query.Criteria;
10 import org.apache.ojb.broker.query.Query;
11 import org.apache.ojb.broker.query.QueryByCriteria;
12 import org.apache.ojb.broker.util.logging.Logger;
13 import org.apache.ojb.broker.util.logging.LoggerFactory;
14
15 import java.sql.Connection JavaDoc;
16 import java.sql.PreparedStatement JavaDoc;
17 import java.sql.ResultSet JavaDoc;
18
19 /**
20  * This TestCase contains the OJB performance benchmarks for the
21  * JDBC API. The original testcases have been enhanced with
22  * code dealing with db failover situations.
23  * @author Thomas Mahler
24  */

25 public class PerformanceJdbcFailoverTest extends TestCase
26 {
27     private Logger logger = LoggerFactory.getLogger("failover");;
28
29     /**
30      * the number of PerformanceArticle objects to work with.
31      */

32     static int articleCount = 10000;
33
34     /**
35      * the number of iterations to perform.
36      */

37     static int iterations = 2;
38
39     /**
40      * the maximum number of retries if db fails.
41      */

42     static int maxRetries = 5;
43
44     /**
45      * the maximum time to wait on db availability.
46      */

47     static int maxWait = 30;
48
49
50     /**
51      * the offset value for PerformanceArticle primary keys
52      */

53     int offsetId = 10000;
54     PersistenceBroker broker;
55     private PerformanceArticle[] arr;
56     private int actualRetries = 0;
57
58     /**
59      * BrokerTests constructor comment.
60      * @param name java.lang.String
61      */

62     public PerformanceJdbcFailoverTest(String JavaDoc name)
63
64     {
65         super(name);
66     }
67
68     /**
69      * launches the TestCase.
70      * The number of Objects to work with and the number of iterations
71      * to be performed can be adjusted by setting them as commandline parameters.
72      * @param args the String[] holding the commandline parameters.
73      */

74     public static void main(String JavaDoc[] args)
75     {
76         if (args.length > 0)
77         {
78             articleCount = Integer.parseInt(args[0]);
79         }
80         if (args.length > 1)
81         {
82             iterations = Integer.parseInt(args[1]);
83         }
84         if (args.length > 2)
85         {
86             maxRetries = Integer.parseInt(args[2]);
87         }
88         if (args.length > 3)
89         {
90             maxWait = Integer.parseInt(args[3]);
91         }
92
93
94         String JavaDoc[] arr = {PerformanceJdbcFailoverTest.class.getName()};
95         junit.textui.TestRunner.main(arr);
96     }
97
98     /**
99      * setting up the test fixture.
100      */

101     public void setUp() throws Exception JavaDoc
102     {
103
104         broker = PersistenceBrokerFactory.defaultPersistenceBroker();
105         clearTable();
106
107         arr = new PerformanceArticle[articleCount];
108         for (int i = 0; i < articleCount; i++)
109         {
110             PerformanceArticle a = createArticle(offsetId + i);
111             arr[i] = a;
112         }
113     }
114
115     /**
116      * tearing down the test fixture.
117      */

118     public void tearDown()
119     {
120         broker.close();
121     }
122
123     /**
124      * factory method that createa an PerformanceArticle with a given id.
125      * @return the created PerformanceArticle object
126      * @param id the primary key value for the new object
127      */

128     private PerformanceArticle createArticle(int id)
129     {
130         PerformanceArticle a = new PerformanceArticle();
131         a.setArticleId(id);
132         a.setArticleName("New Performance Article " + id);
133         a.setMinimumStock(100);
134         a.setOrderedUnits(17);
135         a.setPrice(100.0);
136         a.setProductGroupId(1);
137         a.setStock(234);
138         a.setSupplierId(4);
139         a.setUnit("bottle");
140         return a;
141     }
142
143     /**
144      * obtain a JDBC Connection. OJB API is used to make this code portable for
145      * other target dabases and different lookup methods.
146      * @return the Connection to be used
147      */

148     private Connection JavaDoc getConnection() throws Exception JavaDoc
149     {
150         Connection JavaDoc conn = null;
151         long startToWait = System.currentTimeMillis();
152         System.out.print("[");
153         System.out.flush();
154         while (true)
155         {
156             try
157             {
158                 // Use OJB API to obtain JDBC Connection. All settings are read from
159
// the repository.xml file.
160
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
161                 JdbcConnectionDescriptor jcd =
162                         MetadataManager.getInstance().connectionRepository().getDescriptor(
163                                 TestHelper.DEF_KEY);
164                 ConnectionFactory cf =
165                         ConnectionFactoryFactory.getInstance().createConnectionFactory();
166                 conn = cf.lookupConnection(jcd);
167                 System.out.println("] Waited for connection " + (System.currentTimeMillis() - startToWait) + "msecs");
168                 break;
169             }
170             catch (Throwable JavaDoc t)
171             {
172                 long now = System.currentTimeMillis();
173                 if ((now - startToWait) > (1000* maxWait))
174                 {
175                     System.out.print("Timeout exceeded in getConnection(), DB not available!");
176                     throw new OJBException(t);
177                 }
178                 else
179                 {
180                     if ((now % 1000) == 0)
181                     {
182                         System.out.print("#");
183                         System.out.flush();
184                     }
185                     
186                 }
187             }
188         }
189         return conn;
190     }
191
192     /**
193      * deletes all PerformanceArticle created by <code>insertNewArticles</code>.
194      */

195     protected void deleteArticles() throws Exception JavaDoc
196     {
197         Connection JavaDoc conn = getConnection();
198
199         // Use the OJB SqlGenerator to generate SQL Statements. All details about
200
// Table and column names are read from the repository.xml file.
201
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
202         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedDeleteStatement(cld);
203
204         logger.debug("delete stmt: " + sql);
205
206         long start = System.currentTimeMillis();
207         try
208         {
209             conn.setAutoCommit(false);
210             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
211             for (int i = 0; i < articleCount; i++)
212             {
213                 PerformanceArticle a = arr[i];
214                 stmt.setInt(1, a.articleId);
215                 stmt.execute();
216             }
217             conn.commit();
218         }
219         catch (Throwable JavaDoc t)
220         {
221             actualRetries++;
222             if (actualRetries <= maxRetries)
223             {
224                 logger.error("error during db operations:", t);
225                 try
226                 {
227                     conn.close();
228                 }
229                 catch (Throwable JavaDoc ignored)
230                 {
231                 }
232                 deleteArticles();
233             }
234             else
235             {
236                 logger.error("retry count exceeded!");
237                 fail(t.getMessage());
238             }
239         }
240         finally
241         {
242             try
243             {
244                 conn.close();
245             }
246             catch (Throwable JavaDoc ignored)
247             {
248             }
249         }
250         long stop = System.currentTimeMillis();
251         logger.info("deleting " + articleCount + " Objects: " + (stop - start) + " msec");
252     }
253
254     /**
255      * create new PerformanceArticle objects and insert them into the RDBMS.
256      * The number of objects to create is defined by <code>articleCount</code>.
257      */

258     protected void insertNewArticles() throws Exception JavaDoc
259     {
260         Connection JavaDoc conn = getConnection();
261
262         // Use the OJB SqlGenerator to generate SQL Statements. All details about
263
// Table and column names are read from the repository.xml file.
264
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
265         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedInsertStatement(cld);
266
267         logger.debug("insert stmt: " + sql);
268
269         long start = System.currentTimeMillis();
270         try
271         {
272             conn.setAutoCommit(false);
273             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
274
275             for (int i = 0; i < articleCount; i++)
276             {
277                 PerformanceArticle a = arr[i];
278
279                 stmt.setInt(1, a.articleId);
280                 stmt.setString(2, a.articleName);
281                 stmt.setInt(3, a.supplierId);
282                 stmt.setInt(4, a.productGroupId);
283                 stmt.setString(5, a.unit);
284                 stmt.setDouble(6, a.price);
285                 stmt.setInt(7, a.stock);
286                 stmt.setInt(8, a.orderedUnits);
287                 stmt.setInt(9, a.minimumStock);
288
289                 stmt.execute();
290             }
291             conn.commit();
292         }
293         catch (Throwable JavaDoc t)
294         {
295             actualRetries++;
296             if (actualRetries <= maxRetries)
297             {
298                 logger.error("error during db operations:", t);
299                 try
300                 {
301                     conn.close();
302                 }
303                 catch (Throwable JavaDoc ignored)
304                 {
305                 }
306                 insertNewArticles();
307             }
308             else
309             {
310                 logger.error("retry count exceeded!");
311                 fail(t.getMessage());
312             }
313         }
314         finally
315         {
316             try
317             {
318                 conn.close();
319             }
320             catch (Throwable JavaDoc ignored)
321             {
322             }
323         }
324         long stop = System.currentTimeMillis();
325         logger.info("inserting " + articleCount + " Objects: " + (stop - start) + " msec");
326
327     }
328
329     protected void clearTable() throws Exception JavaDoc
330     {
331         Connection JavaDoc conn = getConnection();
332         try
333         {
334             ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
335             String JavaDoc table = cld.getFullTableName();
336             String JavaDoc sql = "DELETE FROM " + table;
337             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
338             stmt.execute();
339             conn.close();
340         }
341         catch (Throwable JavaDoc t)
342         {
343             actualRetries++;
344             if (actualRetries <= maxRetries)
345             {
346                 logger.error("error during db operations:", t);
347                 try
348                 {
349                     conn.close();
350                 }
351                 catch (Throwable JavaDoc ignored)
352                 {
353                 }
354                 clearTable();
355             }
356             else
357             {
358                 logger.error("retry count exceeded!");
359                 fail(t.getMessage());
360             }
361         }
362         finally
363         {
364             try
365             {
366                 conn.close();
367             }
368             catch (Throwable JavaDoc ignored)
369             {
370             }
371         }
372     }
373
374     /**
375      * read in all the PerformanceArticles from the RDBMS that have
376      * been inserted by <code>insertNewArticles()</code>.
377      * The lookup is done one by one, that is: a primary key based lookup is used.
378      */

379     protected void readArticles() throws Exception JavaDoc
380     {
381         Connection JavaDoc conn = getConnection();
382
383         // Use the OJB SqlGenerator to generate SQL Statements. All details about
384
// Table and column names are read from the repository.xml file.
385
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
386         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld);
387         logger.debug("select stmt: " + sql);
388
389         String JavaDoc colId = cld.getFieldDescriptorByName("articleId").getColumnName();
390         String JavaDoc colName = cld.getFieldDescriptorByName("articleName").getColumnName();
391         String JavaDoc colSupplier = cld.getFieldDescriptorByName("supplierId").getColumnName();
392         String JavaDoc colGroup = cld.getFieldDescriptorByName("productGroupId").getColumnName();
393         String JavaDoc colUnit = cld.getFieldDescriptorByName("unit").getColumnName();
394         String JavaDoc colPrice = cld.getFieldDescriptorByName("price").getColumnName();
395         String JavaDoc colStock = cld.getFieldDescriptorByName("stock").getColumnName();
396         String JavaDoc colOrdered = cld.getFieldDescriptorByName("orderedUnits").getColumnName();
397         String JavaDoc colMin = cld.getFieldDescriptorByName("minimumStock").getColumnName();
398
399         long start = System.currentTimeMillis();
400         try
401         {
402             conn.setAutoCommit(false);
403             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
404             for (int i = 0; i < articleCount; i++)
405             {
406                 stmt.setInt(1, offsetId + i);
407                 ResultSet JavaDoc rs = stmt.executeQuery();
408                 rs.next();
409
410                 PerformanceArticle a = new PerformanceArticle();
411                 a.articleId = rs.getInt(colId);
412                 a.articleName = rs.getString(colName);
413                 a.supplierId = rs.getInt(colSupplier);
414                 a.productGroupId = rs.getInt(colGroup);
415                 a.unit = rs.getString(colUnit);
416                 a.price = rs.getFloat(colPrice);
417                 a.stock = rs.getInt(colStock);
418                 a.orderedUnits = rs.getInt(colOrdered);
419                 a.minimumStock = rs.getInt(colMin);
420             }
421         }
422         catch (Throwable JavaDoc t)
423         {
424             actualRetries++;
425             if (actualRetries <= maxRetries)
426             {
427                 logger.error("error during db operations:", t);
428                 try
429                 {
430                     conn.close();
431                 }
432                 catch (Throwable JavaDoc ignored)
433                 {
434                 }
435                 readArticles();
436             }
437             else
438             {
439                 logger.error("retry count exceeded!");
440                 fail(t.getMessage());
441             }
442         }
443         finally
444         {
445             try
446             {
447                 conn.close();
448             }
449             catch (Throwable JavaDoc ignored)
450             {
451             }
452         }
453
454
455         long stop = System.currentTimeMillis();
456         logger.info("querying " + articleCount + " Objects: " + (stop - start) + " msec");
457
458     }
459
460     /**
461      * read in all the PerformanceArticles from the RDBMS that have
462      * been inserted by <code>insertNewArticles()</code>.
463      * The lookup is done with a cursor fetch,
464      * that is: a between Statement is used to select all inserted PerformanceArticles
465      * and Objects are read in by fetching from the cursor (JDBC ResultSet).
466      */

467     protected void readArticlesByCursor() throws Exception JavaDoc
468     {
469         Connection JavaDoc conn = getConnection();
470
471         Criteria c = new Criteria();
472         c.addBetween("articleId", new Integer JavaDoc(offsetId), new Integer JavaDoc(offsetId + articleCount));
473         Query query = new QueryByCriteria(PerformanceArticle.class, c);
474
475         // Use the OJB SqlGenerator to generate SQL Statements. All details about
476
// Table and column names are read from the repository.xml file.
477
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
478         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld);
479
480         logger.debug("select stmt: " + sql);
481
482         String JavaDoc colId = cld.getFieldDescriptorByName("articleId").getColumnName();
483         String JavaDoc colName = cld.getFieldDescriptorByName("articleName").getColumnName();
484         String JavaDoc colSupplier = cld.getFieldDescriptorByName("supplierId").getColumnName();
485         String JavaDoc colGroup = cld.getFieldDescriptorByName("productGroupId").getColumnName();
486         String JavaDoc colUnit = cld.getFieldDescriptorByName("unit").getColumnName();
487         String JavaDoc colPrice = cld.getFieldDescriptorByName("price").getColumnName();
488         String JavaDoc colStock = cld.getFieldDescriptorByName("stock").getColumnName();
489         String JavaDoc colOrdered = cld.getFieldDescriptorByName("orderedUnits").getColumnName();
490         String JavaDoc colMin = cld.getFieldDescriptorByName("minimumStock").getColumnName();
491
492
493         int fetchCount = 0;
494         long start = System.currentTimeMillis();
495         try
496         {
497             conn.setAutoCommit(false);
498             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
499             stmt.setInt(1, offsetId);
500             stmt.setInt(2, offsetId + articleCount);
501             ResultSet JavaDoc rs = stmt.executeQuery();
502             while (rs.next())
503             {
504                 fetchCount++;
505
506                 PerformanceArticle a = new PerformanceArticle();
507                 a.articleId = rs.getInt(colId);
508                 a.articleName = rs.getString(colName);
509                 a.supplierId = rs.getInt(colSupplier);
510                 a.productGroupId = rs.getInt(colGroup);
511                 a.unit = rs.getString(colUnit);
512                 a.price = rs.getFloat(colPrice);
513                 a.stock = rs.getInt(colStock);
514                 a.orderedUnits = rs.getInt(colOrdered);
515                 a.minimumStock = rs.getInt(colMin);
516             }
517         }
518         catch (Throwable JavaDoc t)
519         {
520             actualRetries++;
521             if (actualRetries <= maxRetries)
522             {
523                 logger.error("error during db operations:", t);
524                 try
525                 {
526                     conn.close();
527                 }
528                 catch (Throwable JavaDoc ignored)
529                 {
530                 }
531                 readArticlesByCursor();
532             }
533             else
534             {
535                 logger.error("retry count exceeded!");
536                 fail(t.getMessage());
537             }
538         }
539         finally
540         {
541             try
542             {
543                 conn.close();
544             }
545             catch (Throwable JavaDoc ignored)
546             {
547             }
548         }
549
550
551         long stop = System.currentTimeMillis();
552         logger.info("fetching " + fetchCount + " Objects: " + (stop - start) + " msec");
553
554     }
555
556     /**
557      * updates all PerformanceArticles inserted by <code>insertNewArticles()</code>.
558      * All objects are modified and changes are written to the RDBMS with an UPDATE.
559      */

560     protected void updateExistingArticles() throws Exception JavaDoc
561     {
562         Connection JavaDoc conn = getConnection();
563
564         // Use the OJB SqlGenerator to generate SQL Statements. All details about
565
// Table and column names are read from the repository.xml file.
566
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
567         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedUpdateStatement(cld);
568         logger.debug("update stmt: " + sql);
569
570         // update all objects
571
for (int i = 0; i < articleCount; i++)
572         {
573             arr[i].setPrice(arr[i].getPrice() * 1.95583);
574         }
575
576         long start = System.currentTimeMillis();
577         try
578         {
579             conn.setAutoCommit(false);
580             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
581             for (int i = 0; i < articleCount; i++)
582             {
583                 PerformanceArticle a = arr[i];
584                 stmt.setString(1, a.articleName);
585                 stmt.setInt(2, a.supplierId);
586                 stmt.setInt(3, a.productGroupId);
587                 stmt.setString(4, a.unit);
588                 stmt.setDouble(5, a.price);
589                 stmt.setInt(6, a.stock);
590                 stmt.setInt(7, a.orderedUnits);
591                 stmt.setInt(8, a.minimumStock);
592                 stmt.setInt(9, a.articleId);
593                 stmt.execute();
594             }
595             conn.commit();
596         }
597         catch (Throwable JavaDoc t)
598         {
599             actualRetries++;
600             if (actualRetries <= maxRetries)
601             {
602                 logger.error("error during db operations:", t);
603                 try
604                 {
605                     conn.close();
606                 }
607                 catch (Throwable JavaDoc ignored)
608                 {
609                 }
610                 updateExistingArticles();
611             }
612             else
613             {
614                 logger.error("retry count exceeded!");
615                 fail(t.getMessage());
616             }
617         }
618         finally
619         {
620             try
621             {
622                 conn.close();
623             }
624             catch (Throwable JavaDoc ignored)
625             {
626             }
627         }
628         long stop = System.currentTimeMillis();
629         logger.info("updating " + articleCount + " Objects: " + (stop - start) + " msec");
630
631     }
632
633     /**
634      * this method is the driver for the complete Benchmark.
635      * It performs the following steps:
636      *
637      * 1.) n objects are created and inserted to the RDBMS.
638      * 2.) the created objects are modified. Modifications are written to the RDBMS with updates.
639      * 3.) All objects created in 1.) are read in by primary key based SELECT statements.
640      * 4.) Step 3.) is repeated to test caching facilities.
641      * 5.) All objects created in 1.) are read by iterating over a ResultSet.
642      * 6.) All objects created in 1.) are deleted with n separate DELETE Statements.
643      */

644     public void testBenchmark()
645     {
646         try
647         {
648             logger.info("Test for native JDBC");
649             for (int i = 0; i < iterations; i++)
650             {
651                 logger.info("");
652
653                 // store all Article objects
654
insertNewArticles();
655
656                 // update all objects
657
updateExistingArticles();
658
659                 // querying
660
readArticles();
661
662                 readArticles();
663
664                 // fetching objects
665
readArticlesByCursor();
666
667                 // delete all objects
668
deleteArticles();
669             }
670         }
671         catch (Throwable JavaDoc t)
672         {
673             logger.error(t);
674             fail(t.getMessage());
675         }
676     }
677
678 }
679
Popular Tags