Author: jeff.yuchang
Date: 2009-11-17 10:07:35 -0500 (Tue, 17 Nov 2009)
New Revision: 276
Added:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/db/H2Database.java
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/db/H2DatabaseMBean.java
Modified:
trunk/distribution/src/main/release/db/datasource/bpel-hsql-ds.xml
trunk/runtime/engine/pom.xml
Log:
* port the H2Database from ESB.
Modified: trunk/distribution/src/main/release/db/datasource/bpel-hsql-ds.xml
===================================================================
--- trunk/distribution/src/main/release/db/datasource/bpel-hsql-ds.xml 2009-11-17 14:37:12
UTC (rev 275)
+++ trunk/distribution/src/main/release/db/datasource/bpel-hsql-ds.xml 2009-11-17 15:07:35
UTC (rev 276)
@@ -15,7 +15,7 @@
<prepared-statement-cache-size>32</prepared-statement-cache-size>
<depends>jboss:service=h2,database=BPELDB</depends>
</local-tx-datasource>
- <mbean code="org.jboss.internal.soa.esb.dependencies.H2Database"
+ <mbean code="rg.jboss.soa.bpel.runtime.db.H2Database"
name="jboss:service=h2,database=BPELDB">
<attribute name="Database">BPELDB</attribute>
<attribute name="DataDir">${jboss.server.data.dir}</attribute>
Modified: trunk/runtime/engine/pom.xml
===================================================================
--- trunk/runtime/engine/pom.xml 2009-11-17 14:37:12 UTC (rev 275)
+++ trunk/runtime/engine/pom.xml 2009-11-17 15:07:35 UTC (rev 276)
@@ -122,9 +122,23 @@
<version>${riftsaw.engine.version}</version>
<scope>provided</scope>
</dependency>
+
+ <!-- for H2Database -->
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <version>1.0.68</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.client</groupId>
+ <artifactId>jbossall-client</artifactId>
+ <version>4.2.3.GA</version>
+ <scope>provided</scope>
+ </dependency>
-
</dependencies>
Added: trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/db/H2Database.java
===================================================================
--- trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/db/H2Database.java
(rev 0)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/db/H2Database.java 2009-11-17
15:07:35 UTC (rev 276)
@@ -0,0 +1,593 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.soa.bpel.runtime.db;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.h2.tools.Server;
+import org.jboss.mx.util.MBeanProxyExt;
+import org.jboss.system.ServiceMBeanSupport;
+import org.jboss.system.server.ServerConfig;
+import org.jboss.system.server.ServerConfigImplMBean;
+
+/**
+ * Integration with H2.
+ *
+ * @author <a href="mailto:rickard.oberg@telkel.com">Rickard
�berg</a>
+ * @author <a href="mailto:Scott_Stark@displayscape.com">Scott
Stark</a>.
+ * @author <a href="mailto:pf@iprobot.com">Peter Fagerlund</a>
+ * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
+ * @author <a href="mailto:vesco.claudio@previnet.it">Claudio
Vesco</a>
+ * @author <a href="mailto:dimitris@jboss.org">Dimitris
Andreadis</a>
+ * @author <a href="mailto:kevin.conner@jboss.org">Kevin
Conner</a>
+ * @author <a href="mailto:dbevenius@redhat.com">Daniel
Bevenius</a>
+ * @version $Revision: 27106 $
+ */
+public class H2Database extends ServiceMBeanSupport implements H2DatabaseMBean
+{
+ /** Default password: <code>empty string</code>. */
+ private static final String DEFAULT_PASSWORD = "";
+
+ /** Default user: <code>sa</code>. */
+ private static final String DEFAULT_USER = "sa";
+
+ /** JDBC Driver class: <code>org.h2.Driver</code>. */
+ private static final String JDBC_DRIVER_CLASS = "org.h2.Driver";
+
+ /** JDBC URL common prefix: <code>jdbc:h2:</code>. */
+ private static final String JDBC_URL_PREFIX = "jdbc:h2:";
+
+ /** JDBC in memory URL prefix: <code>jdbc:h2:mem:</code>. */
+ private static final String JDBC_MEM_URL_PREFIX = JDBC_URL_PREFIX +
"mem:";
+
+ /** JDBC flags */
+ private static final String DEFAULT_FLAGS =
";MVCC=TRUE;DB_CLOSE_ON_EXIT=FALSE";
+
+ /** Default data subdir: <code>h2</code>. */
+ private static final String H2_DATA_DIR = "h2";
+
+ /** Default database name: <code>default</code>. */
+ private static final String DEFAULT_DATABASE_NAME = "default";
+
+ /** Default address for remote h2: <code>0.0.0.0</code>. */
+ private static final String DEFAULT_ADDRESS = "0.0.0.0";
+
+ /** Default port for remote h2: <code>9092</code>. */
+ private static final int DEFAULT_PORT = 9092;
+
+ /** Default delay for remote hypersonic initialisation (ms):
<code>5000</code>. */
+ private static final long DEFAULT_DELAY = 5000;
+
+ // Private Data --------------------------------------------------
+
+ /** Full path to db/h2. */
+ private File dbPath;
+
+ /** Database name. */
+ private String name = DEFAULT_DATABASE_NAME;
+
+ /** In memory mode. */
+ private boolean inMemoryMode ;
+
+ /** Database user. */
+ private String user = DEFAULT_USER;
+
+ /** Database password. */
+ private String password = DEFAULT_PASSWORD;
+
+ /** Database flags */
+ private String flags = DEFAULT_FLAGS ;
+
+ /** Hold a connection for in memory h2. */
+ private Connection connection;
+
+ /** Default address. */
+ private String address = DEFAULT_ADDRESS;
+
+ /** Default port. */
+ private int port = DEFAULT_PORT;
+
+ /** Server/remote mode. */
+ private boolean serverMode = false;
+
+ /** Server thread for remote h2. */
+ private Thread serverThread;
+
+ /** The remote server instance */
+ private Server remoteServer ;
+
+ /** Server thread delay for remote H2. */
+ private long delay = DEFAULT_DELAY ;
+
+ private String datadir;
+
+ // Attributes ----------------------------------------------------
+
+ /**
+ * Set the database name.
+ *
+ * @jmx.managed-attribute
+ */
+ public void setDatabase(String name)
+ {
+ if (name == null)
+ {
+ name = DEFAULT_DATABASE_NAME;
+ }
+ this.name = name;
+ }
+
+ /**
+ * Get the database name.
+ *
+ * @jmx.managed-attribute
+ */
+ public String getDatabase()
+ {
+ return name;
+ }
+
+ /**
+ * Get the full database path.
+ *
+ * @jmx.managed-attribute
+ */
+ public String getDatabasePath()
+ {
+ if (dbPath != null)
+ {
+ return dbPath.toString();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @return the <code>inMemoryMode</code> flag.
+ *
+ * @jmx.managed-attribute
+ */
+ public boolean isInMemoryMode()
+ {
+ return inMemoryMode;
+ }
+
+ /**
+ * If <b>true</b> the h2 is in memory mode otherwise embedded mode.
+ *
+ * @param b in memory mode.
+ *
+ * @jmx.managed-attribute
+ */
+ public void setInMemoryMode( boolean b )
+ {
+ inMemoryMode = b;
+ }
+
+ /**
+ * @return the password
+ *
+ * @jmx.managed-attribute
+ */
+ public String getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * @return the user
+ *
+ * @jmx.managed-attribute
+ */
+ public String getUser()
+ {
+ return user;
+ }
+
+ /**
+ * @return the flags
+ *
+ * @jmx.managed-attribute
+ */
+ public String getFlags()
+ {
+ return flags;
+ }
+
+ /**
+ * @param password
+ *
+ * @jmx.managed-attribute
+ */
+ public void setPassword(String password)
+ {
+ if (password == null)
+ {
+ password = DEFAULT_PASSWORD;
+ }
+ this.password = password;
+ }
+
+ /**
+ * @param user
+ *
+ * @jmx.managed-attribute
+ */
+ public void setUser(String user)
+ {
+ if (user == null)
+ {
+ user = DEFAULT_USER;
+ }
+ this.user = user;
+ }
+
+ /**
+ * @param flags
+ *
+ * @jmx.managed-attribute
+ */
+ public void setFlags(String flags)
+ {
+ if (flags == null)
+ {
+ flags = DEFAULT_FLAGS;
+ }
+ this.flags = flags;
+ }
+
+ /**
+ * @return the serverMode
+ *
+ * @jmx.managed-attribute
+ */
+ public boolean isServerMode()
+ {
+ return serverMode;
+ }
+
+ /**
+ * @param serverMode
+ *
+ * @jmx.managed-attribute
+ */
+ public void setServerMode( boolean serverMode )
+ {
+ this.serverMode = serverMode;
+ }
+
+ /**
+ * @return the address
+ *
+ * @jmx.managed-attribute
+ */
+ public String getBindAddress()
+ {
+ return address;
+ }
+
+ /**
+ * @return the port
+ *
+ * @jmx.managed-attribute
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * @param address
+ *
+ * @jmx.managed-attribute
+ */
+ public void setBindAddress(String address)
+ {
+ this.address = address;
+ }
+
+ /**
+ * @param port
+ *
+ * @jmx.managed-attribute
+ */
+ public void setPort(int port)
+ {
+ this.port = port;
+ }
+
+ /**
+ * Set the delay for remote hypersonic initialisation.
+ *
+ * @jmx.managed-attribute
+ */
+ public void setDelay(final long delay)
+ {
+ this.delay = delay;
+ }
+
+ /**
+ * Get the delay for remote hypersonic initialisation.
+ *
+ * @jmx.managed-attribute
+ */
+ public long getDelay()
+ {
+ return delay;
+ }
+
+ // Lifecycle -----------------------------------------------------
+
+ /**
+ * Start the database
+ */
+ protected void startService() throws Exception
+ {
+ if (serverMode)
+ {
+ startRemoteDatabase();
+ }
+ else if (inMemoryMode)
+ {
+ startInMemoryDatabase();
+ }
+ else
+ {
+ startStandaloneDatabase();
+ }
+ }
+
+ /**
+ * We now close the connection clean by calling the
+ * serverSocket throught jdbc. The MBeanServer calls this
+ * method at closing time.
+ */
+ protected void stopService() throws Exception
+ {
+ if (serverMode)
+ {
+ stopRemoteDatabase();
+ }
+ else if (inMemoryMode)
+ {
+ stopInMemoryDatabase();
+ }
+ else
+ {
+ stopStandaloneDatabase();
+ }
+ }
+
+ // Private -------------------------------------------------------
+
+ /**
+ * Start the standalone (in process) database.
+ */
+ private void startStandaloneDatabase() throws Exception
+ {
+ final File h2Dir = checkDataDir() ;
+
+ dbPath = new File(h2Dir, name);
+
+ final String dbURL = JDBC_URL_PREFIX + dbPath.toURI().toString() + flags ;
+ log.info(dbURL);
+
+ // Check we have connectivity
+ connection = getConnection(dbURL);
+ }
+
+ /**
+ * Start the only in memory database.
+ */
+ private void startInMemoryDatabase() throws Exception
+ {
+ final String dbURL = JDBC_MEM_URL_PREFIX + name + flags ;
+
+ // hold a connection so h2 does not close the database
+ connection = getConnection(dbURL);
+ }
+
+ /**
+ * Start a remote/server database
+ * @throws Exception
+ */
+ private void startRemoteDatabase() throws Exception
+ {
+ final File h2Dir = checkDataDir() ;
+ dbPath = new File(h2Dir, name);
+
+ // Start DB in new thread, or else it will block us
+ serverThread = new Thread("h2-" + name)
+ {
+ public void run()
+ {
+ try
+ {
+ log.debug( "Starting remote h2 db with port : " + port );
+ final String[] args = new String[] {
+ "-baseDir", dbPath.getAbsolutePath(),
+ "-tcpPort", String.valueOf(port),
+ "-tcpAllowOthers","" }; // need the extra empty
string or a exception is thrown by H2
+ final Server server = Server.createTcpServer(args) ;
+ server.start() ;
+ setRemoteServer(server);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to start database", e);
+ }
+ }
+ };
+
+ serverThread.start();
+
+ if (delay > 0)
+ {
+ log.debug("Waiting for Database initialisation: maximum " + delay +
" milliseconds") ;
+ try
+ {
+ serverThread.join(delay) ;
+ }
+ catch (final InterruptedException ie)
+ {
+ Thread.currentThread().interrupt() ;
+ }
+
+ if (serverThread.isAlive())
+ {
+ log.warn("Database initialisation is still active") ;
+ }
+ else
+ {
+ log.debug("Database initialisation completed") ;
+ }
+ }
+ }
+
+ /**
+ * Stop the standalone (in process) database.
+ */
+ private void stopStandaloneDatabase() throws Exception
+ {
+ try
+ {
+ final Statement stmt = connection.createStatement() ;
+ stmt.execute("shutdown") ;
+ }
+ finally
+ {
+ connection = null;
+ }
+ log.info("Database standalone closed clean");
+ }
+
+ /**
+ * Stop the in memory database.
+ */
+ private void stopInMemoryDatabase() throws Exception
+ {
+ try
+ {
+ connection.close() ;
+ }
+ finally
+ {
+ connection = null;
+ }
+ log.info("Database in memory closed clean");
+ }
+
+ /**
+ * Stop the remote database.
+ */
+ private void stopRemoteDatabase() throws SQLException
+ {
+ final Server server = getRemoteServer() ;
+ if (server != null)
+ {
+ server.stop() ;
+ }
+ }
+
+ /**
+ * Set the remote server instance.
+ * @param remoteServer The remote server instance.
+ */
+ private synchronized void setRemoteServer(final Server remoteServer)
+ {
+ this.remoteServer = remoteServer ;
+ }
+
+ /**
+ * Get the remote server instance.
+ * @return The remote server instance.
+ */
+ private synchronized Server getRemoteServer()
+ {
+ return remoteServer ;
+ }
+
+ /**
+ * Get the connection.
+ *
+ * @param dbURL jdbc url.
+ * @return the connection, allocate one if needed.
+ * @throws Exception
+ */
+ private synchronized Connection getConnection(String dbURL) throws Exception
+ {
+ if (connection == null)
+ {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ Class.forName(JDBC_DRIVER_CLASS, true, cl).newInstance();
+ connection = DriverManager.getConnection(dbURL, user, password);
+ }
+ return connection;
+ }
+
+ /**
+ * Check the existence of the h2 data directory.
+ * @return The h2 data directory.
+ * @throws IOException For errors checking/creating the h2 data directory.
+ */
+ private File checkDataDir() throws IOException
+ {
+ // Get the server data directory
+ final File dataDir = getDataDir();
+
+ // Get DB directory
+ final File h2Dir = new File(dataDir, H2_DATA_DIR);
+
+ if (!h2Dir.exists())
+ {
+ h2Dir.mkdirs();
+ }
+ else if (!h2Dir.isDirectory())
+ {
+ throw new IOException("Failed to create directory: " + h2Dir);
+ }
+ return h2Dir ;
+ }
+
+ File getDataDir()
+ {
+ if (datadir == null)
+ {
+ final ServerConfig serverConfig = (ServerConfig)
MBeanProxyExt.create(ServerConfig.class, ServerConfigImplMBean.OBJECT_NAME);
+ return serverConfig.getServerDataDir();
+ }
+ return new File(datadir);
+ }
+
+ public void setDataDir(String datadir)
+ {
+ this.datadir = datadir;
+ }
+
+}
Added:
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/db/H2DatabaseMBean.java
===================================================================
--- trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/db/H2DatabaseMBean.java
(rev 0)
+++
trunk/runtime/engine/src/main/java/org/jboss/soa/bpel/runtime/db/H2DatabaseMBean.java 2009-11-17
15:07:35 UTC (rev 276)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.soa.bpel.runtime.db;
+
+import javax.management.ObjectName;
+
+import org.jboss.mx.util.ObjectNameFactory;
+import org.jboss.system.ServiceMBean;
+
+/**
+ * MBean interface.
+ *
+ * In all cases we run h2 in the same VM with JBoss.
+ * A few notes on h2 running modes:
+ *
+ * remote (server) mode
+ * h2 can be connected to vid tcp
+ *
+ * in-process (standalone) mode
+ * h2 can only be contacted from in-vm clients
+ *
+ * memory-only mode
+ * h2 will only keep tables in memory, no persistence of data
+ *
+ * @version $Revision: 27106 $
+ */
+public interface H2DatabaseMBean extends ServiceMBean
+{
+ /** The default ObjectName */
+ ObjectName OBJECT_NAME = ObjectNameFactory.create("jboss:service=h2");
+
+ // Attributes ----------------------------------------------------
+
+ /** The database name, default is 'default' */
+ String getDatabase();
+ void setDatabase(String name);
+
+ /** The default user to use when connecting to the DB, default is "sa" */
+ String getUser();
+ void setUser(String user);
+
+ /** The default password to use when connecting to the DB, default is "" */
+ String getPassword();
+ void setPassword(String password);
+
+ /** The full database path */
+ String getDatabasePath();
+
+ /** In memory mode */
+ boolean isInMemoryMode() ;
+ void setInMemoryMode(boolean b) ;
+
+ /** Server/remote mode */
+ boolean isServerMode() ;
+ void setServerMode(boolean mode) ;
+
+ /** The flags to use when connecting to the DB, default is "" */
+ String getFlags();
+ void setFlags(String flags);
+
+ /** The listening port when in remove server mode, default is '9092' */
+ int getPort();
+ void setPort(int port);
+
+ /** The binding address, default is '0.0.0.0' */
+ String getBindAddress();
+ void setBindAddress(String address);
+
+ /** Set the dir that will be used by the database. */
+ void setDataDir(final String datadir);
+}