You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by mi...@apache.org on 2006/04/27 18:48:43 UTC

svn commit: r397586 - in /db/derby/code/branches/10.1/java: engine/org/apache/derby/impl/store/raw/log/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/suites/ testing/org/apache/derbyTesting/function...

Author: mikem
Date: Thu Apr 27 09:48:40 2006
New Revision: 397586

URL: http://svn.apache.org/viewcvs?rev=397586&view=rev
Log:
DERBY-1039

Backported 397014 and 397011 from trunk to 10.1 to port fix for DERBY-1039 
from trunk to 10.1 branch.  Also ported current trunk version of TestUtil.java
as the new test for 1039 required new functionality in this utility class.  
Changing the TestUtil class required a master update to the dblook_test.

DERBY-1039 desc:
database create will fail with error if the user specified logDevice location
already contains non-empty "log" dir at that location.
added a new test that tests database creation with logDevice location
with absolute paths and also the above expected error case.


Added:
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/LogDeviceTest.out   (props changed)
      - copied unchanged from r397014, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LogDeviceTest.out
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogDeviceTest.java   (props changed)
      - copied unchanged from r397014, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogDeviceTest.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogDeviceTest_app.properties   (props changed)
      - copied unchanged from r397014, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogDeviceTest_app.properties
Modified:
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java?rev=397586&r1=397585&r2=397586&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java (original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java Thu Apr 27 09:48:40 2006
@@ -2438,6 +2438,36 @@
 
 	}
 
+
+
+    /**
+     * Create the directory where transaction log should go.
+     * @exception StandardException Standard Error Policy
+    */
+	private void createLogDirectory() throws StandardException
+	{
+		StorageFile logDir = 
+            logStorageFactory.newStorageFile(LogFactory.LOG_DIRECTORY_NAME);
+
+        if (privExists(logDir)) {
+            // make sure log directory is empty.
+            String[] logfiles = privList(logDir);
+            if (logfiles != null) {
+                if(logfiles.length != 0) {
+                    throw StandardException.newException(
+                        SQLState.LOG_SEGMENT_EXIST, logDir.getPath());
+                }
+            }
+            
+        }else {
+            // create the log directory.
+            if (!privMkdirs(logDir)) {
+                throw StandardException.newException(
+                    SQLState.LOG_SEGMENT_NOT_EXIST, logDir.getPath());
+            }
+        }
+	}
+
 	/*
 		Return the directory the log should go.
 
@@ -2450,7 +2480,7 @@
 
 		logDir = logStorageFactory.newStorageFile( LogFactory.LOG_DIRECTORY_NAME);
 
-        if (!privExists(logDir) && !privMkdirs(logDir))
+        if (!privExists(logDir))
 		{
 			throw StandardException.newException(
                     SQLState.LOG_SEGMENT_NOT_EXIST, logDir.getPath());
@@ -2780,48 +2810,44 @@
 				logDevice = logDeviceURL;
         }
 
-		//check whether we are restoring from backup
-		restoreLogs(startParams);
-		
+
+        if(create) {
+            getLogStorageFactory();
+            createLogDirectory();
+            
+        } else {
+            // check if the database is being restored from the backup,
+            // if it is then restore the logs.
+            if (!restoreLogs(startParams)) {
+                // set the log storage factory.
+                getLogStorageFactory();
+                if (logDevice != null)
+                {
+                    // Make sure we find the log, do not assume 
+                    // it is OK that the log is not there because 
+                    // it could be a user typo(like when users edit
+                    // service.properties to change the log device 
+                    // while restoring from backups using OS copy.
+                    StorageFile checklogDir =
+                        logStorageFactory.newStorageFile( 
+                                 LogFactory.LOG_DIRECTORY_NAME);
+                    if (!privExists(checklogDir))
+                    {
+                        throw
+                            StandardException.newException(
+                            SQLState.LOG_FILE_NOT_FOUND, checklogDir.getPath());
+
+                    }
+                }
+            }
+        }
+        		
 		//if user does not set the right value for the log buffer size,
 		//default value is used instead.
 		logBufferSize =  PropertyUtil.getSystemInt(org.apache.derby.iapi.reference.Property.LOG_BUFFER_SIZE, 
 												   LOG_BUFFER_SIZE_MIN, 
 												   LOG_BUFFER_SIZE_MAX, 
 												   DEFAULT_LOG_BUFFER_SIZE);
-
-        if( logStorageFactory == null)
-            getLogStorageFactory();
-		if (logDevice != null)
-		{
-			// in case the user specifies logDevice in URL form
-			String logDeviceURL = null;
-			try {
-				URL url = new URL(logDevice);
-				logDeviceURL = url.getFile();
-			} catch (MalformedURLException ex) {}
-			if (logDeviceURL != null)
-				logDevice = logDeviceURL;
-
-			// Make sure we find the log, do not assume it is OK that the log
-			// is not there because it could be a user typo.
-			if (!create)
-			{
-				StorageFile checklogDir =
-					logStorageFactory.newStorageFile( LogFactory.LOG_DIRECTORY_NAME);
-
-                if (!privExists(checklogDir))
-				{
-
-					throw
-                        StandardException.newException(
-                            SQLState.LOG_FILE_NOT_FOUND, checklogDir.getPath());
-
-				}
-			}
-		}
-
-
 		jbmsVersion = Monitor.getMonitor().getEngineVersion();
 
 		String dataEncryption = 
@@ -4489,11 +4515,12 @@
 	 * This function restores logs based on the  following attributes
 	 * are specified on connection URL:
 	 * Attribute.CREATE_FROM (Create database from backup if it does not exist)
-	 * Attribute.RESTORE_FROM (Delete the whole database if it exists and then restore
-	 * it from backup)
+	 * Attribute.RESTORE_FROM (Delete the whole database if it exists and then 
+     * restore it from backup)
 	 * Attribute.ROLL_FORWARD_RECOVERY_FROM:(Perform Rollforward Recovery;
 	 * except for the log directory everthing else is replced  by the copy  from
-	 * backup. log files in the backup are copied to the existing online log directory.
+	 * backup. log files in the backup are copied to the existing online log 
+     * directory.
 	 *
 	 * In cases of RESTORE_FROM whole databases directoy is 
 	 * is removed in Directory.java while restoring service.properties
@@ -4503,57 +4530,54 @@
 	 * In case ROLL_FORWARD_RECOVERY_FROM log directotry should not be removed.
 	 * So only thing that needs to be done here is create a
 	 * a log directory if it does not exists and copy the 
-	 * log files(including control files) that exists in the backup from which we are
-	 * are trying to restore the database to the onlie log directory.
+	 * log files(including control files) that exists in the backup from which 
+     * we are are trying to restore the database to the onlie log directory.
 	 */
-	private void restoreLogs(Properties properties) throws StandardException
+	private boolean restoreLogs(Properties properties) throws StandardException
 	{
 
 		String backupPath =null;
 		boolean isCreateFrom = false; 
 		boolean isRestoreFrom = false;
 
-		//check if the user request for restore/recovery/create from backup
+		//check if the user requested for restore/recovery/create from backup
 		backupPath = properties.getProperty(Attribute.CREATE_FROM);
-		if(backupPath == null)
+        if (backupPath != null) {
+            isCreateFrom = true;
+        } else {
 			backupPath = properties.getProperty(Attribute.RESTORE_FROM);
-		else
-			isCreateFrom = true;
-
-		if(backupPath == null)
-			backupPath =
-				properties.getProperty(Attribute.ROLL_FORWARD_RECOVERY_FROM);
-		else
-			isRestoreFrom = true;
-		
+            if (backupPath != null) {
+                isRestoreFrom = true;
+            } else {
+                backupPath = properties.getProperty(
+                                  Attribute.ROLL_FORWARD_RECOVERY_FROM);
+                // if the backup is not NULL then it is a rollforward recovery.
+            }
+        }
 
 		if(backupPath !=null)
 		{
 			if(!isCreateFrom){
 				if(logDevice == null){
 					/**
-					 * In  restoreFrom/rollForwardRecoveryFrom  mode when no logDevice on
-					 * URL then the log is restored to the same location where the log was 
-					 * when backup was taken.
-					 * In createFrom mode behaviour is same as when create=true , 
-					 * i.e unless user specifies the logDevice on URL, log will be copied to
-					 * the database home dir.
+					 * In restoreFrom/rollForwardRecoveryFrom mode when no 
+                     * logDevice on URL then the log is restored to the same 
+                     * location where the log was when backup was taken.
+					 * In createFrom mode behaviour is same as when create=true,
+					 * i.e unless user specifies the logDevice on URL, log will
+                     * be copied to the database home dir.
 					 * Note: LOG_DEVICE_AT_BACKUP will get set if log is not in
 					 * default location(db home). 
 					 */
-					logDevice = properties.getProperty(Property.LOG_DEVICE_AT_BACKUP);
+					logDevice = 
+                        properties.getProperty(Property.LOG_DEVICE_AT_BACKUP);
 				}
 			}	 
+        
             getLogStorageFactory();
-
 			StorageFile logDir;
-			logDir = logStorageFactory.newStorageFile( LogFactory.LOG_DIRECTORY_NAME);
-			if(isCreateFrom){
-				//log dir should not exist if we are doing create from
-				if(privExists(logDir))
-					throw StandardException.newException(SQLState.LOG_SEGMENT_EXIST, getLogDirPath( logDir));
-			}
-
+			logDir = logStorageFactory.newStorageFile( 
+                             LogFactory.LOG_DIRECTORY_NAME);
 				
 			//remove the log directory in case of restoreFrom 
 			//if it exist, this happens if the log device is on seperate
@@ -4564,13 +4588,20 @@
 				{
 					//it may be just a file, try deleting it
 					if(!privDelete(logDir))
-						throw StandardException.newException(SQLState.UNABLE_TO_REMOVE_DATA_DIRECTORY,
-                                                             getLogDirPath( logDir));
+                    {
+						throw StandardException.newException(
+                            SQLState.UNABLE_TO_REMOVE_DATA_DIRECTORY,
+                            getLogDirPath( logDir));
+                    }
 				}
 			}
 
+            // if it is a create/restore from backup, 
+            // create the log directory.
+            if (isCreateFrom || isRestoreFrom) {
+                createLogDirectory();
+            }
 
-			logDir = getLogDirectory();
 			File backupLogDir = new File(backupPath, LogFactory.LOG_DIRECTORY_NAME);
 			String[] logfilelist = privList(backupLogDir);
 			if(logfilelist !=null)
@@ -4594,7 +4625,13 @@
 			//be replacing updated log after a restore withe 
 			// a log in the backup on next restore.
 			logSwitchRequired = true;
-		}
+
+            // log is restored from backup.
+            return true;
+		} else {
+            // log is not restored from backup.
+            return false;
+        }
 	}
 
 	/*preallocate the given log File to the logSwitchInterval size;

Propchange: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/LogDeviceTest.out
------------------------------------------------------------------------------
    eol-style = native

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out?rev=397586&r1=397585&r2=397586&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out Thu Apr 27 09:48:40 2006
@@ -5302,7 +5302,7 @@
  java org.apache.derby.tools.dblook -d <sourceDBUrl> [OPTIONS]
  	where the source URL is the full URL, including the connection protocol
  	and any connection attributes that might apply.  For example, use
- 	'jdbc:derby:myDB', or 'jdbc:derby:net://localhost:1527/myDB:user=usr;'. 
+ 	'jdbc:derby:myDB', or 'jdbc:derby://localhost:1527/myDB;user=usr;'. 
  	options include: 
  	-z <schemaName> to specify a schema to which the DDL generation
  	 should be limited.  Only database objects with that schema will have

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall?rev=397586&r1=397585&r2=397586&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storemore.runall Thu Apr 27 09:48:40 2006
@@ -29,3 +29,4 @@
 store/holdCursorExternalSortJDBC30.sql
 store/TestDurabilityProperty.java
 store/OnlineCompressTest.java
+store/LogDeviceTest.java

Propchange: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogDeviceTest.java
------------------------------------------------------------------------------
    eol-style = native

Propchange: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/LogDeviceTest_app.properties
------------------------------------------------------------------------------
    eol-style = native

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant?rev=397586&r1=397585&r2=397586&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/store/copyfiles.ant Thu Apr 27 09:48:40 2006
@@ -138,4 +138,4 @@
 MaxLogNumber_derby.properties
 MaxLogNumberRecovery_app.properties
 MaxLogNumberRecovery_derby.properties
-
+LogDeviceTest_app.properties

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java?rev=397586&r1=397585&r2=397586&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/TestUtil.java Thu Apr 27 09:48:40 2006
@@ -28,7 +28,18 @@
 import java.util.Hashtable;
 import java.util.Locale;
 import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.NoSuchElementException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+import javax.sql.DataSource;
+
 import org.apache.derby.iapi.reference.JDBC30Translation;
+import org.apache.derby.iapi.services.info.JVMInfo;
+
+
 
 
 /**
@@ -37,6 +48,19 @@
 
 */
 public class TestUtil {
+	
+	//Used for JSR169
+	public static boolean HAVE_DRIVER_CLASS;
+	static{
+		try{
+			Class.forName("java.sql.Driver");
+			HAVE_DRIVER_CLASS = true;
+		}
+		catch(ClassNotFoundException e){
+			//Used for JSR169
+			HAVE_DRIVER_CLASS = false;
+		}
+	}
 
 	public static final int UNKNOWN_FRAMEWORK = -1;
 
@@ -79,6 +103,7 @@
 	private static String XA_DATASOURCE_STRING = "XA";
 	private static String CONNECTION_POOL_DATASOURCE_STRING = "ConnectionPool";
 	private static String REGULAR_DATASOURCE_STRING = "";
+	private static String JSR169_DATASOURCE_STRING = "Simple";
 	
 	// Methods for making framework dependent decisions in tests.
 
@@ -144,7 +169,13 @@
 	{
 		if (framework != UNKNOWN_FRAMEWORK)
 			return framework;
-		String frameworkString = System.getProperty("framework");
+              String frameworkString = (String) AccessController.doPrivileged
+                  (new PrivilegedAction() {
+                          public Object run() {
+                              return System.getProperty("framework");
+                          }
+                      }
+                   );              
 		if (frameworkString == null || 
 		   frameworkString.toUpperCase(Locale.ENGLISH).equals("EMBEDDED"))
 			framework = EMBEDDED_FRAMEWORK;
@@ -162,14 +193,33 @@
 	/**
 	    Get URL prefix for current framework.
 		
-		@return url, assume localhost and port 1527 for Network Tests
+		@return url, assume localhost - unless set differently in System property - 
+		             and assume port 1527 for Network Tests
 		@see getJdbcUrlPrefix(String server, int port)
 		
 	*/
-	public static String getJdbcUrlPrefix()
-	{
-		return getJdbcUrlPrefix("localhost", 1527);
-	}
+    public static String getJdbcUrlPrefix()
+    {
+        String hostName=getHostName();
+        return getJdbcUrlPrefix(hostName, 1527);
+    }
+
+    /** Get hostName as passed in - if not, set it to "localhost" 
+        @return hostName, as passed into system properties, or "localhost"
+    */
+    public static String getHostName()
+    {
+        String hostName = (String) AccessController.doPrivileged
+            (new PrivilegedAction() {
+                    public Object run() {
+                        return System.getProperty("hostName");
+                    }
+                }
+             );    
+        if (hostName == null)
+            hostName="localhost";
+        return hostName;
+    }
 
 	/** 
 		Get URL prefix for current framework		
@@ -209,7 +259,7 @@
 	*/
 	public static void loadDriver() throws Exception
 	{
-		String driverName = null;
+              final String driverName;
 		framework = getFramework();
 		switch (framework)
 		{
@@ -224,9 +274,23 @@
 			case DERBY_NET_CLIENT_FRAMEWORK:
 				driverName = "org.apache.derby.jdbc.ClientDriver";
 				break;
-		}
-		Class.forName(driverName).newInstance();
-	}
+                      default: 
+                            driverName=  "org.apache.derby.jdbc.EmbeddedDriver";
+                            break;
+		}
+                                
+              try {
+                  AccessController.doPrivileged
+                      (new PrivilegedExceptionAction() {
+                              public Object run() throws Exception {
+                                  return Class.forName(driverName).newInstance();
+                              }
+                          }
+                       );
+              } catch (PrivilegedActionException e) {
+                  throw e.getException();
+              }
+        }
 
 
 	/**
@@ -239,11 +303,23 @@
 	 */
 	public static javax.sql.DataSource getDataSource(Properties attrs)
 	{
+		String classname;
+		if(HAVE_DRIVER_CLASS)
+		{
+			classname = getDataSourcePrefix() + REGULAR_DATASOURCE_STRING + "DataSource";
+			return (javax.sql.DataSource) getDataSourceWithReflection(classname, attrs);
+		}
+		else
+			return getSimpleDataSource(attrs);
 		
-		String classname = getDataSourcePrefix() + REGULAR_DATASOURCE_STRING + "DataSource";
-		return (javax.sql.DataSource) getDataSourceWithReflection(classname, attrs);
 	}
 
+	public static DataSource getSimpleDataSource(Properties attrs)
+	{
+		String classname = getDataSourcePrefix() + JSR169_DATASOURCE_STRING + "DataSource";
+		return (javax.sql.DataSource) getDataSourceWithReflection(classname, attrs);
+	}
+	
 	/**
 	 * Get an xa  data source for the appropriate framework
 	 * @param attrs  A set of attribute values to set on the datasource.
@@ -273,26 +349,27 @@
 		String classname = getDataSourcePrefix() + CONNECTION_POOL_DATASOURCE_STRING + "DataSource";
 		return (javax.sql.ConnectionPoolDataSource) getDataSourceWithReflection(classname, attrs);
 	}
+        
 
 	public static String getDataSourcePrefix()
-		{
-			framework = getFramework();
-			switch(framework)
-			{
-				case OLD_NET_FRAMEWORK:
-				case DERBY_NET_FRAMEWORK:
-				case DB2JCC_FRAMEWORK:
-					return "com.ibm.db2.jcc.DB2";
-				case DERBY_NET_CLIENT_FRAMEWORK:
-					return "org.apache.derby.jdbc.Client";
-				case EMBEDDED_FRAMEWORK:
-					return "org.apache.derby.jdbc.Embedded";
-				default:
-					Exception e = new Exception("FAIL: No DataSource Prefix for framework: " + framework);
-					e.printStackTrace();
-			}
-			return null;
-		}
+    {
+        framework = getFramework();
+        switch(framework)
+        {
+            case OLD_NET_FRAMEWORK:
+            case DERBY_NET_FRAMEWORK:
+            case DB2JCC_FRAMEWORK:
+                return "com.ibm.db2.jcc.DB2";
+            case DERBY_NET_CLIENT_FRAMEWORK:
+                return "org.apache.derby.jdbc.Client";
+            case EMBEDDED_FRAMEWORK:
+                return "org.apache.derby.jdbc.Embedded";
+            default:
+                Exception e = new Exception("FAIL: No DataSource Prefix for framework: " + framework);
+                e.printStackTrace();
+        }
+        return null;
+    }
 
 
 
@@ -324,6 +401,12 @@
 		try {
 		ds  = Class.forName(classname).newInstance();
 
+		// for remote server testing, check whether the hostName is set for the test
+		// if so, and serverName is not yet set explicitly for the datasource, set it now
+		String hostName = getHostName();
+		if ( (!isEmbeddedFramework()) && (hostName != null ) && (attrs.getProperty("serverName") == null) )
+			attrs.setProperty("serverName", hostName);
+
 		for (Enumeration propNames = attrs.propertyNames(); 
 			 propNames.hasMoreElements();)
 		{
@@ -637,8 +720,160 @@
 
 	}
 
+    /**
+        Drop the test objects passed in as a string identifying the
+        type of object (e.g. TABLE, PROCEDURE) and its name.
+        Thus, for example, a testObject array could be:
+        {"TABLE MYSCHEMA.MYTABLE", "PROCEDURE THISDUMMY"}
+        The statement passed in must be a 'live' statement in the test.
+    */
+    public static void cleanUpTest (Statement s, String[] testObjects)
+                                    throws SQLException {
+        /* drop each object named */
+        for (int i=0; i < testObjects.length; i++) {
+            try {
+                s.execute("drop " + testObjects[i]);
+                //System.out.println("now dropping " + testObjects[i]);
+            } catch (SQLException se) { // ignore...
+            }
+        }	
+    }
+
+    
+    /**
+     * Get connection to given database using the connection attributes. This
+     * method is used by tests to get a secondary connection with 
+     * different set of attributes. It does not use what is specified in 
+     * app_properties file or system properties. This method uses DataSource 
+     * class for CDC/Foundation Profile environments, which are based on 
+     * JSR169. Using DataSource will not work with other j9 profiles. So
+     * DriverManager is used for non-JSR169. The method is used as a wrapper to
+     * hide this difference in getting connections in different environments.
+     *  
+     * @param databaseName
+     * @param connAttrs
+     * @return Connection to database 
+     * @throws SQLException on failure to connect.
+     * @throws ClassNotFoundException on failure to load driver.
+     * @throws InstantiationException on failure to load driver.
+     * @throws IllegalAccessException on failure to load driver.
+     */
+    public static Connection getConnection(String databaseName, String connAttrs)
+    	throws SQLException {
+        try {
+            Connection conn;
+            if(TestUtil.HAVE_DRIVER_CLASS) {
+                // following is like loadDriver(), but
+                // that method throws Exception, we want finer granularity
+                String driverName;
+                int framework = getFramework();
+                switch (framework)
+                {
+                    case EMBEDDED_FRAMEWORK:
+                        driverName =  "org.apache.derby.jdbc.EmbeddedDriver";
+                        break;
+                    case DERBY_NET_FRAMEWORK:
+                    case OLD_NET_FRAMEWORK:				
+                    case DB2JCC_FRAMEWORK:				
+                        driverName = "com.ibm.db2.jcc.DB2Driver";
+                        break;
+                    case DERBY_NET_CLIENT_FRAMEWORK:
+                        driverName = "org.apache.derby.jdbc.ClientDriver";
+                        break;
+                    default:
+                        driverName =  "org.apache.derby.jdbc.EmbeddedDriver";
+                        break;
+                } 
+                // q: do we need a privileged action here, like in loadDriver?
+                Class.forName(driverName).newInstance();
+				
+                String url = getJdbcUrlPrefix() + databaseName;
+                if (connAttrs != null) url += ";" + connAttrs;
+                if (framework == DERBY_NET_FRAMEWORK)
+                {
+                    if (( connAttrs == null) || ((connAttrs != null) && (connAttrs.indexOf("user") < 0)))
+                        url += ":" + "user=APP;password=APP;retrieveMessagesFromServerOnGetMessage=true;";
+                }
+                conn = DriverManager.getConnection(url);
+    	    }
+    	    else {
+    		    //Use DataSource for JSR169
+	    	    Properties prop = new Properties();
+	            prop.setProperty("databaseName", databaseName);
+    		    if (connAttrs != null)
+	                prop.setProperty("connectionAttributes", connAttrs);
+	            conn = getDataSourceConnection(prop);
+    	    }
+            return conn;
+    	} catch (ClassNotFoundException cnfe) { 
+		    System.out.println("FAILure: Class not found!");
+		    cnfe.printStackTrace();
+		    return null;
+    	} catch (InstantiationException inste) {
+    		System.out.println("FAILure: Cannot instantiate class");
+    		inste.printStackTrace();
+    		return null;
+    	} catch (IllegalAccessException ille) {
+    		System.out.println("FAILure: Not allowed to use class");
+    		ille.printStackTrace();
+    		return null;
+    	}
+    }
+    
+    public static Connection getDataSourceConnection (Properties prop) throws SQLException {
+		DataSource ds = TestUtil.getDataSource(prop);
+		try {
+			Connection conn = ds.getConnection();
+			return conn;
+		}
+		catch (SQLException e) {
+			throw e;
+		}
+	}
+	
+	public static void shutdownUsingDataSource (String dbName) throws SQLException {
+		Properties prop = new Properties();
+		prop.setProperty("databaseName", dbName );
+		prop.setProperty("shutdownDatabase", "shutdown" );
+		DataSource ds = TestUtil.getDataSource(prop);
+		try {
+			Connection conn = ds.getConnection();
+		}
+		catch (SQLException e) {
+			throw e;
+		}
+	}
+	
+	//Used by metadata tests for DatabaseMetadata.getURL
+	public static boolean compareURL(String url) {
+			
+		if(isEmbeddedFramework()) {
+			if(url.compareTo("jdbc:derby:wombat") == 0)
+				return true;
+		} else if(isNetFramework()) {
+			try {
+				StringTokenizer urlTokenizer = new StringTokenizer(url, "/");
+				String urlStart = urlTokenizer.nextToken();
+				urlTokenizer.nextToken();
+				String urlEnd = urlTokenizer.nextToken();
+				
+				if(urlEnd.compareTo("wombat;create=true") != 0)
+					return false;
+				
+				if(isJCCFramework() && (urlStart.compareTo("jdbc:derby:net:") == 0))
+					return true;
+				
+				if(isDerbyNetClientFramework() && (urlStart.compareTo("jdbc:derby:") == 0))
+					return true;
+				
+			} catch (NoSuchElementException nsee) {
+				//Should not reach here.
+				return false;
+			}
+		}
+		
+		return false;
+	}
 
 }
-
-