You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by tb...@apache.org on 2004/05/06 02:01:40 UTC

cvs commit: avalon-components/facilities/db/hsql/src/java/org/apache/avalon/db/hsql HsqlServer.java HsqlServiceProvider.java

tbennett    2004/05/05 17:01:40

  Added:       facilities/db/hsql/src/java/org/apache/avalon/db/hsql
                        HsqlServer.java HsqlServiceProvider.java
  Log:
  HSQL component update
  
  Revision  Changes    Path
  1.1                  avalon-components/facilities/db/hsql/src/java/org/apache/avalon/db/hsql/HsqlServer.java
  
  Index: HsqlServer.java
  ===================================================================
  /* 
   * Copyright 2004 Apache Software Foundation
   * 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.apache.avalon.db.hsql;
  
  import java.io.IOException;
  import java.io.InterruptedIOException;
  import java.net.InetAddress;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.sql.SQLException;
  
  import org.apache.avalon.framework.logger.Logger;
  import org.hsqldb.HsqlServerFactory;
  import org.hsqldb.HsqlSocketRequestHandler;
  
  import EDU.oswego.cs.dl.util.concurrent.ThreadedExecutor;
  
  /**
   * This is a database server facility for the HypersonicSQL database.
   *
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2004/05/06 00:01:40 $
   */
  public class HsqlServer {
      /**
       * TCP listening socket backlog.
       */
      private static final int BACKLOG = 50;
      /**
       * Default host name to bind the HSQL database server TCP socket
       * to.  The default value is the localhost, that is 127.0.0.1.
       */
      private static final String DEFAULT_HOST = "127.0.0.1";
      //---------------------------------------------------------
      // static
      //---------------------------------------------------------
  
      /**
       * Default HSQL database server TCP socket listening port.
       * The default value is the HSQL standard port 9001.
       */
      private static final int DEFAULT_PORT = 9001;
      /**
       * TCP listening socket connection timeout (msecs).
       */
      private static final int TIMEOUT = 500;
      /**
       * Flag indicating if the HSQL database server will operate in
       * a debug logging mode.
       */
      private boolean m_debug;
      /**
       * Host to bind the database TCP/IP listener to. Default is localhost.
       */
      private InetAddress m_host;
      /**
       * The HSQLDB database server and socket request handler.
       */
      private HsqlSocketRequestHandler m_hsqlSocketRequestHandler;
  
      //---------------------------------------------------------
      // immutable state
      //---------------------------------------------------------
  
      /**
       * The logging channel for this component.
       */
      private final Logger m_logger;
  
      //---------------------------------------------------------
      // state
      //---------------------------------------------------------
      
      /**
       * Alias of the HSQL database server.
       */
      private String m_name;
      /**
       * TCP listening port of the HSQL database server.
       */
      private int m_port;
      /**
       * Main thread managing the server connection socket.
       */
      private Thread m_serverSocketThread;
      /**
       * Flag indicating if the HSQL database server will operate in
       * a silent logging mode.
       */
      private boolean m_silent;
  
      /**
       * Creates a new instance of an <code>HsqlServer</code> object.
       * 
       * @param name alias of the HSQL database server instance
       * @param port listening port of the HSQL database server
       * @param host <code>InetAddress</code> to bind the HSQL database
       * server to
       * @param debug if <b>true</b>, the HSQL database server will be
       * started in debug mode
       * @param silent if <b>true</b>, the HSQL database server will
       * operate in a silent logging mode
       */
      public HsqlServer( String name,
                         int port,
                         InetAddress host,
                         boolean debug,
                         boolean silent,
                         Logger logger)
      {
          logger.info("Entering constructor");
          
          m_name = name;
          m_port = port;
          m_host = host;
          m_debug = debug;
          m_silent = silent;
          m_logger = logger;
  
          logger.info("Exiting constructor");
      }
  
      /**
       * Starts the socket server and hands off connections to
       * the thread pool for processing by a worker thread.
       * 
       * @param serverSocket the serverSocket to manage
       */
      private void runServer( ServerSocket serverSocket ) 
      {
          if ( m_logger.isInfoEnabled() ) 
          {
              m_logger.info( "Running database connection server..." );
          }
          
          ThreadedExecutor runner = new ThreadedExecutor();
          try 
          {
              // accept connections until this thread is interrupted...
              while ( !Thread.interrupted() ) 
              {
                  try
                  {
                      // when a connection is made, spin off a thread to
                      // process the connection, and immediately go back to
                      // listening for other connections
                      final Socket connection = serverSocket.accept();
                      runner.execute( 
                         new Runnable() {
                            public void run() {
                               // who connected to us?
                               final String remoteHost = 
                                  connection.getInetAddress().getHostName();
                               final String remoteIP = 
                                  connection.getInetAddress().getHostAddress();
                              
                               // hand-off the socket connection to HSQLDB...
                               m_hsqlSocketRequestHandler.handleConnection( connection );
  
                               if ( m_logger.isDebugEnabled() ) {
                                  final String message = 
                                    "database connection from " 
                                    + remoteHost 
                                    + " (" 
                                    + remoteIP 
                                    + ")";
                                  m_logger.debug( message );
                               }
                            }
                         }
                      );
                  } 
                  catch ( InterruptedIOException iioe )
                  {
                      // Ignore these - thrown when accept() times out
                  }
                  catch ( Exception e ) 
                  {
                      // IOException - if an I/O error occurs when waiting 
                      // for a connection.
                      // SecurityException - if a security manager exists 
                      // and its checkListen method doesn't allow the operation.
                      if ( m_logger.isWarnEnabled() ) 
                      {
                          m_logger.warn( e.getMessage(), e );
                      }
                  }
              }
          } 
          finally 
          {
              if ( runner != null ) 
              {
                  runner = null;
              }
              if ( serverSocket != null ) 
              {
                  try 
                  {
                      serverSocket.close();
                  } 
                  catch ( IOException ignore ) 
                  {
                      // ignore...
                  }
                  serverSocket = null;
              }
          }
      }
  
      /**
       * Starts the HSQL database server instance.
       * 
       * @throws Exception if an error occurs while starting the server
       */
      public void startServer() throws Exception
      {
          m_logger.info("Entering startServer()");
          
          // create the HSQLDB server and socket request handler
          try 
          {
              m_hsqlSocketRequestHandler = 
                HsqlServerFactory.createHsqlServer( m_name, m_debug, m_silent );
          } 
          catch ( SQLException sqle ) 
          {
              if ( m_logger.isErrorEnabled() ) 
              {
                  final String error = 
                    "Error starting HSQL database: " 
                    + sqle.getMessage();
                  m_logger.error( error, sqle );
              }
              throw sqle;
          }
          
          m_logger.info("Waypoint 1");
          
          // start up primary socket server 
          final ServerSocket serverSocket = new ServerSocket( m_port,
              BACKLOG, m_host );
          m_logger.info("Waypoint 2");
          serverSocket.setSoTimeout( TIMEOUT );
          m_serverSocketThread = 
            new Thread( new Runnable() {
              public void run()
              {
                  runServer( serverSocket );
              }
            } );
          m_logger.info("Waypoint 3");
          m_serverSocketThread.start();
          m_logger.info("Waypoint 4");
          
          if ( m_logger.isInfoEnabled() ) 
          {
              m_logger.info( "Hypersonic SQL listening on port " + m_port );
          }
          
          m_logger.info("Exiting startServer()");
      }
      
      /**
       * Shuts down the HSQL database server instance.
       * 
       * @throws Exception if an error occurs while shutting down the server
       */
      public void stopServer() throws Exception
      {
          // tell HSQLDB that all connections are being shutdown...
          if ( m_hsqlSocketRequestHandler != null ) 
          {
              m_hsqlSocketRequestHandler.signalCloseAllServerConnections();
          }
          
          // shutdown server socket...
          if ( m_serverSocketThread != null ) 
          {
              m_serverSocketThread.interrupt();
          }
      }
  }
  
  
  
  1.1                  avalon-components/facilities/db/hsql/src/java/org/apache/avalon/db/hsql/HsqlServiceProvider.java
  
  Index: HsqlServiceProvider.java
  ===================================================================
  /* 
   * Copyright 2004 Apache Software Foundation
   * 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.apache.avalon.db.hsql;
  
  import java.io.File;
  import java.net.InetAddress;
  import java.net.UnknownHostException;
  
  import org.apache.avalon.db.DatabaseService;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.logger.Logger;
  
  
  /**
   * Database service provider implementing an embedded HypersonicSQL
   * database server.
   *
   * @avalon.component name="server" lifestyle="singleton"
   * @avalon.service type="org.apache.avalon.db.DatabaseService"
   * 
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2004/05/06 00:01:40 $
   */
  public class HsqlServiceProvider implements Contextualizable,
      Configurable, Initializable, Startable, DatabaseService
  {
  
      //---------------------------------------------------------
      // static
      //---------------------------------------------------------
  
      /**
       * Default HSQL database server TCP socket listening port.
       * The default value is the HSQL standard port 9001.
       */
      private static final int DEFAULT_PORT = 9001;
      /**
       * Default host name to bind the HSQL database server TCP socket
       * to.  The default value is the localhost, that is 127.0.0.1.
       */
      private static final String DEFAULT_HOST = "127.0.0.1";
      
      //---------------------------------------------------------
      // immutable state
      //---------------------------------------------------------
  
      /**
       * The logging channel for this component.
       */
      private final Logger m_logger;
      
      //---------------------------------------------------------
      // state
      //---------------------------------------------------------
  
      /**
       * HSQL server wrapper object.
       */
      private HsqlServer m_server;
      /**
       * The working base directory.
       */
      private File m_basedir;
      /**
       * Listening port for database connections. Default is 9001;
       */
      private int m_port;
      /**
       * Host to bind the database TCP/IP listener to. Default is localhost.
       */
      private InetAddress m_host;
      /**
       * Fully qualified filepath to the database file artifacts.
       */
      private File m_dbName;
      /**
       * Run the HSQLDB server in debug mode?
       */
      private boolean m_dbDebug;
      /**
       * Run the HSQLDB server silently?
       */
      private boolean m_dbSilent;
  
      //---------------------------------------------------------
      // constructor
      //---------------------------------------------------------
  
      /**
       * Creates a new instance of the HSQL database server with the
       * logging channel supplied by the container.
       *
       * @param logger the container-supplied logging channel
       */
      public HsqlServiceProvider( final Logger logger )
      {
          m_logger = logger;
      }
  
      //---------------------------------------------------------
      // Contextualizable
      //---------------------------------------------------------
  
     /**
      * Contextualization of the server by the container.
      *
      * @param context the supplied server context
      * @exception ContextException if a contextualization error occurs
      * @avalon.entry key="urn:avalon:home" type="java.io.File"
      */
      public void contextualize( final Context context )
        throws ContextException
      {
          // cache the working base directory
          m_basedir = getBaseDirectory( context );
      }
  
      //---------------------------------------------------------
      // Configurable
      //---------------------------------------------------------
  
      /**
       * Configuration of the server by the container.
       *
       * @param config the supplied server configuration
       * @exception ConfigurationException if a configuration error occurs
       */
      public void configure( final Configuration config )
        throws ConfigurationException
      {
          // get the database listening port/host
          m_port = config.getChild( "port" ).getValueAsInteger( DEFAULT_PORT );
          String host = config.getChild( "host" ).getValue( DEFAULT_HOST );
          try
          {
              m_host = InetAddress.getByName( host );
          }
          catch ( UnknownHostException uhe )
          {
              if ( getLogger().isErrorEnabled() )
              {
                  getLogger().error(
                    "Error configuring HSQLDB component: "
                      + uhe.getMessage(),
                    uhe );
              }
              throw new ConfigurationException( uhe.getMessage(), uhe );
          }
  
          // get the HSQLDB server parameters...
          m_dbName = new File( m_basedir,
              config.getChild( "db-name" ).getValue( "avalon-hsqldb" ) );
          m_dbDebug = config.getChild( "debug" ).getValueAsBoolean( false );
          m_dbSilent = config.getChild( "silent" ).getValueAsBoolean( true );
      }
  
      //---------------------------------------------------------
      // Initializable
      //---------------------------------------------------------
  
      /**
       * Initialization of the component by the container.
       * 
       * @throws Exception if an error occurs while initializing
       * the component
       */
      public void initialize() throws Exception {
          m_server = new HsqlServer( m_dbName.getAbsolutePath(),
                  m_port, m_host, m_dbDebug, m_dbSilent, m_logger );
      }
  
      //---------------------------------------------------------
      // Startable
      //---------------------------------------------------------
  
      /**
       * Start the server.
       * 
       * @throws Exception if an error occurs while starting the 
       * component
       */
      public void start() throws Exception {
          m_logger.info("Entering start()");
          if (m_server != null) {
              m_server.startServer();
          } else {
              throw new Exception("Server instance not instantiated!!");
          }
          m_logger.info("Exiting start()");
      }
  
      /**
       * Stop the server.
       * 
       * @throws Exception if an error occurs while stopping the component
       */
      public void stop() throws Exception {
          m_logger.info("Entering stop()");
          m_server.stopServer();
          m_logger.info("Exiting stop()");
      }
  
      /**
       * Return the working base directory.
       * 
       * @param context the supplied server context
       * @return a <code>File</code> object representing the working
       * base directory
       * @exception ContextException if a contextualization error occurs
       */
      private File getBaseDirectory( final Context context ) 
        throws ContextException 
      {
          File home = (File) context.get( "urn:avalon:home" );
          if ( !home.exists() )
          {
              boolean success = home.mkdirs();
              if ( !success )
              {
                  throw new ContextException( "Unable to create component "
                      + "home directory: " + home.getAbsolutePath() );
              }
          }
          if ( getLogger().isInfoEnabled() )
          {
              getLogger().info( "Setting home directory to: " + home );
          }
          return home;
      }
      
     /**
      * Return the assigned logging channel.
      * @return the logging channel
      */
      private Logger getLogger()
      {
          return m_logger;
      }
  
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org