| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license |
| * agreements. See the NOTICE file distributed with this work for additional information regarding |
| * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. You may obtain a |
| * copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License |
| * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
| * or implied. See the License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| /* |
| * CacheJUnitTest.java JUnit based test |
| * |
| * Created on March 28, 2005, 10:59 AM |
| */ |
| package org.apache.geode.internal.jta.functional; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.sql.Connection; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.sql.Statement; |
| |
| import javax.naming.Context; |
| import javax.naming.NamingException; |
| import javax.sql.DataSource; |
| import javax.transaction.UserTransaction; |
| |
| import org.apache.logging.log4j.Logger; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import org.apache.geode.cache.AttributesFactory; |
| import org.apache.geode.cache.Cache; |
| import org.apache.geode.cache.CacheException; |
| import org.apache.geode.cache.CacheExistsException; |
| import org.apache.geode.cache.CacheFactory; |
| import org.apache.geode.cache.CacheLoader; |
| import org.apache.geode.cache.CacheLoaderException; |
| import org.apache.geode.cache.LoaderHelper; |
| import org.apache.geode.cache.Region; |
| import org.apache.geode.distributed.internal.InternalDistributedSystem; |
| import org.apache.geode.internal.jta.CacheUtils; |
| import org.apache.geode.internal.jta.JTAUtils; |
| import org.apache.geode.logging.internal.log4j.api.LogService; |
| |
| /** |
| * This JUnit version is created from class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests functional behavior. Assumes that CacheUtils.java always creates table(s) and inserts data |
| * in the form: 1 => name1, 2 => name2, 3 => name3...as the values of ID and name fields |
| * respectively. Test # 15 & 16 has the dependency to run on CloudScape database only due to |
| * variations in DDL. |
| * |
| */ |
| public class CacheJUnitTest { |
| |
| private static final Logger logger = LogService.getLogger(); |
| |
| private Region currRegion; |
| private Cache cache; |
| private int tblIDFld; |
| private String tblNameFld; |
| private String tblName; |
| |
| @Before |
| public void setUp() throws Exception { |
| this.tblName = CacheUtils.init("CacheJUnitTest"); |
| assertFalse(this.tblName == null || this.tblName.equals("")); |
| |
| this.cache = CacheUtils.getCache(); |
| assertNotNull(this.cache); |
| |
| this.currRegion = this.cache.getRegion("root"); |
| assertTrue(this.currRegion.getFullPath().equals("/root")); |
| } |
| |
| @After |
| public void tearDown() throws java.lang.Exception { |
| try { |
| CacheUtils.closeCache(); |
| CacheUtils.destroyTable(this.tblName); |
| } finally { |
| InternalDistributedSystem ids = InternalDistributedSystem.getAnyInstance(); |
| if (ids != null) { |
| ids.disconnect(); |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario1 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests a simple User Transaction with Cache lookup. |
| */ |
| @Test |
| public void testScenario1() throws Exception { |
| this.tblIDFld = 1; |
| this.tblNameFld = "test1"; |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn = null; |
| |
| try { |
| ta.begin(); |
| |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| |
| conn = da.getConnection(); |
| |
| Statement stmt = conn.createStatement(); |
| |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| stmt.close(); |
| ta.commit(); |
| conn.close(); |
| } catch (NamingException e) { |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } catch (SQLException e) { |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } catch (Exception e) { |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (SQLException ex) { |
| fail("SQL exception: " + ex.getMessage()); |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario2 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests a simple User Transaction with Cache lookup but closing the Connection object before |
| * committing the Transaction. |
| */ |
| @Test |
| public void testScenario2() throws Exception { |
| this.tblIDFld = 2; |
| this.tblNameFld = "test2"; |
| boolean rollback_chances = true; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| System.out.print(" looking up UserTransaction... "); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn = null; |
| |
| try { |
| ta.begin(); |
| |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| |
| conn = da.getConnection(); |
| |
| Statement stmt = conn.createStatement(); |
| |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| stmt.close(); |
| conn.close(); |
| ta.commit(); |
| |
| rollback_chances = false; |
| |
| int ifAnyRows = jtaObj.getRows(this.tblName); |
| if (ifAnyRows == 0) { |
| // no rows are there !!! failure :) |
| fail(" no rows retrieved even after txn commit after conn close."); |
| } |
| |
| } catch (NamingException e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } catch (SQLException e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } catch (Exception e) { |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (SQLException e) { |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario3 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests whether a user transaction with cache lookup and with XAPooledDataSOurce supports Cache |
| * put and get operations accordingly. Put and get are done within the transaction block and also |
| * db updates are done. After committing we check whether commit is proper in db and also in |
| * Cache. |
| */ |
| @Test |
| public void testScenario3() throws Exception { |
| this.tblIDFld = 3; |
| this.tblNameFld = "test3"; |
| boolean rollback_chances = true; |
| final String DEFAULT_RGN = "root"; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn = null; |
| |
| try { |
| /** begin the transaction **/ |
| ta.begin(); |
| |
| String current_region = jtaObj.currRegion.getName(); |
| assertEquals("the default region is not root", DEFAULT_RGN, current_region); |
| |
| jtaObj.getRegionFromCache("region1"); |
| |
| String current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retrieving current region fullpath", "/" + DEFAULT_RGN + "/region1", |
| current_fullpath); |
| |
| jtaObj.put("key1", "value1"); |
| |
| String str = jtaObj.get("key1"); |
| String tok = jtaObj.parseGetValue(str); |
| assertEquals("get failed for corresponding put", "\"value1\"", tok); |
| |
| current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retrieving current region fullpath", "/" + DEFAULT_RGN + "/region1", |
| current_fullpath); |
| |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| |
| conn = da.getConnection(); |
| |
| Statement stmt = conn.createStatement(); |
| |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| stmt.close(); |
| ta.commit(); |
| conn.close(); |
| |
| rollback_chances = false; |
| |
| current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retrieving current region fullpath after txn commit", |
| "/" + DEFAULT_RGN + "/region1", current_fullpath); |
| |
| int ifAnyRows = jtaObj.getRows(this.tblName); |
| assertEquals("rows retrieved is:" + ifAnyRows, 1, ifAnyRows); |
| /* |
| * if (ifAnyRows == 0) { fail (" DB FAILURE: no rows retrieved even after txn commit."); } |
| */ |
| // after jdbc commit cache value in region1 for key1 must retain... |
| str = jtaObj.get("key1"); |
| tok = jtaObj.parseGetValue(str); |
| assertEquals("cache put didn't commit, value retrieved is: " + tok, "\"value1\"", tok); |
| } catch (CacheExistsException e) { |
| ta.rollback(); |
| fail(" test 3 failed "); |
| } catch (NamingException e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" test 3 failed " + e.getMessage()); |
| } catch (SQLException e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" test 3 failed " + e.getMessage()); |
| } catch (Exception e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" test 3 failed " + e.getMessage()); |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (SQLException e) { |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario4 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests whether a user transaction with cache lookup and with XAPooledDataSOurce supports Cache |
| * put and get operations accordingly along with JTA behavior. Put and get are done within the |
| * transaction block and also db updates are done. After rollback the transaction explicitly we |
| * check whether it was proper in db and also in Cache, which should also rollback. |
| */ |
| @Test |
| public void testScenario4() throws Exception { |
| this.tblIDFld = 4; |
| this.tblNameFld = "test4"; |
| boolean rollback_chances = true; |
| final String DEFAULT_RGN = "root"; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn = null; |
| |
| try { |
| String current_region = jtaObj.currRegion.getName(); |
| assertEquals("default region is not root", DEFAULT_RGN, current_region); |
| |
| jtaObj.getRegionFromCache("region1"); |
| String current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals( |
| "failed retrieving current region fullpath after doing getRegionFromCache(region1)", |
| "/" + DEFAULT_RGN + "/region1", current_fullpath); |
| |
| jtaObj.put("key1", "test"); |
| ta.begin(); |
| |
| jtaObj.put("key1", "value1"); |
| String str = jtaObj.get("key1"); |
| String tok = jtaObj.parseGetValue(str); |
| assertEquals("get value do not match with the put", "\"value1\"", tok); |
| |
| current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retrieving current region fullpath", "/" + DEFAULT_RGN + "/region1", |
| current_fullpath); |
| |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| |
| conn = da.getConnection(); |
| Statement stmt = conn.createStatement(); |
| |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| stmt.close(); |
| ta.rollback(); |
| conn.close(); |
| |
| rollback_chances = false; |
| |
| current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retirieving current region fullpath after txn rollback", |
| "/" + DEFAULT_RGN + "/region1", current_fullpath); |
| |
| int ifAnyRows = jtaObj.getRows(this.tblName); |
| assertEquals("rows retrieved is: " + ifAnyRows, 0, ifAnyRows); |
| /* |
| * if (ifAnyRows != 0) { fail (" DB FAILURE"); } |
| */ |
| str = jtaObj.get("key1"); |
| tok = jtaObj.parseGetValue(str); |
| assertEquals("value existing in cache is: " + tok, "\"test\"", tok); |
| } catch (CacheExistsException e) { |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } catch (NamingException e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } catch (SQLException e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } catch (Exception e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" failed " + e.getMessage()); |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (SQLException e) { |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario5 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests whether a user transaction with cache lookup and with XAPooledDataSOurce supports Cache |
| * put and get operations accordingly along with JTA behavior. Put and get are done within the |
| * transaction block and also db updates are done. We try to rollback the transaction by violating |
| * primary key constraint in db table, nad then we check whether rollback was proper in db and |
| * also in Cache, which should also rollback. |
| */ |
| @Test |
| public void testScenario5() throws Exception { |
| this.tblIDFld = 5; |
| this.tblNameFld = "test5"; |
| boolean rollback_chances = false; |
| final String DEFAULT_RGN = "root"; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn = null; |
| |
| try { |
| String current_region = jtaObj.currRegion.getName(); |
| assertEquals("default region is not root", DEFAULT_RGN, current_region); |
| |
| // trying to create a region 'region1' under /root, if it doesn't exist. |
| // And point to the new region... |
| jtaObj.getRegionFromCache("region1"); |
| |
| // now current region should point to region1, as done from within |
| // getRegionFromCache method... |
| String current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retirieving current fullpath", "/" + DEFAULT_RGN + "/region1", |
| current_fullpath); |
| |
| jtaObj.put("key1", "test"); |
| ta.begin(); |
| |
| jtaObj.put("key1", "value1"); |
| |
| String str = jtaObj.get("key1"); |
| String tok = jtaObj.parseGetValue(str); |
| assertEquals("get value mismatch with put", "\"value1\"", tok); |
| |
| current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retrieving current fullpath, current fullpath: " + current_fullpath, |
| "/" + DEFAULT_RGN + "/region1", current_fullpath); |
| |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| |
| conn = da.getConnection(); |
| Statement stmt = conn.createStatement(); |
| |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| rollback_chances = true; |
| |
| // capable of throwing SQLException during insert operation |
| sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| stmt.close(); |
| ta.commit(); |
| conn.close(); |
| } catch (CacheExistsException e) { |
| ta.rollback(); |
| fail("test failed " + e.getMessage()); |
| } catch (NamingException e) { |
| ta.rollback(); |
| fail("test failed " + e.getMessage()); |
| } catch (SQLException e) { |
| // exception thrown during inserts are handeled as below by rollback |
| if (rollback_chances) { |
| try { |
| ta.rollback(); |
| } catch (Exception ex) { |
| fail("failed: " + ex.getMessage()); |
| } |
| |
| // intended error is checked w.r.t database first |
| int ifAnyRows = 0; |
| try { |
| ifAnyRows = jtaObj.getRows(this.tblName); |
| } catch (Exception ex) { |
| fail(" failed: " + ex.getMessage()); |
| } |
| assertEquals("rows found after rollback is: " + ifAnyRows, 0, ifAnyRows); |
| /* |
| * if (ifAnyRows != 0) { fail (" DB FAILURE"); } |
| */ |
| // intended error is checked w.r.t. cache second |
| String current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals( |
| "failed retrieving current fullpath after rollback, fullpath is: " + current_fullpath, |
| "/" + DEFAULT_RGN + "/region1", current_fullpath); |
| |
| // after jdbc rollback, cache value in region1 for key1 must vanish... |
| String str1 = null; |
| try { |
| str1 = jtaObj.get("key1"); |
| } catch (CacheException ex) { |
| fail("failed getting value for 'key1': " + ex.getMessage()); |
| } |
| |
| String tok1 = jtaObj.parseGetValue(str1); |
| assertEquals("value found in cache: " + tok1 + ", after rollback", "\"test\"", tok1); |
| } else { |
| fail(" failed: " + e.getMessage()); |
| ta.rollback(); |
| } |
| } catch (Exception e) { |
| ta.rollback(); |
| fail(" failed: " + e.getMessage()); |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (SQLException ex) { |
| fail("Exception: " + ex.getMessage()); |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario7 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests a user transaction with cache lookup and with XAPooledDataSource lookup. It does get and |
| * put operations on the cache within the transaction block and checks whether these operations |
| * are committed once the transaction is committed. |
| */ |
| @Test |
| public void testScenario7() throws Exception { |
| this.tblIDFld = 7; |
| this.tblNameFld = "test7"; |
| boolean rollback_chances = true; |
| final String DEFAULT_RGN = "root"; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn = null; |
| |
| try { |
| ta.begin(); |
| |
| String current_region = jtaObj.currRegion.getName(); |
| assertEquals("default region is not root", DEFAULT_RGN, current_region); |
| |
| jtaObj.getRegionFromCache("region1"); |
| |
| // now current region should point to region1, as done from within |
| // getRegionFromCache method... |
| String current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retrieving the current region fullpath", "/" + DEFAULT_RGN + "/region1", |
| current_fullpath); |
| |
| jtaObj.put("key1", "value1"); |
| |
| // try to get value1 from key1 in the same region |
| String str = jtaObj.get("key1"); |
| String tok = jtaObj.parseGetValue(str); |
| assertEquals("get value mismatch with put", "\"value1\"", tok); |
| |
| current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retrieving current region fullpath", "/" + DEFAULT_RGN + "/region1", |
| current_fullpath); |
| |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| |
| conn = da.getConnection(); |
| ta.commit(); |
| conn.close(); |
| |
| rollback_chances = false; |
| |
| current_fullpath = jtaObj.currRegion.getFullPath(); |
| assertEquals("failed retrieving current region fullpath after txn commit, fullpath is: " |
| + current_region, "/" + DEFAULT_RGN + "/region1", current_fullpath); |
| |
| str = jtaObj.get("key1"); |
| tok = jtaObj.parseGetValue(str); |
| assertEquals("cache value found is: " + tok, "\"value1\"", tok); |
| |
| } catch (CacheExistsException e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" failed due to: " + e.getMessage()); |
| } catch (NamingException e) { |
| ta.rollback(); |
| fail(" failed due to: " + e.getMessage()); |
| } catch (SQLException e) { |
| ta.rollback(); |
| fail(" failed due to: " + e.getMessage()); |
| } catch (Exception e) { |
| if (rollback_chances) |
| ta.rollback(); |
| fail(" failed due to: " + e.getMessage()); |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (Exception e) { |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario9 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests a user transaction with cache lookup and with XAPooledDataSource lookup performing a db |
| * update within the transaction block and committing the transaction. Then agin we perform |
| * another db update with the same DataSource and finally close the Connection. The first update |
| * only should be committed in db and the second will not participate in transaction throwing an |
| * SQLException. |
| */ |
| @Test |
| public void testScenario9() throws Exception { |
| this.tblIDFld = 9; |
| this.tblNameFld = "test9"; |
| boolean rollback_chances = true; |
| int first_field = this.tblIDFld; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| // delete the rows inserted from CacheUtils createTable, otherwise conflict |
| // in PK's |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn = null; |
| |
| try { |
| ta.begin(); |
| |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| conn = da.getConnection(); |
| Statement stmt = conn.createStatement(); |
| |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| ta.commit(); |
| |
| rollback_chances = false; |
| |
| // intended test for failure-- capable of throwing SQLException |
| this.tblIDFld += 1; |
| sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| stmt.close(); |
| conn.close(); |
| |
| rollback_chances = true; |
| } catch (NamingException e) { |
| fail(" failed due to: " + e.getMessage()); |
| ta.rollback(); |
| } catch (SQLException e) { |
| if (!rollback_chances) { |
| int ifAnyRows = jtaObj.getRows(this.tblName); |
| assertEquals("rows found is: " + ifAnyRows, 1, ifAnyRows); |
| boolean matched = jtaObj.checkTableAgainstData(this.tblName, first_field + ""); // first |
| // field |
| // must |
| // be |
| // there. |
| assertEquals("first entry to db is not found", true, matched); |
| } else { |
| ta.rollback(); |
| fail(" failed due to: " + e.getMessage()); |
| } |
| } catch (Exception e) { |
| fail(" failed due to: " + e.getMessage()); |
| if (rollback_chances) { |
| ta.rollback(); |
| } |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (SQLException e) { |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario10 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Test a user transaction with cache lookup and with XAPooledDataSource for multiple JDBC |
| * Connections. This should not be allowed for Facets datasource. For other relational DB the |
| * behaviour will be DB specific. For Oracle DB, n connections in a tranxn can be used provided , |
| * n-1 connections are closed before opening nth connection. |
| */ |
| @Test |
| public void testScenario10() throws Exception { |
| this.tblIDFld = 10; |
| this.tblNameFld = "test10"; |
| int rows_inserted = 0; |
| int ifAnyRows = 0; |
| int field1 = this.tblIDFld, field2 = 0; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn1 = null; |
| Connection conn2 = null; |
| |
| try { |
| ta.begin(); |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| conn1 = da.getConnection(); // the first Connection |
| |
| Statement stmt = conn1.createStatement(); |
| |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| rows_inserted += 1; |
| |
| conn1.close(); |
| |
| conn2 = da.getConnection(); // the second Connection |
| stmt = conn2.createStatement(); |
| |
| this.tblIDFld += 1; |
| field2 = this.tblIDFld; |
| sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| |
| stmt.executeUpdate(sqlSTR); |
| rows_inserted += 1; |
| |
| stmt.close(); |
| conn2.close(); |
| ta.commit(); |
| |
| // if we reach here check for proper entries in db |
| ifAnyRows = jtaObj.getRows(this.tblName); |
| if (ifAnyRows == rows_inserted) { |
| boolean matched1 = jtaObj.checkTableAgainstData(this.tblName, (field1 + "")); |
| boolean matched2 = jtaObj.checkTableAgainstData(this.tblName, (field2 + "")); |
| |
| if (matched1) |
| System.out.print("(PK " + field1 + "found "); |
| else |
| System.out.print("(PK " + field1 + "not found "); |
| if (matched2) |
| System.out.print("PK " + field2 + "found)"); |
| else |
| System.out.print("PK " + field2 + "not found)"); |
| |
| if (matched1 & matched2) { |
| System.out.println("ok"); |
| } else { |
| fail(" inserted data not found in DB !... failed"); |
| } |
| } else { |
| fail(" test interrupted, rows found=" + ifAnyRows + ", rows inserted=" + rows_inserted); |
| } |
| } catch (NamingException e) { |
| ta.rollback(); |
| } catch (SQLException e) { |
| ta.rollback(); |
| } catch (Exception e) { |
| ta.rollback(); |
| } finally { |
| if (conn1 != null) |
| try { |
| conn1.close(); |
| } catch (SQLException e) { |
| } |
| |
| if (conn2 != null) |
| try { |
| conn2.close(); |
| } catch (SQLException e) { |
| } |
| } |
| |
| } |
| |
| /** |
| * Test of testScenario11 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests Simple DataSource lookup within a transaction. Things should not participate in the |
| * transaction. |
| */ |
| @Test |
| public void testScenario11() throws Exception { |
| this.tblIDFld = 11; |
| this.tblNameFld = "test11"; |
| boolean rollback_chances = false; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| Connection conn = null; |
| |
| try { |
| ta.begin(); |
| DataSource da = (DataSource) ctx.lookup("java:/SimpleDataSource"); |
| |
| conn = da.getConnection(); |
| Statement stmt = conn.createStatement(); |
| |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| rollback_chances = true; |
| |
| // try insert the same data once more and see if all info gets rolled |
| // back... |
| // capable of throwing SQLException |
| sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| |
| stmt.close(); |
| ta.commit(); |
| conn.close(); |
| } catch (NamingException e) { |
| ta.rollback(); |
| } catch (SQLException e) { |
| if (rollback_chances) { |
| try { |
| ta.rollback(); |
| } catch (Exception ex) { |
| fail("failed due to : " + ex.getMessage()); |
| } |
| |
| // try to check in the db whether any rows (the first one) are there |
| // now... |
| int ifAnyRows = jtaObj.getRows(this.tblName); |
| assertEquals("first row not found in case of Simple Datasource", 1, ifAnyRows); // one |
| // row-- |
| // the |
| // first |
| // one |
| // shud |
| // be |
| // there. |
| boolean matched = jtaObj.checkTableAgainstData(this.tblName, this.tblIDFld + ""); // checking |
| // the |
| // existence |
| // of |
| // first |
| // row |
| assertEquals("first row PK didn't matched", true, matched); |
| } else { |
| ta.rollback(); |
| } |
| |
| } catch (Exception e) { |
| fail(" failed due to: " + e.getMessage()); |
| ta.rollback(); |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (SQLException e) { |
| } |
| } |
| |
| } |
| |
| /** |
| * Test of testScenario14 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests a local Cache Loader with XADataSource lookup to get the connection. The Connection |
| * should not participate in the transaction and commit/rollback should take affect accordingly |
| * along with cache. |
| */ |
| @Test |
| public void testScenario14() throws Exception { |
| final String TABLEID = "2"; |
| // final String TABLEFLD = "name2"; |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| Context ctx = cache.getJNDIContext(); |
| UserTransaction utx = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| utx.begin(); |
| AttributesFactory fac = new AttributesFactory(currRegion.getAttributes()); |
| fac.setCacheLoader(new XACacheLoaderTxn(this.tblName)); |
| Region re = currRegion.createSubregion("employee", fac.create()); |
| String retVal = (String) re.get(TABLEID); // TABLEID correspondes to |
| // "name1". |
| if (!retVal.equals("newname")) |
| fail("Uncommitted value 'newname' not read by cacheloader name = " + retVal); |
| utx.rollback(); |
| |
| DataSource ds = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| Connection conn = ds.getConnection(); |
| Statement stm = conn.createStatement(); |
| String str = "select name from " + tblName + " where id= (2)"; |
| ResultSet rs = stm.executeQuery(str); |
| rs.next(); |
| String str1 = rs.getString(1); |
| if (!str1.equals("name2")) |
| fail("Rollback not occurred on XAConnection got in a cache loader"); |
| } |
| |
| /** |
| * Test of testScenario15 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests performing DDL operations by looking up a XAPooledDataSource and without transaction. |
| */ |
| @Test |
| public void testScenario15() throws Exception { |
| this.tblIDFld = 15; |
| this.tblNameFld = "test15"; |
| String tbl = ""; |
| boolean row_num = true; |
| int ddl_return = 1; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| // delete the rows inserted from CacheUtils createTable, otherwise conflict |
| // in PK's. Basically not needed for this test |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| // UserTransaction ta = null; |
| Connection conn = null; |
| Statement stmt = null; |
| /* |
| * try { ta = (UserTransaction)ctx.lookup("java:/UserTransaction"); |
| * |
| * } catch (NamingException e) { fail ("user txn lookup failed: " + e.getMessage ()); } |
| */ |
| |
| try { |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| conn = da.getConnection(); |
| stmt = conn.createStatement(); |
| |
| // Do some DDL stuff |
| String time = new Long(System.currentTimeMillis()).toString(); |
| tbl = "my_table" + time; |
| // String sql = "create table " + tbl + |
| // " (my_id number primary key, my_name varchar2(50))"; |
| String sql = "create table " + tbl |
| + " (my_id integer NOT NULL, my_name varchar(50), CONSTRAINT my_keyx PRIMARY KEY(my_id))"; |
| ddl_return = stmt.executeUpdate(sql); |
| |
| // check whether the table was created properly |
| sql = "select * from " + tbl; |
| ResultSet rs = null; |
| rs = stmt.executeQuery(sql); |
| row_num = rs.next(); |
| rs.close(); |
| if (ddl_return == 0 && !row_num) { |
| sql = "drop table " + tbl; |
| try { |
| stmt = conn.createStatement(); |
| stmt.executeUpdate(sql); |
| } catch (SQLException e) { |
| fail(" failed to drop, " + e.getMessage()); |
| } |
| } else |
| fail("unable to create table"); |
| |
| /** Code meant for Oracle DB **/ |
| /* |
| * tbl = tbl.toUpperCase(); sql = "select * from tab where tname like '%tbl%'"; ResultSet rs = |
| * null; rs = stmt.executeQuery(sql); rs.close(); sql = "drop table "+tbl; stmt = |
| * conn.createStatement(); stmt.execute(sql); System.out.println (this.space + "ok"); |
| */ |
| stmt.close(); |
| conn.close(); |
| |
| } catch (NamingException e) { |
| fail("failed, " + e.getMessage()); |
| } catch (SQLException e) { |
| fail("failed, " + e.getMessage()); |
| } catch (Exception e) { |
| fail("failed, " + e.getMessage()); |
| } finally { |
| if (conn != null) |
| conn.close(); |
| } |
| } |
| |
| /** |
| * Test of testScenario16 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Tests DDL operations on XAPooledDataSOurce lookup, without transaction but making auto commit |
| * false just before performing DDL queries and making it true before closing the Connection. The |
| * operations should be committed. |
| */ |
| @Test |
| public void testScenario16() throws Exception { |
| this.tblIDFld = 16; |
| this.tblNameFld = "test16"; |
| String tbl = ""; |
| int ddl_return = 1; |
| boolean row_num = true; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| Connection conn = null; |
| Statement stmt = null; |
| |
| try { |
| DataSource da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| conn = da.getConnection(); |
| conn.setAutoCommit(false); |
| stmt = conn.createStatement(); |
| |
| String time = new Long(System.currentTimeMillis()).toString(); |
| tbl = "my_table" + time; |
| // String sql = "create table " + tbl + |
| // " (my_id number primary key, my_name varchar2(50))"; |
| String sql = "create table " + tbl |
| + " (my_id integer NOT NULL, my_name varchar(50), CONSTRAINT my_key PRIMARY KEY(my_id))"; |
| ddl_return = stmt.executeUpdate(sql); |
| |
| sql = "select * from " + tbl; |
| ResultSet rs = null; |
| rs = stmt.executeQuery(sql); |
| row_num = rs.next(); |
| rs.close(); |
| if (ddl_return == 0 && !row_num) { |
| sql = "drop table " + tbl; |
| try { |
| stmt = conn.createStatement(); |
| stmt.executeUpdate(sql); |
| } catch (SQLException e) { |
| fail(" failed to drop, " + e.getMessage()); |
| } |
| } else |
| fail("table do not exists"); |
| |
| /*** Code meant for Oracle DB ***/ |
| /* |
| * tbl = tbl.toUpperCase(); sql = "select * from tab where tname like '%tbl%'"; ResultSet rs = |
| * null; rs = stmt.executeQuery(sql); rs.close(); sql = "drop table "+tbl; stmt = |
| * conn.createStatement(); stmt.executeUpdate(sql); System.out.println (this.space + "ok"); |
| */ |
| conn.setAutoCommit(true); |
| stmt.close(); |
| conn.close(); |
| } catch (NamingException e) { |
| fail("failed, " + e.getMessage()); |
| } catch (SQLException e) { |
| fail("failed, " + e.getMessage()); |
| } catch (Exception e) { |
| fail("failed, " + e.getMessage()); |
| } finally { |
| if (conn != null) |
| try { |
| conn.close(); |
| } catch (SQLException e) { |
| } |
| } |
| } |
| |
| /** |
| * Test of testScenario18 method, of class org.apache.geode.internal.jta.functional.CacheTest1. |
| * Get a connection (conn1) outside a transaction with pooled datasource lookup and another |
| * connection (conn2) within the same transaction with XAPooled datasource lookup. After making |
| * updates we do a rollback on the transaction and close both connections in the order of opening |
| * them. The connection opened within transaction will only participate in the transaction. |
| */ |
| @Test |
| public void testScenario18() throws Exception { |
| this.tblIDFld = 18; |
| this.tblNameFld = "test18"; |
| boolean rollback_chances = true; |
| int ifAnyRows = 0; |
| |
| JTAUtils jtaObj = new JTAUtils(cache, currRegion); |
| |
| jtaObj.deleteRows(this.tblName); |
| |
| Context ctx = cache.getJNDIContext(); |
| |
| Connection conn2 = null; // connection within txn |
| |
| DataSource da = (DataSource) ctx.lookup("java:/PooledDataSource"); |
| Connection conn1 = da.getConnection(); // connection outside txn |
| UserTransaction ta = (UserTransaction) ctx.lookup("java:/UserTransaction"); |
| |
| try { |
| ta.begin(); |
| Statement stmt = conn1.createStatement(); |
| String sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| stmt.close(); |
| |
| ifAnyRows = jtaObj.getRows(this.tblName); |
| if (ifAnyRows == 0) { |
| fail("failed no rows are there..."); |
| } |
| // tryin a XAPooled lookup for second connection |
| da = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| conn2 = da.getConnection(); |
| stmt = conn2.createStatement(); |
| |
| this.tblIDFld += 1; |
| sqlSTR = "insert into " + this.tblName + " values (" + this.tblIDFld + "," + "'" |
| + this.tblNameFld + "'" + ")"; |
| stmt.executeUpdate(sqlSTR); |
| ta.rollback(); // intensional rollback |
| |
| stmt.close(); |
| conn2.close(); |
| conn1.close(); |
| |
| rollback_chances = false; |
| // if we reach here check whether the rollback was success for conn1 and |
| // conn2 |
| ifAnyRows = jtaObj.getRows(this.tblName); |
| assertEquals("at least one row not retained after rollback", 1, ifAnyRows); |
| |
| boolean matched = jtaObj.checkTableAgainstData(this.tblName, this.tblIDFld + ""); // checking |
| // conn2's |
| // field |
| if (matched) { // data is still in db |
| fail(", PK " + this.tblIDFld + " found in db)" + " " + "rollback for conn #2 failed"); |
| } |
| } finally { |
| if (conn1 != null) |
| try { |
| conn1.close(); |
| } catch (SQLException ex) { |
| fail(" Exception: " + ex.getMessage()); |
| } |
| if (conn2 != null) |
| try { |
| conn2.close(); |
| } catch (SQLException ex) { |
| fail(" Exception: " + ex.getMessage()); |
| } |
| } |
| } |
| |
| /** |
| * required for test # 14 |
| */ |
| static class XACacheLoaderTxn implements CacheLoader { |
| |
| String tableName; |
| |
| /** Creates a new instance of XACacheLoaderTxn */ |
| public XACacheLoaderTxn(String str) { |
| this.tableName = str; |
| } |
| |
| @Override |
| public Object load(LoaderHelper helper) throws CacheLoaderException { |
| System.out.println("In Loader.load for" + helper.getKey()); |
| return loadFromDatabase(helper.getKey()); |
| } |
| |
| private Object loadFromDatabase(Object ob) { |
| Object obj = null; |
| try { |
| Context ctx = CacheFactory.getAnyInstance().getJNDIContext(); |
| DataSource ds = (DataSource) ctx.lookup("java:/XAPooledDataSource"); |
| Connection conn = ds.getConnection(); |
| Statement stm = conn.createStatement(); |
| String str = "update " + tableName + " set name ='newname' where id = (" |
| + (new Integer(ob.toString())).intValue() + ")"; |
| stm.executeUpdate(str); |
| ResultSet rs = stm.executeQuery("select name from " + tableName + " where id = (" |
| + (new Integer(ob.toString())).intValue() + ")"); |
| rs.next(); |
| obj = rs.getString(1); |
| stm.close(); |
| conn.close(); |
| return obj; |
| } catch (Exception e) { |
| throw new Error(e); |
| } |
| } |
| |
| @Override |
| public void close() {} |
| } |
| } |