(no commit message)
authorErik Brakkee <erik@brakkee.org>
Sat, 15 Mar 2008 11:33:30 +0000 (11:33 +0000)
committerErik Brakkee <erik@brakkee.org>
Sat, 15 Mar 2008 11:33:30 +0000 (11:33 +0000)
support/src/test/java/org/wamblee/persistence/Database.java [new file with mode: 0644]
support/src/test/java/org/wamblee/persistence/DatabaseStarter.java [new file with mode: 0644]
support/src/test/java/org/wamblee/persistence/DerbyDatabase.java [new file with mode: 0644]
support/src/test/java/org/wamblee/persistence/OracleDatabase.java [new file with mode: 0644]

diff --git a/support/src/test/java/org/wamblee/persistence/Database.java b/support/src/test/java/org/wamblee/persistence/Database.java
new file mode 100644 (file)
index 0000000..eb98a6d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2005 the original author or authors.
+ * 
+ * Licensed 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.
+ */ 
+package org.wamblee.persistence;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+
+/**
+ * Represents a database.
+ */
+public interface Database {
+    /**
+     * Starts a database. This call should not block and return
+     * as soon as the database has been started.
+     * @throws Exception
+     */
+    void start(  ) throws Exception;
+
+    /**
+     * Gets the Jdbc Url to connect to this database.
+     * @return Jdbc Url.
+     */
+    String getJdbcUrl(  );
+    
+    /**
+     * Gets the external Jdbc URL to connect to this database from other JVMs. 
+     */
+    String getExternalJdbcUrl();
+    
+    /**
+     * Gets the driver class name used to connect to the database from another JVM.  
+     * @return Driver class name. 
+     */
+    String getDriverClassName(); 
+    
+    /**
+     * Gets the username to connect to the database. 
+     * @return username. 
+     */
+    String getUsername(); 
+    
+    /**
+     * Gets the password to connect to the database. 
+     * @return password. 
+     */
+    String getPassword(); 
+
+    /**
+     * Creates a new database connection. It is the caller's
+     * responsibility to close this connection.
+     *
+     * @return Newly created database connection.
+     */
+    Connection createConnection(  ) throws SQLException;
+
+    /**
+     * Stops a database.
+     * @throws Exception
+     */
+    void stop(  ) throws Exception;
+}
diff --git a/support/src/test/java/org/wamblee/persistence/DatabaseStarter.java b/support/src/test/java/org/wamblee/persistence/DatabaseStarter.java
new file mode 100644 (file)
index 0000000..c0bdcc2
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2005 the original author or authors.
+ * 
+ * Licensed 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.
+ */ 
+package org.wamblee.persistence;
+
+
+/**
+ * This class is used for starting the database from ant.
+ */
+public class DatabaseStarter {
+
+    /**
+     * Database class which encapsulates management of the database.
+     */
+    private Class _databaseClass;
+
+    /**
+     * Execution as a main program. Commandline
+     * 
+     * <pre>
+     * 
+     *    DatabaseStarter &lt;databaseClassName&gt;
+     *  
+     * </pre>
+     * 
+     * where the database class name must be the name of a concrete subclass of
+     * {@link Database}.
+     * 
+     * @param args
+     */
+    public static void main( String[] args ) throws Exception {
+        String clazz = args[0];
+        try {
+            new DatabaseStarter( Class.forName( clazz ) ).start( );
+        } catch ( Exception e ) {
+            e.printStackTrace( );
+            System.out
+                    .println( "\nUsage: ant -Ddatabase=Derby|Hypersonic startdb" );
+        }
+    }
+
+    /**
+     * Constructs the database starter.
+     * 
+     * @param aClassName
+     *            Classname of the database class to use.
+     * @throws Exception
+     */
+    public DatabaseStarter( Class aClass ) throws Exception {
+        if ( !Database.class.isAssignableFrom( aClass ) ) {
+            throw new IllegalArgumentException( "Class '"
+                    + aClass.getName( )
+                    + "' is not a subclass of Database" );
+        }
+        _databaseClass = aClass;
+    }
+
+    /**
+     * Constructs a database starter with the derby database.
+     * 
+     * @throws Exception
+     */
+    public DatabaseStarter( ) throws Exception {
+        this( DerbyDatabase.class );
+    }
+
+    /**
+     * Starts the database.
+     * 
+     * @throws Exception
+     */
+    public void start( ) throws Exception {
+        Database lDatabase = (Database) _databaseClass.newInstance( );
+        lDatabase.start( );
+        System.out.println( "Database has been started. " );
+        System.out.println( );
+        System.out.println("=======================================================");
+        System.out.println( "Connection details:" );
+        System.out.println( "  Driver class: "
+                + lDatabase.getDriverClassName( ) );
+        System.out.println( "  JDBC URL:     "
+                + lDatabase.getExternalJdbcUrl( ) );
+        System.out.println( "  username:     '" + lDatabase.getUsername( )
+                + "'" );
+        System.out.println( "  password:     '" + lDatabase.getPassword( )
+                + "'" );
+        System.out.println( "Interrupt the program to stop the database." );
+        System.out.println("=======================================================");
+        System.out.println("You must now populate the database with a schema. Use 'ant help' for information.");
+        for ( ;; ) {
+            Thread.sleep( 1000 );
+        }
+    }
+}
diff --git a/support/src/test/java/org/wamblee/persistence/DerbyDatabase.java b/support/src/test/java/org/wamblee/persistence/DerbyDatabase.java
new file mode 100644 (file)
index 0000000..1385def
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2005 the original author or authors.
+ * 
+ * Licensed 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.
+ */ 
+package org.wamblee.persistence;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.apache.derby.drda.NetworkServerControl;
+import org.apache.derby.jdbc.ClientDriver;
+import org.apache.derby.jdbc.EmbeddedDriver;
+import org.apache.log4j.Logger;
+import org.wamblee.io.FileSystemUtils;
+
+
+/**
+ * Derby database setup.
+ * The external JDBC url used to connect to a running instance is
+ * <pre>
+ *     jdbc:derby:net://localhost:1527/testdb 
+ * </pre>
+ * and the driver class is
+ * <pre>
+ *     com.ibm.db2.jcc.DB2Driver
+ * </pre>
+ * The following jars will have to be used
+ * <code>db2jcc.jar</code> and <code>db2jcc_license_c.jar</code>.
+ */
+public class DerbyDatabase implements Database {
+    
+    /**
+     * Logger.
+     */
+    private static final Logger LOGGER 
+        = Logger.getLogger( DerbyDatabase.class );
+    
+    /**
+     * Database user name.
+     */
+    private static final String USERNAME = "sa";
+
+    /**
+     * Database password.
+     */
+    private static final String PASSWORD = "123";
+
+    /**
+     * Poll interval for the checking the server status.
+     */
+    private static final int POLL_INTERVAL = 100;
+
+    /**
+     * Maximum time to wait until the server has started or stopped.
+     */
+    private static final int MAX_WAIT_TIME = 10000;
+
+    /**
+     * Database name to use.
+     */
+    private static final String DATABASE_NAME = "testdb";
+
+    /**
+     * Path on the file system where derby files are stored.
+     */
+    private static final String DATABASE_PATH = "target/db/persistence/derby";
+
+    /**
+     * Derby property required to set the file system path
+     * {@link #DATABASE_PATH}.
+     */
+    private static final String SYSTEM_PATH_PROPERTY = "derby.system.home";
+    
+    /**
+     * Constructs derby database class to allow creation of derby
+     * database instances.
+     */
+    public DerbyDatabase(  ) {
+        // Empty
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.wamblee.persistence.Database#start()
+     */
+    public void start(  ) throws Exception {
+        // just in case a previous run was killed without the 
+        // cleanup
+        cleanPersistentStorage(  );
+
+        // set database path.
+        Properties lProperties = System.getProperties(  );
+        lProperties.put( SYSTEM_PATH_PROPERTY, DATABASE_PATH );
+        
+        Class.forName( "org.apache.derby.jdbc.EmbeddedDriver" ).newInstance(  );
+        
+        runDatabase(  );
+
+        waitUntilStartedOrStopped( true );
+
+        // Force creation of the database.
+        Connection lConnection = createConnection(  );
+        lConnection.close(  );
+    }
+
+    /**
+     * Waits until the database server has started or stopped.
+     *
+     * @param aStarted
+     *            If true, waits until the server is up, if false, waits until
+     *            the server is down.
+     * @throws InterruptedException
+     */
+    private void waitUntilStartedOrStopped( boolean aStarted )
+        throws InterruptedException {
+        long lWaited = 0;
+
+        while ( aStarted != isStarted(  ) ) {
+            Thread.sleep( POLL_INTERVAL );
+            lWaited += POLL_INTERVAL;
+
+            if ( lWaited > MAX_WAIT_TIME ) {
+                throw new RuntimeException( 
+                    "Derby database did not start within " + MAX_WAIT_TIME
+                    + "ms" );
+            }
+        }
+    }
+
+    /**
+     * Checks if the database server has started or not.
+     *
+     * @return True if started, false otherwise.
+     */
+    private boolean isStarted(  ) {
+        try {
+            getControl(  ).ping(  );
+
+            return true;
+        } catch ( Exception e ) {
+            return false;
+        }
+    }
+
+    /**
+     * Gets the controller for the database server.
+     *
+     * @return Controller.
+     * @throws Exception
+     */
+    private NetworkServerControl getControl(  ) throws Exception {
+        return new NetworkServerControl(  );
+    }
+
+    /**
+     * Runs the database.
+     *
+     */
+    private void runDatabase(  ) {
+        try {
+            getControl(  ).start( new PrintWriter( System.out ) );
+        } catch ( Exception e ) {
+            throw new RuntimeException( e );
+        }
+    }
+
+   /*
+    * (non-Javadoc)
+    * @see org.wamblee.persistence.Database#getJdbcUrl()
+    */
+    public String getJdbcUrl(  ) {
+        return getBaseJdbcUrl(  )
+        + ";create=true;retrieveMessagesFromServerOnGetMessage=true;";
+    }
+
+    private String getBaseJdbcUrl(  ) {
+        return "jdbc:derby:" + DATABASE_NAME;
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.wamblee.persistence.Database#getExternalJdbcUrl()
+     */
+    public String getExternalJdbcUrl( ) {
+        return "jdbc:derby:net://localhost:1527/" + DATABASE_NAME;
+    }
+
+    /**
+     * Shuts down the derby database and cleans up all created files.
+     *
+     */
+    private void shutdownDerby(  ) {
+        try {
+            DriverManager.getConnection( "jdbc:derby:;shutdown=true" );
+            throw new RuntimeException( 
+                "Derby did not shutdown, " 
+                    + " should always throw exception at shutdown" );
+        } catch ( Exception e ) {
+            LOGGER.info( "Derby has been shut down." );
+        }
+    }
+    
+   /*
+    * (non-Javadoc)
+    * @see org.wamblee.persistence.Database#getDriverClassName()
+    */
+    public String getDriverClassName( ) {
+        return ClientDriver.class.getName();
+    }
+
+    /**
+     * Gets the user name.
+     */
+    public String getUsername(  ) {
+        return USERNAME;
+    }
+
+    /**
+     * Gets the password.
+     * @return
+     */
+    public String getPassword(  ) {
+        return PASSWORD;
+    }
+
+   /*
+    * (non-Javadoc)
+    * @see org.wamblee.persistence.Database#createConnection()
+    */
+    public Connection createConnection(  ) throws SQLException {
+        Connection c =
+            DriverManager.getConnection( getJdbcUrl(  ), getUsername(  ),
+                getPassword(  ) );
+
+        return c;
+    }
+
+    /**
+     * Stops the derby database and cleans up all derby files.
+     */
+    public void stop(  ) throws Exception {
+        // shutdown network server.
+        getControl(  ).shutdown(  );
+        waitUntilStartedOrStopped( false );
+
+        // shutdown inmemory access.
+        shutdownDerby(  );
+        cleanPersistentStorage(  );
+    }
+
+    /**
+     * Cleans up persistent storage of Derby.
+     */
+    private void cleanPersistentStorage(  ) {
+        File lFile = new File( DATABASE_PATH );
+
+        if ( lFile.isFile(  ) ) {
+            TestCase.fail( "A regular file by the name " + DATABASE_PATH
+                + " exists, clean this up first" );
+        }
+
+        if ( !lFile.isDirectory(  ) ) {
+            return; // no-op already cleanup up. 
+        }
+
+        FileSystemUtils.deleteDirRecursively( DATABASE_PATH );
+    }
+}
diff --git a/support/src/test/java/org/wamblee/persistence/OracleDatabase.java b/support/src/test/java/org/wamblee/persistence/OracleDatabase.java
new file mode 100644 (file)
index 0000000..a091dbc
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2005 the original author or authors.
+ * 
+ * Licensed 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.
+ */ 
+package org.wamblee.persistence;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class OracleDatabase implements Database {
+    
+    public OracleDatabase() {
+        super();
+    }
+
+    public void start( ) throws Exception {
+       System.out.println("Oracle must be started externally");
+    }
+
+    public String getJdbcUrl( ) {
+        return null;
+    }
+
+    public String getExternalJdbcUrl( ) {
+        return null;
+    }
+
+    public String getDriverClassName( ) {
+        return null;
+    }
+
+    public String getUsername( ) {
+        return null;
+    }
+
+    public String getPassword( ) {
+        return null;
+    }
+
+    public Connection createConnection( ) throws SQLException {
+        return null;
+    }
+
+    public void stop( ) throws Exception {
+        System.out.println("Oracle must be stopped externally");
+    }
+
+}