You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by le...@apache.org on 2001/04/05 21:10:13 UTC
cvs commit: jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/facilities Facility.java
leosimons 01/04/05 12:10:13
Added: proposal/4.0/src/java/org/apache/phoenix Restart.java
Shutdown.java Start.java
proposal/4.0/src/java/org/apache/phoenix/applications
Application.java ApplicationException.java
ServerApplication.java
proposal/4.0/src/java/org/apache/phoenix/core Block.java
BlockContext.java Embeddor.java Kernel.java
ServerKernel.java
proposal/4.0/src/java/org/apache/phoenix/engine
PhoenixEmbeddor.java PhoenixKernel.java
proposal/4.0/src/java/org/apache/phoenix/engine/applications
DefaultServerApplication.java
ServerApplicationFactory.java
proposal/4.0/src/java/org/apache/phoenix/engine/deployer
DefaultSarDeployer.java
proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks
BlockDAG.java BlockEntry.java BlockVisitor.java
DefaultBlockContext.java DefaultBlockDeployer.java
RoleEntry.java
proposal/4.0/src/java/org/apache/phoenix/engine/facilities
ApplicationManager.java ClassLoader.java
ConfigurationManager.java LogManager.java
SecurityManager.java ThreadManager.java
proposal/4.0/src/java/org/apache/phoenix/engine/jmx
Manager.java
proposal/4.0/src/java/org/apache/phoenix/facilities
Facility.java
Log:
Creating a proposal structure for version 4 of phoenix. Phoenix 4 is ment
to work with version 4 of the framework, include jmx support, use an
embeddor to talk with the environment as detailed in the JSF JSR and
generally be a lot cleaner than the current setup.
A detailed changes.txt will be written once the first version of this
proposal stabilises.
Revision Changes Path
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/Restart.java
Index: Restart.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix;
/**
* Class to restart phoenix. Call to restart the server.
*
* @author <a href="mail@leosimons.com">Leo Simons</a>
*/
public class Restart {
public Restart() {
(new Start()).restart();
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/Shutdown.java
Index: Shutdown.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix;
/**
* Class to exit phoenix. Call to shut down the server.
*
* @author <a href="mail@leosimons.com">Leo Simons</a>
*/
public class Shutdown {
public Shutdown() {
(new Start()).shutdown();
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/Start.java
Index: Start.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.management.MBeanServer;
import org.apache.framework.context.Context;
import org.apache.framework.context.DefaultContext;
import org.apache.framework.container.Entry;
import org.apache.framework.configuration.Configuration;
import org.apache.framework.configuration.DefaultConfiguration;
import org.apache.framework.configuration.ConfigurationException;
import org.apache.framework.lifecycle.Disposable;
import org.apache.avalon.component.DefaultComponentManager;
import org.apache.phoenix.core.Embeddor;
import org.apache.phoenix.engine.PhoenixEmbeddor;
/**
* Entry point to phoenix. Call to start the server.
// TODO: list available arguments
*
* @author <a href="mail@leosimons.com">Leo Simons</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
*/
public class Start implements Disposable
{
// embeddor
private static Embeddor embeddor;
// embeddor configuration settings
private static String embeddorClass;
private static final String DEFAULT_EMBEDDOR_CLASS =
"org.apache.phoenix.engine.PhoenixEmbeddor";
private static String deployerClass;
private static final String DEFAULT_DEPLOYER_CLASS =
"org.apache.phoenix.engine.DefaultSarDeployer";
private static String mBeanServerClass;
private static final String DEFAULT_MBEANSERVER_CLASS =
"org.apache.jmx.MBeanServerImpl";
private static String kernelClass;
private static final String DEFAULT_KERNEL_CLASS =
"org.apache.phoenix.engine.DefaultKernel";
private static String configurationSource;
private static final String DEFAULT_CONFIGURATION_SOURCE = "../conf/server.xml";
// monitor these for status changes
private static boolean singleton = false;
private static boolean shutdown = false;
private static boolean restart = false;
// command line options
private static final int DEBUG_LOG_OPT = 'd';
private static final int HELP_OPT = 'h';
private static final int LOG_FILE_OPT = 'l';
private static final int APPS_PATH_OPT = 'a';
/**
* Entry-point into Phoenix. See the class description for a list of the possible
* arguments.
*/
public void main( final String[] args )
{
if( singleton )
{
System.out.println( "Sorry, an instance of phoenix is already running. Phoenix cannot be run multiple times in the same VM." );
System.exit( 1 );
}
singleton = true;
final Start start = new Start();
try
{
start.execute( args );
}
catch( final Throwable throwable )
{
System.out.println( "There was an uncaught exception:" );
System.out.println( "---------------------------------------------------------" );
System.out.println( throwable.toString() );
System.out.println( "---------------------------------------------------------" );
System.out.println( "Please check the configuration files and restart phoenix." );
System.out.println( "If the problem persists, contact the Avalon project. See" );
System.out.println( "http://jakarta.apache.org/avalon for more information." );
System.exit( 1 );
}
}
/////////////////////////
/// LIFECYCLE METHODS ///
/////////////////////////
/**
* Shuts down and immediately restarts the server using the
* same settings.
*/
public void restart()
{
this.restart = true;
}
/**
* Shuts down the server.
*/
public void dispose()
{
this.shutdown = true;
}
/////////////////////////
/// EXECUTION METHODS ///
/////////////////////////
private void execute( final String[] args ) throws Exception
{
try
{
final PrivilegedExceptionAction action = new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
exec( args );
return null;
}
};
AccessController.doPrivileged( action );
}
catch( final PrivilegedActionException pae )
{
// only "checked" exceptions will be "wrapped" in a PrivilegedActionException.
throw pae.getException();
}
}
private void exec( final String[] args ) throws Exception
{
this.parseCommandLineOptions( args );
this.createEmbeddor();
final DefaultContext ctx = new DefaultContext();
ctx.put( "kernel-class", this.kernelClass );
ctx.put( "deployer-class", this.deployerClass );
ctx.put( "mBeanServer-class", this.mBeanServerClass );
ctx.put( "kernel-configuration-source", this.configurationSource );
ctx.put( "log-destination", "../log/phoenix.log" );
final Configuration conf = new DefaultConfiguration("phoenix","localhost");
// run Embeddor lifecycle
this.embeddor.contextualize(ctx);
this.embeddor.configure(conf);
this.embeddor.init();
while( !this.shutdown )
{
while( !this.restart )
{
this.embeddor.run();
}
this.embeddor.restart();
this.restart = false;
}
embeddor.dispose();
System.exit( 0 );
}
//////////////////////
/// HELPER METHODS ///
//////////////////////
private void parseCommandLineOptions( final String[] args )
{
// start with the defaults
this.mBeanServerClass = this.DEFAULT_MBEANSERVER_CLASS;
this.kernelClass = this.DEFAULT_KERNEL_CLASS;
this.embeddorClass = this.DEFAULT_EMBEDDOR_CLASS;
this.deployerClass = this.DEFAULT_DEPLOYER_CLASS;
this.configurationSource = this.DEFAULT_CONFIGURATION_SOURCE;
// TODO: update code below to set the code above
// setup parser and get arguments
final CLOptionDescriptor[] clOptionsDescriptor = createCommandLineOptions();
final CLArgsParser parser = new CLArgsParser( args, clOptionsDescriptor );
if( null != parser.getErrorString() )
{
System.err.println( "Error: " + parser.getErrorString() );
return;
}
final List clOptions = parser.getArguments();
final int size = clOptions.size();
boolean debugLog = false;
// parse options
for( int i = 0; i < size; i++ )
{
final CLOption option = (CLOption)clOptions.get( i );
switch( option.getId() )
{
case 0:
System.err.println( "Error: Unknown argument" + option.getArgument() );
//fall threw
case HELP_OPT:
usage();
return;
case DEBUG_LOG_OPT: debugLog = true; break;
case LOG_FILE_OPT: m_logFile = option.getArgument(); break;
case APPS_PATH_OPT: m_appsPath = option.getArgument(); break;
}
}
if( !debugLog ) LogKit.setGlobalPriority( Priority.DEBUG );
}
protected CLOptionDescriptor[] createCommandLineOptions()
{
//TODO: localise
final CLOptionDescriptor options[] = new CLOptionDescriptor[ 4 ];
options[0] =
new CLOptionDescriptor( "help",
CLOptionDescriptor.ARGUMENT_DISALLOWED,
HELP_OPT,
"display this help" );
options[1] =
new CLOptionDescriptor( "log-file",
CLOptionDescriptor.ARGUMENT_REQUIRED,
LOG_FILE_OPT,
"the name of log file." );
options[2] =
new CLOptionDescriptor( "apps-path",
CLOptionDescriptor.ARGUMENT_REQUIRED,
APPS_PATH_OPT,
"the path to apps/ directory that contains .sars" );
options[3] =
new CLOptionDescriptor( "debug-init",
CLOptionDescriptor.ARGUMENT_DISALLOWED,
DEBUG_LOG_OPT,
"use this option to specify enable debug " +
"initialisation logs." );
return options;
}
protected void usage(List commandLineOptions)
{
System.out.println( "java " + getClass().getName() + " [options]" );
System.out.println( "\tAvailable options:");
System.out.println( CLUtil.describeOptions( commandLineOptions ) );
}
private void createEmbeddor() throws ConfigurationException
{
try
{
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
this.embeddor = (Embeddor)Class.forName( this.embeddorClass ).newInstance();
}
catch( final Exception e )
{
throw new ConfigurationException( "Failed to create Embeddor of class " +
this.embeddorClass, e );
}
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/applications/Application.java
Index: Application.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.applications;
import org.apache.framework.lifecycle.Disposable;
import org.apache.framework.lifecycle.Initializable;
import org.apache.framework.lifecycle.Startable;
import org.apache.framework.lifecycle.Stoppable;
import org.apache.avalon.camelot.Container;
/**
* The Application is a self-contained component that performs a specific
* function.
*
* Example ServerApplications may be a Mail Server, File Server, Directory Server etc.
* Example JesktopApplications may be a Spreadsheet program, browser, mail client
* Example WebApplications may be a particular website or application within a website
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface Application
extends Initializable, Startable, Stoppable, Disposable, Container
{
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/applications/ApplicationException.java
Index: ApplicationException.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.applications;
import org.apache.framework.CascadingException;
/**
* The ApplicationException is used to indicate problems with applications.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class ApplicationException
extends CascadingException
{
public ApplicationException( final String message )
{
this( message, null );
}
public ApplicationException( final String message, final Throwable throwable )
{
super( message, throwable );
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/applications/ServerApplication.java
Index: ServerApplication.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.applications;
import org.apache.framework.context.Contextualizable;
import org.apache.framework.configuration.Configurable;
/**
* The ServerApplication is a self-contained server component that performs a specific
* user function.
*
* Example ServerApplications may be a Mail Server, File Server, Directory Server etc.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface ServerApplication
extends Application, Contextualizable, Configurable
{
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/Block.java
Index: Block.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.core;
import org.apache.framework.component.Component;
/**
* The main interface to implement for building servers using Avalon patterns.
*
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
*/
public interface Block
extends Component
{
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/BlockContext.java
Index: BlockContext.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.core;
import java.io.File;
import org.apache.framework.context.Context;
import org.apache.avalon.thread.ThreadPool;
import org.apache.log.Logger;
/**
* Context via which Blocks communicate with container.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface BlockContext
extends Context
{
String APP_NAME = "app.name";
String APP_HOME_DIR = "app.home";
String NAME = "block.name";
/**
* Base directory of .sar application.
*
* @return the base directory
*/
File getBaseDirectory();
/**
* Retrieve name of block.
*
* @return the name of block
*/
String getName();
/**
* Retrieve thread pool by category.
* ThreadPools are given names so that you can manage different thread
* count to different components.
*
* @param category the category
* @return the ThreadManager
*/
ThreadPool getThreadPool( String category );
/**
* Retrieve default thread pool.
* Equivelent to getThreadPool( "default" );
*
* @return the default ThreadPool
*/
ThreadPool getDefaultThreadPool();
/**
* Retrieve logger coresponding to root category of application.
*
* @return the base logger
*/
Logger getBaseLogger();
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/Embeddor.java
Index: Embeddor.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.core;
import java.lang.Runnable;
import java.lang.UnsupportedOperationException;
import org.apache.framework.context.Contextualizable;
import org.apache.framework.configuration.Configurable;
import org.apache.framework.lifecycle.Initializable;
import org.apache.framework.lifecycle.Disposable;
/**
*
* @author <a href="mail@leosimons.com">Leo Simons</a>
*/
public interface Embeddor
extends Contextualizable, Configurable, Initializable, Runnable, Disposable
{
public void restart() throws UnsupportedOperationException;
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/Kernel.java
Index: Kernel.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.core;
import org.apache.avalon.camelot.ContainerException;
import org.apache.phoenix.applications.Application;
/**
* The Kernel is the core of any system.
* The kernel is responsible for orchestrating low level services
* such as loading, configuring and destroying applications. It also
* gives access to basic facilities specific to that particular kernel.
* A ServerKernel may offer scheduling, naming, security, classloading etc.
* A JesktopKernel may offer inter-application drag-n-drop support.
* A VEKernel may offer inter-VE transport for Avatars.
*
* Note that no facilities are available until after the Kernel has been initialized.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface Kernel
extends Application, Runnable
// and thus extends Initializable, Startable, Stoppable, Disposable, Container, Component
{
/**
* Retrieve Application from container.
* The Application that is returned must be initialized
* and prepared for manipulation.
*
* @param name the name of application
* @return the application
* @exception ContainerException if an error occurs
*/
Application getApplication( String name )
throws ContainerException;
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/core/ServerKernel.java
Index: ServerKernel.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.core;
import org.apache.framework.logger.Loggable;
import org.apache.framework.context.Contextualizable;
/**
* The ServerKernel is the core of the Phoenix system.
* The kernel is responsible for orchestrating low level services
* such as loading, configuring and destroying blocks. It also
* gives access to basic facilities such as scheduling sub-systems,
* protected execution contexts, naming and directory services etc.
*
* Note that no facilities are available until after the Kernel has been
* contextualized, configured and initialized.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface ServerKernel
extends Loggable, Kernel, Contextualizable
// and thus extends Application, Runnable, Initializable, Startable,
// Stoppable, Disposable, Container, Component
{
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/PhoenixEmbeddor.java
Index: PhoenixEmbeddor.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine;
import javax.management.MBeanServer;
import java.io.File;
import org.apache.framework.configuration.Configurable;
import org.apache.framework.context.Contextualizable;
import org.apache.framework.container.Container;
import org.apache.framework.component.Composer;
import org.apache.framework.logger.Loggable;
import org.apache.framework.container.Deployer;
import org.apache.framework.lifecycle.Suspendable;
import org.apache.framework.lifecycle.Resumable;
import org.apache.framework.context.Context;
import org.apache.framework.container.Entry;
import org.apache.framework.configuration.Configuration;
import org.apache.framework.configuration.ConfigurationException;
import org.apache.avalon.camelot.CamelotUtil;
import org.apache.avalon.atlantis.Kernel;
import org.apache.avalon.context.DefaultContext;
import org.apache.avalon.component.DefaultComponentManager;
import org.apache.avalon.configuration.DefaultConfigurationBuilder;
import org.apache.phoenix.engine.facilities.Manager;
import org.apache.log.format.AvalonLogFormatter;
import org.apache.log.output.FileOutputLogTarget;
import org.apache.log.Logger;
import org.apache.log.LogKit;
import org.apache.log.Priority;
import org.apache.log.LogTarget;
/**
*
* @author <a href="mail@leosimons.com">Leo Simons</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
*/
public class DefaultEmbeddor
implements Embeddor
{
private Context context;
private Logger logger;
private Deployer deployer;
private DefaultContext deployerContext;
private Manager manager;
private MBeanServer mBeanServer;
private DefaultContext managerContext;
private Kernel kernel;
private Thread kernelThread;
private DefaultContext kernelContext;
private Configuration kernelConfiguration;
private boolean kernelSupportsSuspend = false;
// monitor these for status changes
private boolean shutdown = false;
private boolean restart = false;
private boolean suspend = false;
private boolean recontextualized = false;
private boolean reconfigured = false;
/////////////////////////
/// LIFECYCLE METHODS ///
/////////////////////////
/**
* Make sure to provide all the neccessary information through
* this context. All information it needs consists of strings.
* These are also indexed using strings. Neccessary are:
* <ul>
* <li><b>kernel-class</b>, the classname of the
* org.apache.phoenix.core.Kernel to be used.</li>
* <li><b>deployer-class</b>, the classname of the
* org.apache.avalon.camelot.Deployer to be used.</li>
* <li><b>mBeanServer-class</b>, the classname of the
* javax.management.MBeanServer to be used.</li>
* <li><b>kernel-configuration-source</b>, the location
* of the configuration file to be used for configuring the
* kernel.</li>
* <li><b>log-destination</b>, the file to save log
* messages in. If omitted, no logs are written.</li>
* <li>TODO: <b>facilities-directory</b>, the directory in
* which the facilities you wish to load into the kernel
* are stored (in .far format).<br />
* When ommited, the default facilities are used.</li>
* <li><b>applications-directory</b>, the directory in which
* the applications to be loaded by the kernel are stored
* (in .sar format).<br />
* When ommited, no applications are loaded.</li>
* </ul>
*/
public void contextualize( Context context )
{
this.context = context;
}
/**
* Currently unused, but Embeddor extends it so call anyway
* using a dummy configuration.
*/
void configure( Configuration configuration )
throws ConfigurationException;
{
// TODO
}
/**
* Creates the core handlers - logger, deployer, Manager and
* Kernel. Note that these are not set up properly until you have
* called the <code>run()</code> method.
*/
public void init()
throws Exception
{
this.createLogger();
try { this.createDeployer(); }
catch( Exception e ) { logger.fatalError("Unable to create deployer!", e);
throw new Exception(e); }
try { this.createManager(); }
catch( Exception e ) { logger.fatalError("Unable to create manager!", e);
throw new Exception(e); }
try { this.createKernel(); }
catch( Exception e ) { logger.fatalError("Unable to create kernel!", e);
throw new Exception(e); }
}
/**
* This is the main method of the embeddor. It sets up the core
* components, and then deploys the <code>Facilities</code>. These
* are registered with the Kernel and the Manager. The same
* happens for the <code>Applications</code>.
* Now, the Kernel is taken through its lifecycle. When it is
* finished, as well as all the applications running in it, it
* is shut down, after which the PhoenixEmbeddor is as well.
*/
public void run()
{
this.setupLogger();
try { this.setupDeployer(); }
catch( Exception e ) { logger.fatalError("Unable to setup deployer!", e);
System.exit( 1 ); }
try { this.setupManager(); }
catch( Exception e ) { logger.fatalError("Unable to setup manager!", e);
System.exit( 1 ); }
try { this.setupKernel(); }
catch( Exception e ) { logger.fatalError("Unable to setup kernel!", e);
System.exit( 1 ); }
try
{
kernel.start();
while( !this.shutdown )
{
while( !this.restart && !this.suspend )
{
kernel.run();
try { synchronized( this ) { wait(); } }
catch (InterruptedException e) {}
}
if( this.restart )
{
handleRestart();
}
else if( this.suspend )
{
handleSuspend();
}
}
handleDispose();
}
catch ( Exception e )
{
// whoops!
this.logger.fatalError("There was a fatal error while running phoenix.", e );
System.exit( 1 );
}
}
/**
* This stops and then restarts the Embeddor,
* re-creating the logger, deployer, Manager
* and Kernel in the process.
*/
public void restart()
{
this.restart = true;
}
/**
* Shut down the Embeddor together with the
* Logger, Deployer, Manager and Kernel.
*/
public void dispose()
{
this.shutdown = true;
}
/**
* Suspend both the Embeddor and its Manager.
* If the Kernel does not support suspend,
* this shuts down the Kernel and all
* Applications running in it. This is not
* recommended!
*/
public void suspend()
{
this.suspend = true;
}
/**
* Resume both the Embeddor and its Manager.
* If the Kernel does not support suspend, it
* has to be re-created and re-setup. This
* happens now.
*/
public void resume()
{
try
{
if( this.kernelSupportsSuspend )
{
if( kernel instanceof Resumable )
{
manager.resume();
((Resumable)kernel).resume();
this.suspend = false;
synchronized( this ) { notifyAll(); }
} else
{
// it's stupid if this happens
// but let's handle it anyway...
kernel.stop();
kernel.dispose();
kernel = null;
this.createKernel();
this.setupKernel();
manager.resume();
kernel.start();
this.suspend = false;
synchronized( this ) { notifyAll(); }
}
} else
{
this.createKernel();
this.setupKernel();
manager.resume();
kernel.start();
this.suspend = false;
synchronized( this ) { notifyAll(); }
}
}
catch( Exception e )
{
// this is bad...
logger.fatalError( "A fatal error occured while resuming. Phoenix will exit.", e );
System.exit( 1 );
}
}
//////////////////////
/// HELPER METHODS ///
//////////////////////
private void createLogger() throws ConfigurationException
{
try
{
final FileOutputLogTarget logTarget = new FileOutputLogTarget( (String)this.context.get( "log-destination" ) );
final AvalonLogFormatter formatter = new AvalonLogFormatter();
formatter.setFormat( "%{time} [%7.7{priority}] <<%{category}>> " +
"(%{context}): %{message}\\n%{throwable}" );
logTarget.setFormatter( formatter );
LogKit.addLogTarget( (String)this.context.get( "log-destination" ), logTarget );
this.logger = LogKit.createLogger( LogKit.createCategory( "Phoenix", Priority.DEBUG ),
new LogTarget[] { logTarget } );
this.logger.info( "Loader started" );
}
catch( final Exception e )
{
throw new ConfigurationException( "Failed to create Logger", e );
}
}
private void setupLogger() {}
private void createDeployer() throws ConfigurationException
{
try
{
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
this.deployer = (Deployer)Class.forName( (String)this.context.get( "deployer-class" ) ).newInstance();
this.deployerContext = new DefaultContext();
}
catch( final Exception e )
{
throw new ConfigurationException( "Failed to create Deployer of class " +
(String)this.context.get( "deployer-class" ), e );
}
}
private void setupDeployer() throws Exception
{
if( this.deployer instanceof Loggable )
{
((Loggable)this.deployer).setLogger( this.logger );
}
if( this.deployer instanceof Contextualizable )
{
((Contextualizable)this.deployer).contextualize( (Context)this.deployerContext );
}
if( this.deployer instanceof Composer )
{
final DefaultComponentManager componentManager = new DefaultComponentManager();
componentManager.put( "org.apache.avalon.camelot.Container", (Container)this.kernel );
((Composer)this.deployer).compose( componentManager );
}
final File directory = new File( (String)this.context.get( "default-apps-location" ) );
CamelotUtil.deployFromDirectory( deployer, directory, ".sar" );
// TODO: load facilities from .fars
// final File directory2 = new File( (String)this.context.get( "default-facilities-location" ) );
// CamelotUtil.deployFromDirectory( deployer, directory2, ".far" );
}
private void createManager() throws ConfigurationException
{
try
{
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
this.mBeanServer = (MBeanServer)Class.forName( (String)this.context.get( "mBeanServer-class" ) ).newInstance();
this.managerContext = new DefaultContext();
}
catch( final Exception e )
{
throw new ConfigurationException( "Failed to create MBean Server of class " +
(String)this.context.get( "mBeanServer-class" ), e );
}
}
private void setupManager()
{
this.manager = new Manager( this.mBeanServer );
if( this.manager instanceof Loggable )
{
((Loggable)this.manager).setLogger( this.logger );
}
if( this.manager instanceof Contextualizable )
{
this.managerContext.put( "org.apache.framework.container.Deployer", this.deployer );
/* add references to default facilities so they will be loaded.
TODO: put the facilities in .sars, make the deployer load
those and remove this. */
this.managerContext.put( "org.apache.avalon.atlantis.Facility.ComponentBuilder",
"org.apache.phoenix.engine.facilities.DefaultComponentBuilder" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.ComponentManager",
"org.apache.phoenix.engine.facilities.DefaultComponentManager" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.ConfigurationRepository",
"org.apache.phoenix.engine.facilities.DefaultConfigurationRepository" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.ContextBuilder",
"org.apache.phoenix.engine.facilities.DefaultContextBuilder" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.LoggerBuilder",
"org.apache.phoenix.engine.facilities.DefaultLoggerBuilder" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.LogManager",
"org.apache.phoenix.engine.facilities.DefaultLogManager" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.DefaultPolicy",
"org.apache.phoenix.engine.facilities.DefaultPolicy" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.ThreadManager",
"org.apache.phoenix.engine.facilities.DefaultThreadManager" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.SarBlockFactory",
"org.apache.phoenix.engine.facilities.SarBlockFactory" );
this.managerContext.put( "org.apache.avalon.atlantis.Facility.SarClassLoader",
"org.apache.phoenix.engine.facilities.SarClassLoader" );
((Contextualizable)this.manager).contextualize( (Context)this.managerContext );
}
/* TODO
add DynamicMBeans for the default kernel services here
*/
}
private void createKernel() throws ConfigurationException
{
try
{
Thread.currentThread().setContextClassLoader( getClass().getClassLoader() );
this.kernel = (Kernel)Class.forName( (String)this.context.get( "kernel-class" ) ).newInstance();
this.kernelContext = new DefaultContext();
} catch( final Exception e )
{
throw new ConfigurationException( "Failed to create Kernel of class " +
(String)this.context.get( "kernel-class" ), e );
}
}
private void setupKernel()
{
if( this.kernel instanceof Loggable )
{
((Loggable)this.kernel).setLogger( this.logger );
}
if( this.kernel instanceof Contextualizable )
{
this.kernelContext.put( "org.apache.phoenix.facilities.Manager", this.manager );
((Contextualizable)this.kernel).contextualize( (Context)this.kernelContext );
}
if( this.kernel instanceof Configurable )
{
try {
this.kernelConfiguration = (new DefaultConfigurationBuilder()).build(
(String)this.context.get( "kernel-configuration-source" ) );
((Configurable)this.kernel).configure( this.kernelConfiguration );
}
catch ( Exception se )
{
// it's okay; we don't use this yet anyway...
}
}
if( this.kernel instanceof Suspendable )
{
this.kernelSupportsSuspend = true;
}
try {
this.kernel.init();
} catch ( Exception e )
{
this.logger.log( Priority.FATAL_ERROR,
"There was a fatal error; phoenix could not be started", e );
System.exit( 1 );
}
}
private void handleRestart()
{
this.restart = false;
kernel.stop();
kernel.dispose();
manager.stop();
manager.dispose();
logger = null;
kernel = null;
manager = null;
mBeanServer = null;
deployer = null;
System.gc(); // make sure resources are released
try
{
this.init();
this.setupLogger();
this.setupDeployer();
this.setupManager();
this.setupKernel();
}
catch( Exception e )
{
// this is bad...
logger.fatalError( "A fatal error occured while restarting. Phoenix will exit.", e );
System.exit( 1 );
}
kernel.start();
}
private void handleSuspend()
{
//this.suspend = false;
if( this.kernelSupportsSuspend )
{
((Suspendable)kernel).suspend();
} else
{
// the kernel does not support suspend,
// thus, we must destroy and then
// re-create it.
kernel.stop();
kernel.dispose();
kernel = null;
System.gc(); // make sure resources are released
}
// wait for resume
try { synchronized( this ) { wait(); } }
catch (InterruptedException e) {}
}
private void handleDispose()
{
kernel.stop();
kernel.dispose();
manager.stop();
manager.dispose();
kernel = null;
manager = null;
mBeanServer = null;
deployer = null;
System.gc(); // make sure resources are released
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/PhoenixKernel.java
Index: PhoenixKernel.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine;
import org.apache.phoenix.applications.Application;
import org.apache.framework.container.Entry;
/**
* This is the DefaultServerKernel for phoenix.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultServerKernel
{
public final static String BANNER = Constants.SOFTWARE + " " + Constants.VERSION;
public DefaultServerKernel()
{
m_entryClass = ServerApplicationEntry.class;
m_applicationClass = ServerApplication.class;
}
/**
* Prepare an application before it is initialized.
* Overide to provide functionality.
* Usually used to setLogger(), contextualize, compose, configure.
*
* @param name the name of application
* @param entry the application entry
* @param application the application instance
* @exception Exception if an error occurs
*/
protected void prepareApplication( final String name,
final Entry entry,
final Application application )
throws Exception
{
final ServerApplicationEntry saEntry = (ServerApplicationEntry)entry;
final ServerApplication saApplication = (ServerApplication)application;
setupLogger( saApplication, LogKit.getLoggerFor( name ) );
saApplication.contextualize( saEntry.getContext() );
if( saApplication instanceof Composer )
{
((Composer)saApplication).compose( saEntry.getComponentManager() );
}
saApplication.configure( saEntry.getConfiguration() );
}
protected void postAdd( final String name, final Entry entry )
{
}
public void init()
throws Exception
{
System.out.println();
System.out.println( BANNER );
super.init();
}
protected Application newApplication( final String name, final Entry entry )
throws Exception
{
//It is here where you could return new EASServerApplication()
//if you wanted to host multiple different types of apps
return new DefaultServerApplication();
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/applications/DefaultServerApplication.java
Index: DefaultServerApplication.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine;
import java.security.Policy;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.framework.component.Component;
import org.apache.framework.component.ComponentManager;
import org.apache.framework.component.ComponentException;
import org.apache.framework.component.Composer;
import org.apache.framework.context.Context;
import org.apache.framework.context.Contextualizable;
import org.apache.avalon.component.DefaultComponentManager;
import org.apache.avalon.context.DefaultContext;
import org.apache.framework.lifecycle.Initializable;
import org.apache.avalon.atlantis.ApplicationException;
import org.apache.avalon.camelot.AbstractContainer;
import org.apache.avalon.camelot.pipeline.AvalonState;
import org.apache.framework.container.ContainerException;
import org.apache.framework.container.Entry;
import org.apache.framework.container.Factory;
import org.apache.avalon.camelot.pipeline.ComponentBuilder;
import org.apache.avalon.camelot.pipeline.ComponentManagerBuilder;
import org.apache.avalon.camelot.pipeline.ConfigurationRepository;
import org.apache.avalon.camelot.pipeline.ContextBuilder;
import org.apache.avalon.camelot.pipeline.LoggerBuilder;
import org.apache.avalon.camelot.pipeline.ShutdownPipeline;
import org.apache.avalon.camelot.pipeline.StartupPipeline;
import org.apache.framework.configuration.Configurable;
import org.apache.framework.configuration.Configuration;
import org.apache.framework.configuration.ConfigurationException;
import org.apache.framework.thread.ThreadManager;
import org.apache.phoenix.engine.blocks.BlockDAG;
import org.apache.phoenix.engine.blocks.BlockEntry;
import org.apache.phoenix.engine.blocks.RoleEntry;
import org.apache.phoenix.engine.facilities.DefaultComponentBuilder;
import org.apache.phoenix.engine.facilities.DefaultComponentManagerBuilder;
import org.apache.phoenix.engine.facilities.DefaultConfigurationRepository;
import org.apache.phoenix.engine.facilities.DefaultContextBuilder;
import org.apache.phoenix.engine.facilities.DefaultLogManager;
import org.apache.phoenix.engine.facilities.DefaultLoggerBuilder;
import org.apache.phoenix.engine.facilities.DefaultPolicy;
import org.apache.phoenix.engine.facilities.DefaultThreadManager;
import org.apache.phoenix.engine.facilities.SarClassLoader;
import org.apache.phoenix.engine.phases.DefaultPhase;
import org.apache.phoenix.engine.phases.Phase;
import org.apache.phoenix.engine.phases.Traversal;
import org.apache.phoenix.metainfo.DependencyInfo;
/**
* This is the basic container of blocks. A server application
* represents an aggregation of blocks that act together to form
* an application.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
*/
public class DefaultServerApplication
extends AbstractContainer
implements ServerApplication
{
protected HashMap m_phases = new HashMap();
protected BlockDAG m_dag = new BlockDAG();
//the following are used for setting up facilities
protected Context m_context;
protected Configuration m_configuration;
protected ComponentManager m_componentManager;
protected DefaultLogManager m_logManager;
protected ThreadManager m_threadManager;
protected DefaultPolicy m_policy;
protected SarClassLoader m_classLoader;
//these are the facilities (internal components) of ServerApplication
protected ComponentBuilder m_componentBuilder;
protected LoggerBuilder m_loggerBuilder;
protected ContextBuilder m_contextBuilder;
protected ComponentManagerBuilder m_componentManagerBuilder;
protected ConfigurationRepository m_configurationRepository;
public DefaultServerApplication()
{
m_entryClass = BlockEntry.class;
}
public void contextualize( final Context context )
{
//save it to contextualize policy/logManager/etc
final DefaultContext newContext = new DefaultContext( context );
newContext.put( "name", context.get( SarContextResources.APP_NAME ) );
newContext.put( "directory", context.get( SarContextResources.APP_HOME_DIR ) );
m_context = newContext;
}
public void configure( final Configuration configuration )
throws ConfigurationException
{
m_configuration = configuration;
}
public void init()
throws Exception
{
createComponents();
//setup the component manager
m_componentManager = createComponentManager();
setupComponents();
initPhases();
setupPhases();
}
protected void initPhases()
throws ApplicationException
{
Phase phase = null;
phase = new DefaultPhase( Phase.FORWARD,
new StartupPipeline(),
AvalonState.BASE,
AvalonState.RUNNING );
m_phases.put( "startup", phase );
phase = new DefaultPhase( Phase.REVERSE,
new ShutdownPipeline(),
AvalonState.RUNNING,
AvalonState.DISPOSED );
m_phases.put( "shutdown", phase );
}
protected void setupPhases()
throws Exception
{
final Iterator phases = m_phases.values().iterator();
while( phases.hasNext() )
{
final Phase phase = (Phase)phases.next();
setupComponent( phase );
}
}
public void start()
throws Exception
{
// load blocks
try
{
getLogger().info( "Number of blocks to load: " + m_entries.size() );
final Phase phase = (Phase)m_phases.get( "startup" );
runPhase( phase );
}
catch( final ApplicationException ae )
{
getLogger().warn( "Error loading blocks: " + ae.getMessage(), ae );
throw ae;
}
}
public void stop()
throws Exception
{
}
public void dispose()
throws Exception
{
getLogger().info( "Number of blocks to unload: " + m_entries.size() );
final Phase phase = (Phase)m_phases.get( "shutdown" );
runPhase( phase );
m_entries.clear();
}
/**
* Create all required components.
*
* @exception Exception if an error occurs
*/
protected void createComponents()
throws Exception
{
//TODO: Refactor logManager so it does more useful managing
// possibly including setting up rolling etc
m_logManager = new DefaultLogManager();
m_contextBuilder = new DefaultContextBuilder();
m_componentManagerBuilder = new DefaultComponentManagerBuilder();
m_configurationRepository = new DefaultConfigurationRepository();
m_loggerBuilder = new DefaultLoggerBuilder();
m_componentBuilder = new DefaultComponentBuilder();
m_classLoader = new SarClassLoader();
m_threadManager = new DefaultThreadManager();
m_policy = new DefaultPolicy();
}
/**
* Setup all the components. (ir run all required lifecycle methods).
*
* @exception Exception if an error occurs
*/
protected void setupComponents()
throws Exception
{
Configuration configuration = null;
configuration = m_configuration.getChild( "logs" );
setupComponent( m_logManager, "<core>.logs", configuration );
configuration = m_configuration.getChild( "threads" );
setupComponent( m_threadManager, "<core>.threads", configuration );
configuration = m_configuration.getChild( "policy" );
setupComponent( (Component)m_policy, "<policy>", configuration );
setupComponent( m_classLoader );
setupComponent( m_componentBuilder );
setupComponent( m_loggerBuilder );
setupComponent( m_contextBuilder );
setupComponent( m_componentManagerBuilder );
setupComponent( m_configurationRepository );
setupComponent( m_dag, "<core>.dag", null );
}
protected void setupComponent( final Component object )
throws Exception
{
setupComponent( object, null, null );
}
protected void setupComponent( final Component object,
final String logName,
final Configuration configuration )
throws Exception
{
setupLogger( object, logName );
if( object instanceof Contextualizable )
{
((Contextualizable)object).contextualize( m_context );
}
if( object instanceof Composer )
{
((Composer)object).compose( m_componentManager );
}
if( object instanceof Configurable )
{
((Configurable)object).configure( configuration );
}
if( object instanceof Initializable )
{
((Initializable)object).init();
}
}
protected void runPhase( final Phase phase )
throws Exception
{
if( Phase.FORWARD == phase.getTraversal() )
{
final Iterator entries = list();
while( entries.hasNext() )
{
final String name = (String)entries.next();
m_dag.walkGraph( name, phase );
}
}
else if( Phase.REVERSE == phase.getTraversal() )
{
//TODO:
final Iterator entries = list();
while( entries.hasNext() )
{
final String name = (String)entries.next();
//m_dag.reverseWalkGraph( name, phase );
}
}
else
{
//TODO: Does this make sense ????
final Iterator entries = list();
while( entries.hasNext() )
{
final String name = (String)entries.next();
final BlockEntry entry = (BlockEntry)getEntry( name );
phase.visitBlock( name, entry );
}
}
}
/**
* This method is called before entry is added to give chance for
* sub-class to veto addition.
*
* @param name the name of entry
* @param entry the entry
* @exception ContainerException to stop removal of entry
*/
protected void preAdd( final String name, final Entry entry )
throws ContainerException
{
final BlockEntry blockEntry = (BlockEntry)entry;
verifyDependenciesMap( name, blockEntry );
}
/**
* Retrieve a list of RoleEntry objects that were specified
* in configuration file and verify they were expected based
* on BlockInfo file. Also verify that all entries specified
* in BlockInfo file have been provided.
*
* @param entry the BlockEntry describing block
* @return the list of RoleEntry objects
*/
protected void verifyDependenciesMap( final String name, final BlockEntry entry )
throws ContainerException
{
//Make sure all role entries specified in config file are valid
final RoleEntry[] roleEntrys = entry.getRoleEntrys();
for( int i = 0; i < roleEntrys.length; i++ )
{
final String role = roleEntrys[ i ].getRole();
final DependencyInfo info = entry.getBlockInfo().getDependency( role );
if( null == info )
{
final String message = "Unknown dependency " + roleEntrys[ i ].getName() +
" with role " + role + " declared for Block " + name;
getLogger().warn( message );
throw new ContainerException( message );
}
}
//Make sure all dependencies in BlockInfo file are satisfied
final DependencyInfo[] dependencies = entry.getBlockInfo().getDependencies();
for( int i = 0; i < dependencies.length; i++ )
{
final RoleEntry roleEntry =
entry.getRoleEntry( dependencies[ i ].getRole() );
if( null == roleEntry )
{
final String message = "Dependency " + dependencies[ i ].getRole() +
" not provided in configuration for Block " + name;
getLogger().warn( message );
throw new ContainerException( message );
}
}
}
/**
* Create a ComponentManager containing all components in engine.
*
* @return the ComponentManager
*/
protected ComponentManager createComponentManager()
{
final DefaultComponentManager componentManager = new DefaultComponentManager();
componentManager.put( "org.apache.phoenix.engine.ServerApplication", this );
componentManager.put( "java.security.Policy", m_policy );
componentManager.put( "java.lang.ClassLoader", m_classLoader );
componentManager.put( "NOT_DONE_YET", m_logManager );
componentManager.put( "org.apache.avalon.util.thread.ThreadManager", m_threadManager );
componentManager.put( "org.apache.avalon.camelot.pipeline.ContextBuilder", m_contextBuilder );
componentManager.put( "org.apache.avalon.camelot.pipeline.LoggerBuilder", m_loggerBuilder );
componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentBuilder",
m_componentBuilder );
componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentManagerBuilder",
m_componentManagerBuilder );
componentManager.put( "org.apache.avalon.camelot.pipeline.ConfigurationRepository",
m_configurationRepository );
return componentManager;
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/applications/ServerApplicationFactory.java
Index: ServerApplicationFactory.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine;
import java.security.Policy;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.framework.component.Component;
import org.apache.framework.component.ComponentManager;
import org.apache.framework.component.ComponentException;
import org.apache.framework.component.Composer;
import org.apache.framework.context.Context;
import org.apache.framework.context.Contextualizable;
import org.apache.avalon.component.DefaultComponentManager;
import org.apache.avalon.context.DefaultContext;
import org.apache.framework.lifecycle.Initializable;
import org.apache.avalon.atlantis.ApplicationException;
import org.apache.avalon.camelot.AbstractContainer;
import org.apache.avalon.camelot.pipeline.AvalonState;
import org.apache.framework.container.ContainerException;
import org.apache.framework.container.Entry;
import org.apache.framework.container.Factory;
import org.apache.avalon.camelot.pipeline.ComponentBuilder;
import org.apache.avalon.camelot.pipeline.ComponentManagerBuilder;
import org.apache.avalon.camelot.pipeline.ConfigurationRepository;
import org.apache.avalon.camelot.pipeline.ContextBuilder;
import org.apache.avalon.camelot.pipeline.LoggerBuilder;
import org.apache.avalon.camelot.pipeline.ShutdownPipeline;
import org.apache.avalon.camelot.pipeline.StartupPipeline;
import org.apache.framework.configuration.Configurable;
import org.apache.framework.configuration.Configuration;
import org.apache.framework.configuration.ConfigurationException;
import org.apache.framework.thread.ThreadManager;
import org.apache.phoenix.engine.blocks.BlockDAG;
import org.apache.phoenix.engine.blocks.BlockEntry;
import org.apache.phoenix.engine.blocks.RoleEntry;
import org.apache.phoenix.engine.facilities.DefaultComponentBuilder;
import org.apache.phoenix.engine.facilities.DefaultComponentManagerBuilder;
import org.apache.phoenix.engine.facilities.DefaultConfigurationRepository;
import org.apache.phoenix.engine.facilities.DefaultContextBuilder;
import org.apache.phoenix.engine.facilities.DefaultLogManager;
import org.apache.phoenix.engine.facilities.DefaultLoggerBuilder;
import org.apache.phoenix.engine.facilities.DefaultPolicy;
import org.apache.phoenix.engine.facilities.DefaultThreadManager;
import org.apache.phoenix.engine.facilities.SarClassLoader;
import org.apache.phoenix.engine.phases.DefaultPhase;
import org.apache.phoenix.engine.phases.Phase;
import org.apache.phoenix.engine.phases.Traversal;
import org.apache.phoenix.metainfo.DependencyInfo;
/**
* This is the basic container of blocks. A server application
* represents an aggregation of blocks that act together to form
* an application.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
*/
public class DefaultServerApplication
extends AbstractContainer
implements ServerApplication
{
protected HashMap m_phases = new HashMap();
protected BlockDAG m_dag = new BlockDAG();
//the following are used for setting up facilities
protected Context m_context;
protected Configuration m_configuration;
protected ComponentManager m_componentManager;
protected DefaultLogManager m_logManager;
protected ThreadManager m_threadManager;
protected DefaultPolicy m_policy;
protected SarClassLoader m_classLoader;
//these are the facilities (internal components) of ServerApplication
protected ComponentBuilder m_componentBuilder;
protected LoggerBuilder m_loggerBuilder;
protected ContextBuilder m_contextBuilder;
protected ComponentManagerBuilder m_componentManagerBuilder;
protected ConfigurationRepository m_configurationRepository;
public DefaultServerApplication()
{
m_entryClass = BlockEntry.class;
}
public void contextualize( final Context context )
{
//save it to contextualize policy/logManager/etc
final DefaultContext newContext = new DefaultContext( context );
newContext.put( "name", context.get( SarContextResources.APP_NAME ) );
newContext.put( "directory", context.get( SarContextResources.APP_HOME_DIR ) );
m_context = newContext;
}
public void configure( final Configuration configuration )
throws ConfigurationException
{
m_configuration = configuration;
}
public void init()
throws Exception
{
createComponents();
//setup the component manager
m_componentManager = createComponentManager();
setupComponents();
initPhases();
setupPhases();
}
protected void initPhases()
throws ApplicationException
{
Phase phase = null;
phase = new DefaultPhase( Phase.FORWARD,
new StartupPipeline(),
AvalonState.BASE,
AvalonState.RUNNING );
m_phases.put( "startup", phase );
phase = new DefaultPhase( Phase.REVERSE,
new ShutdownPipeline(),
AvalonState.RUNNING,
AvalonState.DISPOSED );
m_phases.put( "shutdown", phase );
}
protected void setupPhases()
throws Exception
{
final Iterator phases = m_phases.values().iterator();
while( phases.hasNext() )
{
final Phase phase = (Phase)phases.next();
setupComponent( phase );
}
}
public void start()
throws Exception
{
// load blocks
try
{
getLogger().info( "Number of blocks to load: " + m_entries.size() );
final Phase phase = (Phase)m_phases.get( "startup" );
runPhase( phase );
}
catch( final ApplicationException ae )
{
getLogger().warn( "Error loading blocks: " + ae.getMessage(), ae );
throw ae;
}
}
public void stop()
throws Exception
{
}
public void dispose()
throws Exception
{
getLogger().info( "Number of blocks to unload: " + m_entries.size() );
final Phase phase = (Phase)m_phases.get( "shutdown" );
runPhase( phase );
m_entries.clear();
}
/**
* Create all required components.
*
* @exception Exception if an error occurs
*/
protected void createComponents()
throws Exception
{
//TODO: Refactor logManager so it does more useful managing
// possibly including setting up rolling etc
m_logManager = new DefaultLogManager();
m_contextBuilder = new DefaultContextBuilder();
m_componentManagerBuilder = new DefaultComponentManagerBuilder();
m_configurationRepository = new DefaultConfigurationRepository();
m_loggerBuilder = new DefaultLoggerBuilder();
m_componentBuilder = new DefaultComponentBuilder();
m_classLoader = new SarClassLoader();
m_threadManager = new DefaultThreadManager();
m_policy = new DefaultPolicy();
}
/**
* Setup all the components. (ir run all required lifecycle methods).
*
* @exception Exception if an error occurs
*/
protected void setupComponents()
throws Exception
{
Configuration configuration = null;
configuration = m_configuration.getChild( "logs" );
setupComponent( m_logManager, "<core>.logs", configuration );
configuration = m_configuration.getChild( "threads" );
setupComponent( m_threadManager, "<core>.threads", configuration );
configuration = m_configuration.getChild( "policy" );
setupComponent( (Component)m_policy, "<policy>", configuration );
setupComponent( m_classLoader );
setupComponent( m_componentBuilder );
setupComponent( m_loggerBuilder );
setupComponent( m_contextBuilder );
setupComponent( m_componentManagerBuilder );
setupComponent( m_configurationRepository );
setupComponent( m_dag, "<core>.dag", null );
}
protected void setupComponent( final Component object )
throws Exception
{
setupComponent( object, null, null );
}
protected void setupComponent( final Component object,
final String logName,
final Configuration configuration )
throws Exception
{
setupLogger( object, logName );
if( object instanceof Contextualizable )
{
((Contextualizable)object).contextualize( m_context );
}
if( object instanceof Composer )
{
((Composer)object).compose( m_componentManager );
}
if( object instanceof Configurable )
{
((Configurable)object).configure( configuration );
}
if( object instanceof Initializable )
{
((Initializable)object).init();
}
}
protected void runPhase( final Phase phase )
throws Exception
{
if( Phase.FORWARD == phase.getTraversal() )
{
final Iterator entries = list();
while( entries.hasNext() )
{
final String name = (String)entries.next();
m_dag.walkGraph( name, phase );
}
}
else if( Phase.REVERSE == phase.getTraversal() )
{
//TODO:
final Iterator entries = list();
while( entries.hasNext() )
{
final String name = (String)entries.next();
//m_dag.reverseWalkGraph( name, phase );
}
}
else
{
//TODO: Does this make sense ????
final Iterator entries = list();
while( entries.hasNext() )
{
final String name = (String)entries.next();
final BlockEntry entry = (BlockEntry)getEntry( name );
phase.visitBlock( name, entry );
}
}
}
/**
* This method is called before entry is added to give chance for
* sub-class to veto addition.
*
* @param name the name of entry
* @param entry the entry
* @exception ContainerException to stop removal of entry
*/
protected void preAdd( final String name, final Entry entry )
throws ContainerException
{
final BlockEntry blockEntry = (BlockEntry)entry;
verifyDependenciesMap( name, blockEntry );
}
/**
* Retrieve a list of RoleEntry objects that were specified
* in configuration file and verify they were expected based
* on BlockInfo file. Also verify that all entries specified
* in BlockInfo file have been provided.
*
* @param entry the BlockEntry describing block
* @return the list of RoleEntry objects
*/
protected void verifyDependenciesMap( final String name, final BlockEntry entry )
throws ContainerException
{
//Make sure all role entries specified in config file are valid
final RoleEntry[] roleEntrys = entry.getRoleEntrys();
for( int i = 0; i < roleEntrys.length; i++ )
{
final String role = roleEntrys[ i ].getRole();
final DependencyInfo info = entry.getBlockInfo().getDependency( role );
if( null == info )
{
final String message = "Unknown dependency " + roleEntrys[ i ].getName() +
" with role " + role + " declared for Block " + name;
getLogger().warn( message );
throw new ContainerException( message );
}
}
//Make sure all dependencies in BlockInfo file are satisfied
final DependencyInfo[] dependencies = entry.getBlockInfo().getDependencies();
for( int i = 0; i < dependencies.length; i++ )
{
final RoleEntry roleEntry =
entry.getRoleEntry( dependencies[ i ].getRole() );
if( null == roleEntry )
{
final String message = "Dependency " + dependencies[ i ].getRole() +
" not provided in configuration for Block " + name;
getLogger().warn( message );
throw new ContainerException( message );
}
}
}
/**
* Create a ComponentManager containing all components in engine.
*
* @return the ComponentManager
*/
protected ComponentManager createComponentManager()
{
final DefaultComponentManager componentManager = new DefaultComponentManager();
componentManager.put( "org.apache.phoenix.engine.ServerApplication", this );
componentManager.put( "java.security.Policy", m_policy );
componentManager.put( "java.lang.ClassLoader", m_classLoader );
componentManager.put( "NOT_DONE_YET", m_logManager );
componentManager.put( "org.apache.avalon.util.thread.ThreadManager", m_threadManager );
componentManager.put( "org.apache.avalon.camelot.pipeline.ContextBuilder", m_contextBuilder );
componentManager.put( "org.apache.avalon.camelot.pipeline.LoggerBuilder", m_loggerBuilder );
componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentBuilder",
m_componentBuilder );
componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentManagerBuilder",
m_componentManagerBuilder );
componentManager.put( "org.apache.avalon.camelot.pipeline.ConfigurationRepository",
m_configurationRepository );
return componentManager;
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/DefaultSarDeployer.java
Index: DefaultSarDeployer.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.avalon.ComponentManager;
import org.apache.avalon.ComponentManagerException;
import org.apache.framework.component.Composer;
import org.apache.avalon.configuration.Configuration;
import org.apache.avalon.configuration.ConfigurationException;
import org.apache.avalon.DefaultComponentManager;
import org.apache.avalon.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.DefaultContext;
import org.apache.avalon.camelot.AbstractCamelotDeployer;
import org.apache.avalon.camelot.CamelotUtil;
import org.apache.avalon.camelot.ContainerException;
import org.apache.avalon.camelot.DefaultLocatorRegistry;
import org.apache.avalon.camelot.DefaultRegistry;
import org.apache.avalon.camelot.Deployer;
import org.apache.avalon.camelot.DeployerUtil;
import org.apache.avalon.camelot.DeploymentException;
import org.apache.avalon.camelot.Locator;
import org.apache.avalon.camelot.LocatorRegistry;
import org.apache.avalon.camelot.Registry;
import org.apache.avalon.camelot.RegistryException;
import org.apache.avalon.util.io.FileUtil;
import org.apache.avalon.util.io.IOUtil;
import org.apache.phoenix.BlockContext;
import org.apache.phoenix.metainfo.BlockInfo;
import org.apache.phoenix.engine.blocks.BlockEntry;
import org.apache.phoenix.engine.blocks.RoleEntry;
import org.apache.phoenix.engine.blocks.DefaultBlockDeployer;
/**
* This class deploys a .sar file.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultSarDeployer
extends AbstractCamelotDeployer
{
protected File m_deployDirectory;
/**
* Default constructor.
*/
public DefaultSarDeployer()
{
m_deployToContainer = true;
m_autoUndeploy = true;
m_type = "Sar";
}
protected void deployFromFile( final String name, final File file )
throws DeploymentException
{
if( file.isDirectory() )
{
throw new DeploymentException( "Deploying directories is not supported" );
}
else
{
final File destination = getDestinationFor( name, file );
expandTo( file, destination );
deployFromDirectory( file, name, destination );
}
}
protected void expandTo( final File file, final File directory )
throws DeploymentException
{
final ZipFile zipFile = DeployerUtil.getZipFileFor( file );
if( !needsExpanding( zipFile, directory ) )
{
return;
}
directory.mkdirs();
final Enumeration entries = zipFile.entries();
while( entries.hasMoreElements() )
{
final ZipEntry entry = (ZipEntry)entries.nextElement();
if( entry.isDirectory() ) continue;
final String name = entry.getName().replace( '/', File.separatorChar );
if( !shouldExpandEntry( entry.getName() ) ) continue;
final File destination = new File( directory, name );
InputStream input = null;
OutputStream output = null;
try
{
destination.getParentFile().mkdirs();
output = new FileOutputStream( destination );
input = zipFile.getInputStream( entry );
IOUtil.copy( input, output );
}
catch( final IOException ioe )
{
throw new DeploymentException( "Error extracting " + name, ioe );
}
finally
{
IOUtil.shutdownStream( input );
IOUtil.shutdownStream( output );
}
}
}
protected boolean shouldExpandEntry( final String name )
{
if( name.startsWith( "META-INF" ) ) return false;
else return true;
}
protected boolean needsExpanding( final ZipFile zipFile, final File directory )
{
return !directory.exists();
}
protected File getDestinationFor( final String location, final File file )
{
final String name =
FileUtil.removeExtention( FileUtil.removePath( file.getName() ) );
if( null != m_deployDirectory )
{
return (new File( m_deployDirectory, name )).getAbsoluteFile();
}
else
{
return (new File( file.getParentFile(), name )).getAbsoluteFile();
}
}
protected ServerKernel getKernel()
throws DeploymentException
{
if( !(m_container instanceof ServerKernel) )
{
throw new DeploymentException( "Can only deploy to a kernel container" );
}
else
{
return (ServerKernel)m_container;
}
}
protected void buildEntry( final String name,
final ServerApplicationEntry entry,
final File archive,
final File directory )
throws DeploymentException
{
//final File file = new File( directory, "SAR-INF" + File.separator + "sar-inf.xml" );
//setup the ServerApplications context
final DefaultContext context = new DefaultContext();
context.put( SarContextResources.APP_ARCHIVE, archive );
context.put( SarContextResources.APP_HOME_DIR, directory );
context.put( SarContextResources.APP_NAME, name );
entry.setContext( context );
//setup the ServerApplications component manager
final DefaultComponentManager componentManager = new DefaultComponentManager();
componentManager.put( "org.apache.avalon.camelot.Registry",
new DefaultRegistry( BlockInfo.class ) );
componentManager.put( "org.apache.avalon.camelot.LocatorRegistry",
new DefaultLocatorRegistry() );
entry.setComponentManager( componentManager );
//setup the ServerApplications configuration manager
final File file = new File( directory, "conf" + File.separator + "server.xml" );
final Configuration configuration = getConfigurationFor( file );
entry.setConfiguration( configuration );
}
protected void deployFromDirectory( final File archive,
final String name,
final File directory )
throws DeploymentException
{
getLogger().info( "deploying from archive (" + archive +
") expanded into directory " + directory );
final ServerApplicationEntry entry = new ServerApplicationEntry();
buildEntry( name, entry, archive, directory );
addEntry( name, entry );
final ServerKernel kernel = getKernel();
ServerApplication serverApplication = null;
try
{
serverApplication = (ServerApplication)kernel.getApplication( name );
}
catch( final ContainerException ce )
{
throw new DeploymentException( "Error preparingserver application", ce );
}
//rework next bit so it grabs deployments from archive
final Deployer deployer = getBlockDeployer( entry );
final File blocksDirectory = new File( directory, "blocks" );
CamelotUtil.deployFromDirectory( deployer, blocksDirectory, ".bar" );
final File file =
new File( directory, "conf" + File.separator + "assembly.xml" );
try
{
final Configuration configuration = getConfigurationFor( file );
final Configuration[] blocks = configuration.getChildren( "block" );
handleBlocks( serverApplication, entry, blocks );
}
catch( final ComponentManagerException cme )
{
throw new DeploymentException( "Error setting up registries", cme );
}
catch( final ConfigurationException ce )
{
throw new DeploymentException( "Error in assembly.xml", ce );
}
}
protected Configuration getConfigurationFor( final File file )
throws DeploymentException
{
try
{
final FileInputStream input = new FileInputStream( file );
return DeployerUtil.buildConfiguration( input );
}
catch( final IOException ioe )
{
throw new DeploymentException( "Error reading " + file, ioe );
}
}
protected Deployer getBlockDeployer( final ServerApplicationEntry entry )
throws DeploymentException
{
final Deployer deployer = new DefaultBlockDeployer();
setupLogger( deployer );
if( deployer instanceof Composer )
{
try { ((Composer)deployer).compose( entry.getComponentManager() ); }
catch( final Exception e )
{
throw new DeploymentException( "Error composing block deployer", e );
}
}
return deployer;
}
protected void handleBlocks( final ServerApplication serverApplication,
final ServerApplicationEntry saEntry,
final Configuration[] blocks )
throws ComponentManagerException, ConfigurationException, DeploymentException
{
final ComponentManager componentManager = saEntry.getComponentManager();
final Registry infoRegistry =
(Registry)componentManager.lookup( "org.apache.avalon.camelot.Registry" );
final LocatorRegistry locatorRegistry = (LocatorRegistry)componentManager.
lookup( "org.apache.avalon.camelot.LocatorRegistry" );
for( int i = 0; i < blocks.length; i++ )
{
final Configuration block = blocks[ i ];
final String name = block.getAttribute("name");
final String className = block.getAttribute("class");
BlockInfo info = null;
try { info = (BlockInfo)infoRegistry.getInfo( className ); }
catch( final RegistryException re )
{
throw new DeploymentException( "Failed to aquire BlockInfo for " + className,
re );
}
Locator locator = null;
try { locator = locatorRegistry.getLocator( className ); }
catch( final RegistryException re )
{
throw new DeploymentException( "Failed to aquire Locator for " + className,
re );
}
final Configuration[] provides = block.getChildren( "provide" );
final ArrayList roleList = new ArrayList();
for( int j = 0; j < provides.length; j++ )
{
final Configuration provide = provides[ j ];
final String requiredName = provide.getAttribute("name");
final String role = provide.getAttribute("role");
roleList.add( new RoleEntry( requiredName, role ) );
}
final RoleEntry[] roles = (RoleEntry[]) roleList.toArray( new RoleEntry[ 0 ] );
final BlockEntry entry = new BlockEntry( locator, roles );
entry.setBlockInfo( info );
entry.setConfiguration( block.getChild( "configuration" ) );
try { serverApplication.add( name, entry ); }
catch( final ContainerException ce )
{
throw new DeploymentException( "Error adding component to container", ce );
}
getLogger().debug( "Adding " + m_type + "Entry " + name + " as " + entry );
}
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/BlockDAG.java
Index: BlockDAG.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.blocks;
import java.util.Iterator;
import org.apache.avalon.logger.AbstractLoggable;
import org.apache.framework.component.ComponentManager;
import org.apache.framework.component.ComponentException;
import org.apache.framework.component.Composer;
import org.apache.framework.container.ContainerException;
import org.apache.phoenix.Block;
import org.apache.phoenix.engine.ServerApplication;
import org.apache.phoenix.metainfo.DependencyInfo;
import org.apache.phoenix.metainfo.ServiceInfo;
/**
* This is the dependency graph for blocks.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class BlockDAG
extends AbstractLoggable
implements Composer
{
protected ServerApplication m_serverApplication;
public void compose( final ComponentManager componentManager )
throws ComponentException
{
m_serverApplication = (ServerApplication)componentManager.
lookup( "org.apache.phoenix.engine.ServerApplication" );
}
public void walkGraph( final String root, final BlockVisitor visitor )
throws Exception
{
visitBlock( root, getBlockEntry( root ), visitor, true );
}
public void reverseWalkGraph( final String root, final BlockVisitor visitor )
throws Exception
{
visitBlock( root, getBlockEntry( root ), visitor, false );
}
protected BlockEntry getBlockEntry( final String name )
throws Exception
{
return (BlockEntry)m_serverApplication.getEntry( name );
//catch( final ContainerException ce )
}
/**
* Traverse dependencies of specified entry.
*
* @param name name of BlockEntry
* @param entry the BlockEntry
*/
protected void visitDependencies( final String name,
final BlockEntry entry,
final BlockVisitor visitor )
throws Exception
{
getLogger().debug( "Traversing dependencies for " + name );
final DependencyInfo[] infos = entry.getBlockInfo().getDependencies();
for( int i = 0; i < infos.length; i++ )
{
final ServiceInfo serviceInfo = infos[ i ].getService();
final String role = infos[ i ].getRole();
getLogger().debug( "Traversing dependency of " + name + " with role " + role +
" to provide service " + serviceInfo.getName() );
//roleEntry should NEVER be null as it is checked when
//entry is added to container
final RoleEntry roleEntry = entry.getRoleEntry( role );
final String dependencyName = roleEntry.getName();
final BlockEntry dependency = getBlockEntry( dependencyName );
visitBlock( dependencyName, dependency, visitor, true );
}
}
/**
* Traverse all reverse dependencies of specified entry.
* A reverse dependency are those that dependend on entry.
*
* @param name name of BlockEntry
* @param entry the BlockEntry
*/
protected void visitReverseDependencies( final String name, final BlockVisitor visitor )
throws Exception
{
getLogger().debug( "Traversing reverse dependencies for " + name );
final Iterator entries = m_serverApplication.list();
while( entries.hasNext() )
{
final String blockName = (String)entries.next();
final BlockEntry entry = getBlockEntry( blockName );
final RoleEntry[] roles = entry.getRoleEntrys();
for( int i = 0; i < roles.length; i++ )
{
final String depends = roles[ i ].getName();
if( depends.equals( name ) )
{
getLogger().debug( "Attempting to unload block " + blockName +
" as it depends on " + depends );
//finally try to traverse block
visitBlock( blockName, entry, visitor, false );
}
}
}
}
protected void visitBlock( final String name,
final BlockEntry entry,
final BlockVisitor visitor,
final boolean forward )
throws Exception
{
if( forward )
{
visitDependencies( name, entry, visitor );
}
else
{
visitReverseDependencies( name, visitor );
}
visitor.visitBlock( name, entry );
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/BlockEntry.java
Index: BlockEntry.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.blocks;
import org.apache.avalon.camelot.Entry;
import org.apache.framework.container.Locator;
import org.apache.avalon.camelot.AvalonState;
import org.apache.framework.configuration.Configuration;
import org.apache.phoenix.Block;
import org.apache.phoenix.metainfo.BlockInfo;
/**
* This is the structure describing each block before it is loaded.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class BlockEntry
extends Entry
{
protected final Locator m_locator;
protected final RoleEntry[] m_roleEntrys;
//UGLY HACK should be stored in another server Facility (ie ConfigurationRepository)
protected Configuration m_configuration;
public BlockEntry( final Locator locator, final RoleEntry[] roleEntrys )
{
setState( AvalonState.BASE );
m_locator = locator;
m_roleEntrys = roleEntrys;
}
public Locator getLocator()
{
return m_locator;
}
public BlockInfo getBlockInfo()
{
return (BlockInfo)getInfo();
}
public void setBlockInfo( final BlockInfo blockInfo )
{
setInfo( blockInfo );
}
/**
* Get a RoleEntry from entry with a particular role.
*
* @param role the role of RoleEntry to look for
* @return the matching deendency else null
*/
public RoleEntry getRoleEntry( final String role )
{
for( int i = 0; i < m_roleEntrys.length; i++ )
{
if( m_roleEntrys[ i ].getRole().equals( role ) )
{
return m_roleEntrys[ i ];
}
}
return null;
}
public RoleEntry[] getRoleEntrys()
{
return m_roleEntrys;
}
public Configuration getConfiguration()
{
return m_configuration;
}
public void setConfiguration( final Configuration configuration )
{
m_configuration = configuration;
}
public Block getBlock()
{
return (Block)getInstance();
}
public void setBlock( final Block block )
{
setInstance( block );
}
public void setInfo( final BlockInfo info )
{
//m_info = info;
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/BlockVisitor.java
Index: BlockVisitor.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.blocks;
import org.apache.avalon.atlantis.ApplicationException;
/**
* Visitor interface that objects implement to walk the DAG.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface BlockVisitor
{
/**
* This is called when a block is reached whilst walking the tree.
*
* @param name the name of block
* @param entry the BlockEntry
* @exception ApplicationException if walking is to be stopped
*/
void visitBlock( String name, BlockEntry entry )
throws ApplicationException;
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/DefaultBlockContext.java
Index: DefaultBlockContext.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.blocks;
import java.io.File;
import org.apache.framework.context.Context;
import org.apache.avalon.context.DefaultContext;
import org.apache.framework.thread.ThreadManager;
import org.apache.framework.thread.ThreadPool;
import org.apache.log.Logger;
import org.apache.phoenix.BlockContext;
/**
* Context via which Blocks communicate with container.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultBlockContext
extends DefaultContext
implements BlockContext
{
protected ThreadManager m_threadManager;
protected Logger m_baseLogger;
public DefaultBlockContext( final Logger logger, final ThreadManager threadManager )
{
this( logger, threadManager, null );
}
public DefaultBlockContext( final Logger logger,
final ThreadManager threadManager,
final Context context )
{
super( context );
m_baseLogger = logger;
m_threadManager = threadManager;
}
/**
* Base directory of .sar application.
*
* @return the base directory
*/
public File getBaseDirectory()
{
return (File)get( APP_HOME_DIR );
}
/**
* Retrieve name of block.
*
* @return the name of block
*/
public String getName()
{
return (String)get( NAME );
}
/**
* Retrieve thread manager by category.
* ThreadManagers are given names so that you can manage different thread
* count to different components.
*
* @param category the category
* @return the ThreadManager
*/
public ThreadPool getThreadPool( final String category )
{
return m_threadManager.getThreadPool( category );
}
/**
* Retrieve the default thread pool.
* Equivelent to getThreadPool( "default" );
* @return the ThreadPool
*/
public ThreadPool getDefaultThreadPool()
{
return getThreadPool( "default" );
}
/**
* Retrieve logger coresponding to root category of application.
*
* @return the base logger
*/
public Logger getBaseLogger()
{
return m_baseLogger;
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/DefaultBlockDeployer.java
Index: DefaultBlockDeployer.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.blocks;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.zip.ZipFile;
import org.apache.avalon.camelot.AbstractZipDeployer;
import org.apache.avalon.camelot.DeployerUtil;
import org.apache.framework.container.DeploymentException;
import org.apache.framework.container.LocatorRegistry;
import org.apache.framework.container.Registry;
import org.apache.framework.container.RegistryException;
import org.apache.aut.io.IOUtil;
import org.apache.phoenix.metainfo.BlockInfo;
import org.apache.phoenix.metainfo.BlockInfoBuilder;
/**
* This class deploys a .bar file into a registry.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultBlockDeployer
extends AbstractZipDeployer
{
protected BlockInfoBuilder m_builder;
/**
* Default constructor.
*/
public DefaultBlockDeployer()
{
m_builder = new BlockInfoBuilder();
//Indicate that this deployer should deploy to respective types
m_deployToLocatorRegistry = true;
m_deployToInfoRegistry = true;
m_autoUndeploy = true;
m_type = "Block";
}
/**
* Load resources from jar required to deploy file.
*
* @param zipFile the zipFile
* @param location the location deploying to
* @param url the URL
* @exception DeploymentException if an error occurs
*/
protected void loadResources( final ZipFile zipFile, final String location, final URL url )
throws DeploymentException
{
handleBlocks( zipFile, DeployerUtil.loadManifest( zipFile ), url );
}
/**
* Create and register Infos for all blocks stored in deployment.
*
* @param properties the properties
* @param url the url of deployment
* @exception DeploymentException if an error occurs
*/
protected void handleBlocks( final ZipFile zipFile, final Manifest manifest, final URL url )
throws DeploymentException
{
final Map entries = manifest.getEntries();
final Iterator sections = entries.keySet().iterator();
//for every section (aka resource)
// check to see if the attribute "Avalon-Block" is set to true
while( sections.hasNext() )
{
final String section = (String)sections.next();
final Attributes attributes = manifest.getAttributes( section );
final String blockValue = attributes.getValue( "Avalon-Block" );
final boolean isBlock = Boolean.valueOf( blockValue ).booleanValue();
if( isBlock )
{
handleBlock( zipFile, section, url );
}
}
}
/**
* Handle the addition of a block from .bar file.
*
* @param zipFile the .bar zip
* @param block the block filename
* @param url the url of .bar file
* @exception DeploymentException if an error occurs
*/
protected void handleBlock( final ZipFile zipFile, final String block, final URL url )
throws DeploymentException
{
final String classname = block.substring( 0, block.length() - 6 ).replace('/','.');
addLocator( classname, classname, url );
final BlockInfo info = loadBlockInfo( zipFile, classname, url );
addInfo( classname, info );
}
/**
* Create a blockinfo object by loading a .xinfo file.
*
* @param zipFile the zipFile to load it from
* @param classname the name of the block class
* @param url the url for zip
* @return the created block info
* @exception DeploymentException if an error occurs
*/
protected BlockInfo loadBlockInfo( final ZipFile zipFile,
final String classname,
final URL url )
throws DeploymentException
{
final String resource = classname.replace( '.', '/' ) + ".xinfo";
final InputStream inputStream = DeployerUtil.loadResourceStream( zipFile, resource );
try { return m_builder.build( inputStream ); }
catch( final Exception e )
{
throw new DeploymentException( "Failed to build BlockInfo for " + classname +
" in location " + url, e );
}
finally
{
IOUtil.shutdownStream( inputStream );
}
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/deployer/blocks/RoleEntry.java
Index: RoleEntry.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.blocks;
/**
* This is the structure describing the instances of roles provided to each block.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class RoleEntry
{
protected final String m_name;
protected final String m_role;
public RoleEntry( final String name, final String role )
{
m_name = name;
m_role = role;
}
public String getRole()
{
return m_role;
}
public String getName()
{
return m_name;
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/ApplicationManager.java
Index: ApplicationManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.loader;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.security.Security;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.StringTokenizer;
/**
* PhoenixLoader is the class that bootstraps and installs the security manager.
* It also a default policy that gives all code all permssions.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public final class PhoenixLoader
{
protected final static boolean ENABLE_SECURITY_MANAGER =
!Boolean.getBoolean("phoenix.insecure");
protected final static String RESTRICTED_PACKAGES =
System.getProperty( "phoenix.restricted.packages",
Security.getProperty("package.access") );
protected final static String MAIN_JAR =
System.getProperty( "phoenix.mainJar", "phoenix-engine.jar" );
protected final static String MAIN_CLASS =
System.getProperty( "phoenix.mainClass", "org.apache.phoenix.engine.Main" );
public final static void main( final String args[] )
throws Exception
{
//setup restricted packages
Security.setProperty( "phoenix.access", RESTRICTED_PACKAGES );
//setup new Policy manager
Policy.setPolicy( new FreeNEasyPolicy() );
final File loaderDir = findLoaderDir();
final String avalonHome =
loaderDir.getAbsoluteFile().getParentFile() + File.separator;
System.setProperty( "phoenix.home", avalonHome );
final File mainJar = new File( loaderDir, MAIN_JAR );
//load main jar
final URL archive = mainJar.toURL();
final URLClassLoader classLoader = new URLClassLoader( new URL[] { archive } );
runSystem( classLoader, args );
}
/**
* load class and retrieve appropriate main method.
*/
protected static void runSystem( final ClassLoader classLoader, final String[] args )
{
try
{
final Class clazz = classLoader.loadClass( MAIN_CLASS );
final Method method = clazz.getMethod( "main", new Class[] { args.getClass() } );
final Object instance = clazz.newInstance();
// Set security manager unless it has been disabled by system property
if( ENABLE_SECURITY_MANAGER )
{
System.setSecurityManager( new SecurityManager() );
}
//kick the tires and light the fires....
try
{
final PrivilegedExceptionAction action = new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
method.invoke( instance, new Object[] { args } );
return null;
}
};
AccessController.doPrivileged( action );
}
catch( final PrivilegedActionException pae )
{
// only "checked" exceptions will be "wrapped" in a PrivilegedActionException.
throw pae.getException();
}
}
catch( final Exception throwable )
{
throwable.printStackTrace( System.err );
}
}
/**
* Finds the avalon-loader.jar file in the classpath.
*/
protected final static File findLoaderDir()
throws Exception
{
final String classpath = System.getProperty( "java.class.path" );
final String pathSeparator = System.getProperty( "path.separator" );
final StringTokenizer tokenizer = new StringTokenizer( classpath, pathSeparator );
while( tokenizer.hasMoreTokens() )
{
final String element = tokenizer.nextToken();
if( element.endsWith( "phoenix-loader.jar" ) )
{
File file = (new File( element )).getCanonicalFile();
file = file.getParentFile();
return file;
}
}
throw new Exception( "Unable to locate avalon-loader.jar in classpath" );
}
/**
* Default polic class to give every code base all permssions.
* Will be replaced once the kernel loads.
*/
private static class FreeNEasyPolicy
extends Policy
{
public PermissionCollection getPermissions( final CodeSource codeSource )
{
final Permissions permissions = new Permissions();
permissions.add( new java.security.AllPermission() );
return permissions;
}
public void refresh() {}
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/ClassLoader.java
Index: ClassLoader.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.facilities;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.Policy;
import org.apache.framework.component.ComponentManager;
import org.apache.framework.component.ComponentException;
import org.apache.framework.component.Composer;
import org.apache.framework.context.Context;
import org.apache.framework.context.Contextualizable;
import org.apache.framework.lifecycle.Initializable;
import org.apache.avalon.atlantis.Facility;
import org.apache.aut.io.ExtensionFileFilter;
import org.apache.aut.security.PolicyClassLoader;
import org.apache.phoenix.engine.SarContextResources;
/**
* This component creates blocks and blockInfos.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class SarClassLoader
extends PolicyClassLoader
implements Facility, Contextualizable, Composer, Initializable
{
protected File m_baseDirectory;
public SarClassLoader()
{
super( new URL[ 0 ], Thread.currentThread().getContextClassLoader(), null );
}
public void contextualize( final Context context )
{
m_baseDirectory = (File)context.get( SarContextResources.APP_HOME_DIR );
}
public void compose( final ComponentManager componentManager )
throws ComponentException
{
m_policy = (Policy)componentManager.lookup( "java.security.Policy" );
}
public void init()
throws Exception
{
final File blockDir =
(new File( m_baseDirectory, "blocks" )).getAbsoluteFile();
final File libDir =
(new File( m_baseDirectory, "lib" )).getAbsoluteFile();
addURLs( blockDir, new String[] { ".bar" } );
addURLs( libDir, new String[] { ".jar", ".zip" } );
}
protected void addURLs( final File directory, final String[] extentions )
throws MalformedURLException
{
final ExtensionFileFilter filter = new ExtensionFileFilter( extentions );
final File[] files = directory.listFiles( filter );
if( null == files ) return;
addURLs( files );
}
protected void addURLs( final File[] files )
throws MalformedURLException
{
for( int i = 0; i < files.length; i++ )
{
addURL( files[ i ].toURL() );
}
}
public String toString()
{
final StringBuffer sb = new StringBuffer();
sb.append( "ClassLoader[" );
final URL[] urls = getURLs();
for( int i = 0; i < urls.length; i++ )
{
sb.append( ' ' );
sb.append( urls[ i ] );
}
sb.append( " ]" );
return sb.toString();
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/ConfigurationManager.java
Index: ConfigurationManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.facilities;
import org.apache.avalon.atlantis.Facility;
import org.apache.avalon.camelot.Entry;
import org.apache.avalon.camelot.pipeline.ConfigurationRepository;
import org.apache.framework.configuration.Configuration;
import org.apache.framework.configuration.ConfigurationException;
import org.apache.phoenix.engine.blocks.BlockEntry;
/**
* Repository from which all configuration data is retrieved.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultConfigurationRepository
implements Facility
{
public Configuration getConfiguration( String name, Entry entry )
throws ConfigurationException
{
final BlockEntry blockEntry = (BlockEntry)entry;
return blockEntry.getConfiguration();
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/LogManager.java
Index: LogManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.facilities;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import org.apache.avalon.logger.AbstractLoggable;
import org.apache.framework.context.Context;
import org.apache.framework.context.Contextualizable;
import org.apache.avalon.atlantis.Facility;
import org.apache.framework.configuration.Configurable;
import org.apache.framework.configuration.Configuration;
import org.apache.framework.configuration.ConfigurationException;
import org.apache.log.format.AvalonLogFormatter;
import org.apache.log.Category;
import org.apache.log.LogKit;
import org.apache.log.LogTarget;
import org.apache.log.output.FileOutputLogTarget;
/**
* Component responsible for managing logs.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultLogManager
extends AbstractLoggable
implements Facility, Contextualizable, Configurable
{
protected String m_baseName;
protected File m_baseDirectory;
public void contextualize( final Context context )
{
m_baseName = (String)context.get( "name" );
if( null == m_baseName ) m_baseName = "<base>";
m_baseDirectory = (File)context.get( "directory" );
if( null == m_baseDirectory ) m_baseDirectory = new File( "." );
}
public void configure( final Configuration configuration )
throws ConfigurationException
{
final Iterator targets = configuration.getChildren( "log-target" );
configureTargets( m_baseName, m_baseDirectory, targets );
final Iterator categories = configuration.getChildren( "category" );
configureCategories( m_baseName, categories );
/*
final String logPriority = configuration.getChild( "global-priority" ).getValue();
final Priority.Enum priority = LogKit.getPriorityForName( logPriority );
LogKit.setGlobalPriority( priority );
*/
}
protected void configureTargets( final String baseName,
final File baseDirectory,
final Iterator targets )
throws ConfigurationException
{
while(targets.hasNext())
{
final Configuration target = (Configuration)targets.next();
final String name = baseName + '.' + target.getAttribute( "name" );
String location = target.getAttribute( "location" ).trim();
final String format = target.getAttribute( "format", null );
if( '/' == location.charAt( 0 ) )
{
location = location.substring( 1 );
}
final File file = new File( baseDirectory, location );
final FileOutputLogTarget logTarget = new FileOutputLogTarget();
final AvalonLogFormatter formatter = new AvalonLogFormatter();
formatter.setFormat( "%{time} [%7.7{priority}] <<%{category}>> " +
"(%{context}): %{message}\\n%{throwable}" );
logTarget.setFormatter( formatter );
try { logTarget.setFilename( file.getAbsolutePath() ); }
catch( final IOException ioe )
{
throw new ConfigurationException( "Error initializing log files", ioe );
}
if( null != format )
{
logTarget.setFormat( format );
}
LogKit.addLogTarget( name, logTarget );
}
}
protected void configureCategories( final String baseName, final Iterator categories )
throws ConfigurationException
{
while(categories.hasNext())
{
final Configuration category = (Configuration)categories.next();
String name = category.getAttribute( "name" );
final String target = baseName + '.' + category.getAttribute( "target" );
final String priority = category.getAttribute( "priority" );
if( name.trim().equals( "" ) )
{
name = baseName;
}
else
{
name = baseName + '.' + name;
}
final Category logCategory =
LogKit.createCategory( name, LogKit.getPriorityForName( priority ) );
final LogTarget logTarget = LogKit.getLogTarget( target );
LogTarget logTargets[] = null;
if( null != target ) logTargets = new LogTarget[] { logTarget };
LogKit.createLogger( logCategory, logTargets );
}
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/SecurityManager.java
Index: SecurityManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.facilities;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.UnresolvedPermission;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.PropertyPermission;
import java.util.StringTokenizer;
import org.apache.framework.component.Component;
import org.apache.framework.context.Context;
import org.apache.framework.context.Contextualizable;
import org.apache.avalon.context.DefaultContext;
import org.apache.framework.lifecycle.Initializable;
import org.apache.avalon.atlantis.Facility;
import org.apache.framework.configuration.Configurable;
import org.apache.framework.configuration.Configuration;
import org.apache.framework.configuration.ConfigurationException;
import org.apache.aut.PropertyException;
import org.apache.aut.PropertyUtil;
import org.apache.aut.security.AbstractPolicy;
/**
* Policy that extracts information from policy files.
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultPolicy
extends AbstractPolicy
implements Facility, Contextualizable, Configurable, Initializable
{
protected DefaultContext m_context;
public void contextualize( final Context context )
{
m_context = new DefaultContext( System.getProperties(), context );
m_context.put( "/", File.separator );
}
public void configure( final Configuration configuration )
throws ConfigurationException
{
final Iterator it = configuration.getChildren( "keystore" );
final HashMap keyStores = configureKeyStores( it );
final Iterator grants = configuration.getChildren( "grant" );
configureGrants( grants, keyStores );
// final Configuration[] grants = configuration.getChildren( "grant" );
// configureGrants( grants, keyStores );
}
public void init()
throws Exception
{
//these properties straight out ot ${java.home}/lib/security/java.policy
final Permissions permissions = createPermissionSetFor( "file:/-", null );
permissions.add( new PropertyPermission( "os.name", "read" ) );
permissions.add( new PropertyPermission( "os.arch", "read" ) );
permissions.add( new PropertyPermission( "os.version", "read" ) );
permissions.add( new PropertyPermission( "file.separator", "read" ) );
permissions.add( new PropertyPermission( "path.separator", "read" ) );
permissions.add( new PropertyPermission( "line.separator", "read" ) );
permissions.add( new PropertyPermission( "java.version", "read" ) );
permissions.add( new PropertyPermission( "java.vendor", "read" ) );
permissions.add( new PropertyPermission( "java.vendor.url", "read" ) );
permissions.add( new PropertyPermission( "java.class.version", "read" ) );
permissions.add( new PropertyPermission( "java.vm.version", "read" ) );
permissions.add( new PropertyPermission( "java.vm.vendor", "read" ) );
permissions.add( new PropertyPermission( "java.vm.name", "read" ) );
permissions.add( new PropertyPermission( "java.specification.version", "read" ) );
permissions.add( new PropertyPermission( "java.specification.vendor", "read" ) );
permissions.add( new PropertyPermission( "java.specification.name", "read" ) );
permissions.add( new PropertyPermission( "java.vm.specification.version", "read" ) );
permissions.add( new PropertyPermission( "java.vm.specification.vendor", "read" ) );
permissions.add( new PropertyPermission( "java.vm.specification.name", "read" ) );
}
protected HashMap configureKeyStores( final Iterator it )
throws ConfigurationException
{
final HashMap keyStores = new HashMap();
while(it.hasNext())
{
final Configuration configuration = (Configuration)it.next();
final String type = configuration.getAttribute( "type" );
final String location = configuration.getAttribute( "location" );
final String name = configuration.getAttribute( "name" );
try
{
final KeyStore keyStore = KeyStore.getInstance( type );
final URL url = new URL( location );
final InputStream ins = url.openStream();
keyStore.load( ins, null );
keyStores.put( name, keyStore );
}
catch( final Exception e )
{
throw new ConfigurationException( "Error configuring keystore " + name, e );
}
}
return keyStores;
}
protected void configureGrants( final Iterator it,
final HashMap keyStores )
throws ConfigurationException
{
while(it.hasNext())
{
configureGrant( (Configuration)it.next(), keyStores );
}
}
protected void configureGrant( final Configuration configuration, final HashMap keyStores )
throws ConfigurationException
{
//<grant signed-by="Fred" code-base="file:${sar.home}/blocks/*" key-store="foo-keystore">
//<permission class="java.io.FilePermission" target="/tmp/*" action="read,write" />
//</grant>
final String signedBy = configuration.getAttribute( "signed-by", null );
final String keyStoreName = configuration.getAttribute( "key-store", null );
String codeBase = configuration.getAttribute( "code-base", null );
if( null != codeBase )
{
codeBase = expand( codeBase );
}
final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores );
Permissions permissions = null;
try { permissions = createPermissionSetFor( codeBase, signers ); }
catch( final MalformedURLException mue )
{
throw new ConfigurationException( "Malformed code-base " + codeBase, mue );
}
configurePermissions( configuration.getChildren( "permission" ),
permissions,
keyStores );
}
protected void configurePermissions( final Iterator it,
final Permissions permissions,
final HashMap keyStores )
throws ConfigurationException
{
while(it.hasNext())
{
configurePermission( (Configuration)it.next(), permissions, keyStores );
}
}
protected void configurePermission( final Configuration configuration,
final Permissions permissions,
final HashMap keyStores )
throws ConfigurationException
{
final String type = configuration.getAttribute( "class" );
final String actions = configuration.getAttribute( "actions", null );
final String signedBy = configuration.getAttribute( "signed-by", null );
final String keyStoreName = configuration.getAttribute( "key-store", null );
String target = configuration.getAttribute( "target", null );
if( null != target )
{
target = expand( target );
}
final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores );
final Permission permission = createPermission( type, target, actions, signers );
permissions.add( permission );
}
protected String expand( final String value )
throws ConfigurationException
{
try
{
final Object resolvedValue = PropertyUtil.resolveProperty( value, m_context, false );
return resolvedValue.toString();
}
catch( final PropertyException pe )
{
throw new ConfigurationException( "Error resolving property " + value, pe );
}
}
protected Permission createPermission( final String type,
final String target,
final String actions,
final Certificate[] signers )
throws ConfigurationException
{
if( null != signers )
{
return createUnresolvedPermission( type, target, actions, signers );
}
try
{
final Class c = Class.forName( type );
Class paramClasses[] = null;
Object params[] = null;
if( null == actions && null == target )
{
paramClasses = new Class[ 0 ];
params = new Object[ 0 ];
}
else if( null == actions )
{
paramClasses = new Class[1];
paramClasses[0] = String.class;
params = new Object[1];
params[0] = target;
}
else
{
paramClasses = new Class[2];
paramClasses[0] = String.class;
paramClasses[1] = String.class;
params = new Object[2];
params[0] = target;
params[1] = actions;
}
final Constructor constructor = c.getConstructor( paramClasses );
final Object o = constructor.newInstance( params );
return (Permission)o;
}
catch( final ClassNotFoundException cnfe )
{
return createUnresolvedPermission( type, target, actions, signers );
}
catch( final Exception e )
{
throw new ConfigurationException( "Failed to create permission " + type +
" due to " + e, e );
}
}
protected Permission createUnresolvedPermission( final String type,
final String target,
final String actions,
final Certificate[] signers )
{
return new UnresolvedPermission( type, target, actions, signers );
}
protected Certificate[] getSigners( final String signedBy,
String keyStoreName,
final HashMap keyStores )
throws ConfigurationException
{
if( null != signedBy && null == keyStoreName )
{
keyStoreName = "default";
}
Certificate[] signers = null;
if( null != signedBy )
{
signers = getCertificates( signedBy, keyStoreName, keyStores );
}
return signers;
}
protected Certificate[] getCertificates( final String signedBy,
final String keyStoreName,
final HashMap keyStores )
throws ConfigurationException
{
final KeyStore keyStore = (KeyStore)keyStores.get( keyStoreName );
if( null == keyStore )
{
throw new ConfigurationException( "Unable to aquire keyStore " + keyStoreName );
}
final ArrayList certificateSet = new ArrayList();
final StringTokenizer tokenizer = new StringTokenizer( signedBy, "," );
while( tokenizer.hasMoreTokens() )
{
final String alias = ((String)tokenizer.nextToken()).trim();
Certificate certificate = null;
try { certificate = keyStore.getCertificate( alias ); }
catch( final KeyStoreException kse )
{
throw new ConfigurationException( "Error aquiring certificate " + alias,
kse );
}
if( null == certificate )
{
throw new ConfigurationException( "Unable to locate alias " + alias +
" in keystore named " + keyStoreName );
}
if( !certificateSet.contains( certificate ) )
{
if( DEBUG ) getLogger().debug( "Certificate " + certificate );
certificateSet.add( certificate );
}
}
return (Certificate[])certificateSet.toArray( new Certificate[ 0 ] );
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/facilities/ThreadManager.java
Index: ThreadManager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.facilities;
import java.util.Hashtable;
import java.util.Iterator;
import org.apache.avalon.logger.AbstractLoggable;
import org.apache.avalon.atlantis.Facility;
import org.apache.framework.configuration.Configurable;
import org.apache.framework.configuration.Configuration;
import org.apache.framework.configuration.ConfigurationException;
import org.apache.avalon.thread.DefaultThreadPool;
import org.apache.framework.thread.ThreadManager;
import org.apache.framework.thread.ThreadPool;
/**
*
*
* @author <a href="mailto:fede@apache.org">Federico Barbieri</a>
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public class DefaultThreadManager
extends AbstractLoggable
implements Facility, ThreadManager, Configurable
{
protected final Hashtable m_pools = new Hashtable();
public void configure( final Configuration configuration )
throws ConfigurationException
{
final Iterator it = configuration.getChildren( "thread-group" );
while(it.hasNext())
{
final Configuration group = (Configuration)it.next();
final String name = group.getChild( "name" ).getValue();
final int priority = group.getChild( "priority" ).getValueAsInt( 5 );
final boolean isDaemon = group.getChild( "is-daemon" ).getValueAsBoolean( false );
final int minThreads = group.getChild( "min-threads" ).getValueAsInt( 5 );
final int maxThreads = group.getChild( "max-threads" ).getValueAsInt( 10 );
final int minSpareThreads = group.getChild( "min-spare-threads" ).
getValueAsInt( maxThreads - minThreads );
try
{
final DefaultThreadPool threadPool = new DefaultThreadPool( name, maxThreads );
threadPool.setDaemon( isDaemon );
//setupLogger( threadPool );
m_pools.put( name, threadPool );
}
catch( final Exception e )
{
throw new ConfigurationException( "Error creating thread pool " + name,
e );
}
}
}
public ThreadPool getDefaultThreadPool()
{
return getThreadPool( "default" );
}
public ThreadPool getThreadPool( final String name )
{
final ThreadPool threadPool = (ThreadPool)m_pools.get( name );
if( null == threadPool )
{
//Should this be a ComponentNotFoundException ????
throw new IllegalArgumentException( "No such thread group " + name );
}
return threadPool;
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/engine/jmx/Manager.java
Index: Manager.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.phoenix.engine.facilities;
import javax.management.MBeanServer;
/**
*
* @author <a href="mail@leosimons.com">Leo Simons</a>
*/
public class AvalonMBeanServer
{
private MBeanServer server;
public AvalonMBeanServer( MBeanServer server )
{
this.server = server;
}
}
1.1 jakarta-avalon-phoenix/proposal/4.0/src/java/org/apache/phoenix/facilities/Facility.java
Index: Facility.java
===================================================================
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE file.
*/
package org.apache.avalon.atlantis;
import org.apache.avalon.Component;
/**
* A Facility is a horizontal cut through the kernel.
* Unlike Components which offer a Service/Content interface, Facilitys
* are used to facilitate the non-Service/Form interface or life-cycle orientated
* methods of Components. See documentation for a clearer explanation.
*
* Example Facilities would be
* <ul>
* <li>ConfigurationRepository that stores configuration data for components</li>
* <li>ThreadFacility that allows components to run in threads</li>
* <li>ContextUtility that builds context information for components</li>
* <li>ExportFacility that exports components to external users (perhaps via RMI)</li>
* <li>NamingFacility that binds compoents to a name in a directory</li>
* <li>ManagementFacility that manages components via JMX</li>
* </ul>
*
* @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
*/
public interface Facility
extends Component
{
}
---------------------------------------------------------------------
To unsubscribe, e-mail: avalon-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: avalon-dev-help@jakarta.apache.org