From: <st...@us...> - 2007-07-11 20:10:45
|
Revision: 4634 http://svn.sourceforge.net/smartfrog/?rev=4634&view=rev Author: steve_l Date: 2007-07-11 13:09:12 -0700 (Wed, 11 Jul 2007) Log Message: ----------- SFOS-273: Deploy by Copy improvements the async queue is in there, with some stuff moved around. Needs tests. Modified Paths: -------------- trunk/core/components/www/src/org/smartfrog/services/www/ApplicationServerContext.java trunk/core/components/www/src/org/smartfrog/services/www/dbc/AbstractDbcDelegate.java trunk/core/components/www/src/org/smartfrog/services/www/dbc/DbcEarDelegate.java trunk/core/components/www/src/org/smartfrog/services/www/dbc/DbcWarDelegate.java trunk/core/components/www/src/org/smartfrog/services/www/dbc/DeployByCopyServer.java trunk/core/components/www/src/org/smartfrog/services/www/dbc/DeployByCopyServerImpl.java trunk/core/components/www/src/org/smartfrog/services/www/dbc/components.sf Added Paths: ----------- trunk/core/components/www/src/org/smartfrog/services/www/dbc/EndOfQueue.java trunk/core/components/www/src/org/smartfrog/services/www/dbc/QueuedFile.java trunk/core/components/www/src/org/smartfrog/services/www/servers/ Modified: trunk/core/components/www/src/org/smartfrog/services/www/ApplicationServerContext.java =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/ApplicationServerContext.java 2007-07-11 15:20:27 UTC (rev 4633) +++ trunk/core/components/www/src/org/smartfrog/services/www/ApplicationServerContext.java 2007-07-11 20:09:12 UTC (rev 4634) @@ -38,15 +38,15 @@ /** * {@value} */ - final static String ATTR_CONTEXT_PATH = "contextPath"; + String ATTR_CONTEXT_PATH = "contextPath"; /** * {@value} */ - final static String ATTR_SERVER = "server"; + String ATTR_SERVER = "server"; /** * absolute path is the path up to the first "*" {@value} */ - final static String ATTR_ABSOLUTE_PATH = "absolutePath"; + String ATTR_ABSOLUTE_PATH = "absolutePath"; /** * name or File reference of a file {@value} */ @@ -62,16 +62,16 @@ /** * start the component * - * @throws SmartFrogException - * @throws RemoteException + * @throws SmartFrogException for deployment problems + * @throws RemoteException for RMI/Networking problems */ void start() throws SmartFrogException, RemoteException; /** * this method is here for server-specific implementation classes, * - * @throws RemoteException - * @throws SmartFrogException + * @throws SmartFrogException for deployment problems + * @throws RemoteException for RMI/Networking problems */ public void terminate() throws RemoteException, SmartFrogException; @@ -79,8 +79,8 @@ /** * liveness check * - * @throws SmartFrogLivenessException - * @throws RemoteException + * @throws SmartFrogException for deployment problems + * @throws RemoteException for RMI/Networking problems */ void ping() throws SmartFrogLivenessException, RemoteException; } Modified: trunk/core/components/www/src/org/smartfrog/services/www/dbc/AbstractDbcDelegate.java =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/dbc/AbstractDbcDelegate.java 2007-07-11 15:20:27 UTC (rev 4633) +++ trunk/core/components/www/src/org/smartfrog/services/www/dbc/AbstractDbcDelegate.java 2007-07-11 20:09:12 UTC (rev 4634) @@ -27,21 +27,26 @@ import org.smartfrog.sfcore.prim.Prim; import java.io.File; -import java.io.IOException; import java.rmi.RemoteException; /** - * created 19-Jun-2006 16:43:01 + * This is the base class for all deploy by copy delegates. + * It deploys by copying in its start() operation. This is not a Prim derivative; + * it is a simple POJO that implements {@link ApplicationServerContext} + * Created 19-Jun-2006 16:43:01 */ public abstract class AbstractDbcDelegate implements ApplicationServerContext { - private File sourceFile; - private File destDir; - private File destFile; private DeployByCopyServerImpl server; private Prim declaration; + private QueuedFile operation; + /** + * Bind to a server, taking in a reference to the (possibly remote) owner interface) + * @param server owner server + * @param owner owner as a Prim interface. + */ public AbstractDbcDelegate(DeployByCopyServerImpl server, Prim owner) { this.server = server; this.declaration = owner; @@ -51,11 +56,28 @@ return declaration; } + /** + * Get the extension of this artifact. + * @return something like ".ear" + */ public abstract String getExtension(); + /** + * Base class deploy is a no-op. + * @throws SmartFrogException subclasses may throw this + * @throws RemoteException subclasses may throw this + */ public void deploy() throws SmartFrogException, RemoteException { } + /** + * Deploy by determining the source file, and doing a blocking copy. + * If the source file is missing, A {@link SmartFrogDeploymentException} with + * text {@link #ERROR_FILE_NOT_FOUND} is thrown. IOExceptions are passed on + * nested inside a {@link SmartFrogDeploymentException}. + * @throws SmartFrogException if the deployment failed + * @throws RemoteException for network problems. + */ public void start() throws SmartFrogException, RemoteException { String source = FileSystem.lookupAbsolutePath(getDeclaration(), @@ -65,11 +87,7 @@ true, null); //sanity check - sourceFile = new File(source); - if (!sourceFile.exists()) { - throw new SmartFrogDeploymentException(ERROR_FILE_NOT_FOUND + - sourceFile); - } + File sourceFile = new File(source); String filename = sourceFile.getName(); if (filename.endsWith(getExtension())) { filename = filename.substring(0, filename.length() - getExtension().length()); @@ -81,36 +99,51 @@ if (contextPath.startsWith("/")) { contextPath = contextPath.substring(1); } - String absolutePath = "/" + contextPath; + String absolutePath = '/' + contextPath; getDeclaration().sfReplaceAttribute(ATTR_ABSOLUTE_PATH, absolutePath); //create the full extension now. filename = contextPath + getExtension(); - //do nothing - destDir = server.getDestDir(); - destFile = new File(destDir, filename); - server.sfLog().info("Deploying " - +sourceFile.getAbsolutePath() - +" to " - +destFile.getAbsolutePath()); - try { - FileSystem.fCopy(sourceFile, destFile); - } catch (IOException e) { - throw SmartFrogDeploymentException.forward(e); + + //queue/execute the operation. + operation = server.queueCopy(sourceFile, filename); + pingOperation(); + } + + /** + * Poll for the completed state of the operation + * @throws SmartFrogException + */ + protected void pingOperation() throws SmartFrogException { + if (operation != null) { + operation.ping(); } } + /** + * Terminate by deleting the destination file. If it cannot be deleted + * (i.e. the file is locked), we queue a {@link File#deleteOnExit()} operation, + * which <i>may</i> delete it later. + * @throws RemoteException subclasses may throw this + * @throws SmartFrogException subclasses may throw this + */ public void terminate() throws RemoteException, SmartFrogException { //delete the destination file - server.sfLog().info("undeploying "+destFile); - if (destFile != null && destFile.exists() && !destFile.delete()) { - destFile.deleteOnExit(); - } + server.sfLog().info("undeploying "+operation); + operation.deleteDestFile(); } + /** + * Ping operation checks that the destination file exists + * @throws SmartFrogLivenessException if the destination file is absent + * @throws RemoteException subclasses may throw this + */ public void ping() throws SmartFrogLivenessException, RemoteException { - if (!destFile.exists()) { - throw new SmartFrogLivenessException("Deployed File " + destFile + " has disappeared"); + try { + pingOperation(); + } catch (SmartFrogException e) { + throw (SmartFrogLivenessException) + SmartFrogLivenessException.forward(e); } } } Modified: trunk/core/components/www/src/org/smartfrog/services/www/dbc/DbcEarDelegate.java =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/dbc/DbcEarDelegate.java 2007-07-11 15:20:27 UTC (rev 4633) +++ trunk/core/components/www/src/org/smartfrog/services/www/dbc/DbcEarDelegate.java 2007-07-11 20:09:12 UTC (rev 4634) @@ -23,6 +23,7 @@ import org.smartfrog.sfcore.prim.Prim; /** + * This delegate will queue copy operations when deploying EAR files. * created 19-Jun-2006 16:57:38 */ @@ -32,6 +33,10 @@ super(server, owner); } + /** + * Return the extension + * @return ".ear" + */ public String getExtension() { return ".ear"; } Modified: trunk/core/components/www/src/org/smartfrog/services/www/dbc/DbcWarDelegate.java =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/dbc/DbcWarDelegate.java 2007-07-11 15:20:27 UTC (rev 4633) +++ trunk/core/components/www/src/org/smartfrog/services/www/dbc/DbcWarDelegate.java 2007-07-11 20:09:12 UTC (rev 4634) @@ -23,6 +23,7 @@ import org.smartfrog.sfcore.prim.Prim; /** + * Deploy a WAR file * created 19-Jun-2006 16:57:38 */ @@ -32,6 +33,12 @@ super(server, owner); } + /** + * Return the extension + * + * @return ".war" + */ + public String getExtension() { return ".war"; } Modified: trunk/core/components/www/src/org/smartfrog/services/www/dbc/DeployByCopyServer.java =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/dbc/DeployByCopyServer.java 2007-07-11 15:20:27 UTC (rev 4633) +++ trunk/core/components/www/src/org/smartfrog/services/www/dbc/DeployByCopyServer.java 2007-07-11 20:09:12 UTC (rev 4634) @@ -39,10 +39,11 @@ public static final String ATTR_DEPLOY_DIR = "destDir"; /** - * Clean up directory: boolean + * Clean up directory: boolean. + * This is currently unused. * {@value} */ - public static final String ATTR_CLEAN_DIRECTORY = "cleanDir"; + public static final String ATTR_CLEAN_DIRECTORY = "cleanDirOnStartup"; /** @@ -60,5 +61,11 @@ */ public static final String ATTR_SHUTDOWN_COMPONENT = "shutdown"; + /** + * Flag to control whether or not a copy is synchronous. + * {@value} + */ + public static final String ATTR_SYNCHRONOUS_COPY = "synchronousCopy"; + } Modified: trunk/core/components/www/src/org/smartfrog/services/www/dbc/DeployByCopyServerImpl.java =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/dbc/DeployByCopyServerImpl.java 2007-07-11 15:20:27 UTC (rev 4633) +++ trunk/core/components/www/src/org/smartfrog/services/www/dbc/DeployByCopyServerImpl.java 2007-07-11 20:09:12 UTC (rev 4634) @@ -23,54 +23,71 @@ import org.smartfrog.services.www.JavaEnterpriseApplication; import org.smartfrog.services.www.JavaWebApplication; import org.smartfrog.services.www.ServletContextIntf; +import org.smartfrog.services.www.ApplicationServerContext; import org.smartfrog.sfcore.common.SmartFrogException; import org.smartfrog.sfcore.common.SmartFrogLivenessException; import org.smartfrog.sfcore.common.SmartFrogRuntimeException; +import org.smartfrog.sfcore.common.SmartFrogDeploymentException; import org.smartfrog.sfcore.componentdescription.ComponentDescription; import org.smartfrog.sfcore.logging.LogFactory; +import org.smartfrog.sfcore.prim.ChildMinder; +import org.smartfrog.sfcore.prim.Liveness; import org.smartfrog.sfcore.prim.Prim; import org.smartfrog.sfcore.prim.PrimImpl; import org.smartfrog.sfcore.prim.TerminationRecord; -import org.smartfrog.sfcore.prim.ChildMinder; -import org.smartfrog.sfcore.prim.Liveness; -import org.smartfrog.sfcore.utils.ComponentHelper; import org.smartfrog.sfcore.utils.ParentHelper; +import org.smartfrog.sfcore.utils.SmartFrogThread; import java.io.File; import java.rmi.RemoteException; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; -import java.util.Enumeration; /** + * Implementation of deploy-by-copy. * created 19-Jun-2006 15:53:07 */ -public class DeployByCopyServerImpl extends PrimImpl implements DeployByCopyServer, Runnable, +public class DeployByCopyServerImpl extends PrimImpl implements DeployByCopyServer, ChildMinder { - private List filesToCopy = new ArrayList(); + private final List/*<QueuedFile>*/ filesToCopy = new ArrayList/*<QueuedFile>*/(); private File destDir; private ComponentDescription startup; private ComponentDescription shutdown; private Prim startupPrim; private Prim shutdownPrim; - private ComponentHelper helper; private ParentHelper childminder; - private Thread thread; - private Throwable caughtException; + private SmartFrogThread thread; + private boolean synchronousCopy; + /** - * special file that is fed in to the queue to tell the thread to terminate * {@value} */ - private static File END_QUEUE_MARKER = new File("****END_QUEUE_MARKER****"); + public static final String ERROR_NO_SERVLETS = "Servlet contexts are not supported"; + /** + * {@value} + */ + public static final String ERROR_ALREADY_RUNNING = "The servlet is already running!"; + public DeployByCopyServerImpl() throws RemoteException { } + /** + * Startup: + * <ol> + * <li>Bind to the destination directory</li> + * <li>deploy and start the <i>startup</i> component if present + * <li>deploy but do not start the <i>shutdown</i> component if present + * <li>start the worker thread that accepts queued copy operations + * </li> + * @throws SmartFrogException for deployment problems + * @throws RemoteException RMI problems + */ public synchronized void sfStart() throws SmartFrogException, RemoteException { super.sfStart(); - helper = new ComponentHelper(this); childminder = new ParentHelper(this); //bind to and create the destination directory @@ -100,35 +117,46 @@ shutdownPrim.sfDeploy(); } + synchronousCopy=sfResolve(ATTR_SYNCHRONOUS_COPY,true,true); + //begin deploying things. - startWorkerThread(); + if(!synchronousCopy) { + startWorkerThread(); + } } /** * handle liveness check by throwing any fault received in the worker thread, then - * + * checking the health of the startup component. * @param source - * @throws SmartFrogLivenessException - * @throws RemoteException + * @throws SmartFrogLivenessException ping failure + * @throws RemoteException network failure */ public void sfPing(Object source) throws SmartFrogLivenessException, RemoteException { super.sfPing(source); - if (caughtException != null) { - throw (SmartFrogLivenessException) SmartFrogLivenessException.forward(caughtException); - } + //ping the child if (startupPrim != null) { startupPrim.sfPing(this); } } + /** + * Termination logic. + * At terminate time, we shutdown the copy thread, + * then kill the startup prim. + * If shutdown was not null, it is started and then immediately terminated (so it + * had better do its work in the start component) + * @param status + */ public synchronized void sfTerminateWith(TerminationRecord status) { + //close down the thread + queueFileToCopy(EndOfQueue.END_OF_QUEUE); super.sfTerminateWith(status); - //close down the thread - addFileToCopy(END_QUEUE_MARKER); + //kill the startup component if (startupPrim != null) { try { @@ -155,10 +183,6 @@ } - public synchronized void addFileToCopy(File file) { - filesToCopy.add(file); - filesToCopy.notify(); - } public File getDestDir() { return destDir; @@ -172,18 +196,32 @@ return shutdownPrim; } - public JavaWebApplication deployWebApplication(Prim webApplication) - throws RemoteException, SmartFrogException { + /** + * Factory for a DBC deployment + * @param webApplication the web application to deploy + * @return an instance of a {@link DbcWarDelegate} + */ + public JavaWebApplication deployWebApplication(Prim webApplication) { return new DbcWarDelegate(this, webApplication); } - public JavaEnterpriseApplication deployEnterpriseApplication(Prim enterpriseApplication) - throws RemoteException, SmartFrogException { + /** + * Deploy an EAR by returning an instance of {@link DbcEarDelegate} + * @param enterpriseApplication the EAR application to deploy + * @return a delegate + */ + public JavaEnterpriseApplication deployEnterpriseApplication(Prim enterpriseApplication) { return new DbcEarDelegate(this, enterpriseApplication); } - public ServletContextIntf deployServletContext(Prim servlet) throws RemoteException, SmartFrogException { - throw new SmartFrogException("Servlet contexts are not supported"); + /** + * DBC does not support servlet deployment, so an exception gets thrown + * @param servlet servlet to deploy + * @return never; we always throw an exception + * @throws SmartFrogException containing the text {@link #ERROR_NO_SERVLETS} + */ + public ServletContextIntf deployServletContext(Prim servlet) throws SmartFrogException { + throw new SmartFrogException(ERROR_NO_SERVLETS); } /** @@ -191,7 +229,7 @@ * * @param child child to add * - * @throws java.rmi.RemoteException In case of Remote/nework error + * @throws RemoteException In case of Remote/nework error */ public void sfAddChild(Liveness child) throws RemoteException { childminder.sfAddChild(child); @@ -204,7 +242,8 @@ * * @return Status of child removal * - * @throws java.rmi.RemoteException In case of Remote/nework error + * @throws SmartFrogRuntimeException if failed to remove + * @throws RemoteException In case of Remote/nework error */ public boolean sfRemoveChild(Liveness child) throws SmartFrogRuntimeException, RemoteException { @@ -218,7 +257,7 @@ * * @return true is child is present else false * - * @throws java.rmi.RemoteException In case of Remote/nework error + * @throws RemoteException In case of Remote/nework error */ public boolean sfContainsChild(Liveness child) throws RemoteException { return childminder.sfContainsChild(child); @@ -229,7 +268,7 @@ * * @return enumeration over children * - * @throws java.rmi.RemoteException In case of Remote/nework error + * @throws RemoteException In case of Remote/nework error */ public Enumeration sfChildren() throws RemoteException { return childminder.sfChildren(); @@ -238,28 +277,107 @@ /** * Start the component in a new thread. Synchronized. * - * @throws SmartFrogException + * @throws SmartFrogException with {@link #ERROR_ALREADY_RUNNING} if a worker + * thread is already live. */ private synchronized void startWorkerThread() throws SmartFrogException { if (thread != null) { - throw new SmartFrogException("We are already running!"); + throw new SmartFrogException(ERROR_ALREADY_RUNNING,this); } - thread = new Thread(this); - thread.run(); + thread = new SmartFrogThread(new QueueHandler()); + thread.start(); } + /** - * {@inheritDoc} + * Add a file to the copy queue + * + * @param file file to copy in */ - public void run() { - try { - } catch (Exception e) { - caughtException = e; - } finally { - //end of life - thread = null; + public void queueFileToCopy(QueuedFile file) { + synchronized(filesToCopy) { + filesToCopy.add(file); + filesToCopy.notify(); } } + /** + * Poll for the next file to copy + * @return the next entry, or {@link EndOfQueue#END_OF_QUEUE} for the end of the queue + */ + public QueuedFile pollNextFile() { + synchronized(filesToCopy) { + if(filesToCopy.isEmpty()) { + try { + filesToCopy.wait(); + } catch (InterruptedException e) { + //interrupted? End the queue + return EndOfQueue.END_OF_QUEUE; + } + } + return (QueuedFile) filesToCopy.remove(0); + } + } + + /** + * copy the file. This may be blocking or not, depending on the settings + * + * + * @param sourceFile the file to copy + * @param destinationName short name of the destination file + * @return the file (which may or may not be copied yet; it depends on the + * async flag) + * + * @throws SmartFrogDeploymentException if the IO failed + */ + protected QueuedFile queueCopy(File sourceFile,String destinationName) throws + SmartFrogDeploymentException { + if (!sourceFile.exists()) { + throw new SmartFrogDeploymentException( + ApplicationServerContext.ERROR_FILE_NOT_FOUND + + sourceFile, + this); + } + //determine the destination file (with the target extension) + File destFile = new File(destDir, destinationName); + QueuedFile queuedFile = new QueuedFile(sourceFile, destFile); + queuedFile.execute(this); + return queuedFile; + } + + /** + * Worker routine for asynchronous copy actions + */ + private class QueueHandler implements Runnable { + + + /** + * When an object implementing interface <code>Runnable</code> is used to + * create a thread, starting the thread causes the object's <code>run</code> + * method to be called in that separately executing thread. + * <p/> + * The general contract of the method <code>run</code> is that it may take + * any action whatsoever. + * + * @see Thread#run() + */ + public void run() { + boolean finished=false; + while(!finished) { + QueuedFile queuedFile = pollNextFile(); + if(queuedFile instanceof EndOfQueue) { + finished=true; + } else try { + //do the copy; this marks the file as processed + queuedFile.execute(DeployByCopyServerImpl.this); + } catch (SmartFrogDeploymentException e) { + //log the error. which is stored in the queuedFile + sfLog().error(e); + } + } + thread=null; + } + } + } Added: trunk/core/components/www/src/org/smartfrog/services/www/dbc/EndOfQueue.java =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/dbc/EndOfQueue.java (rev 0) +++ trunk/core/components/www/src/org/smartfrog/services/www/dbc/EndOfQueue.java 2007-07-11 20:09:12 UTC (rev 4634) @@ -0,0 +1,44 @@ +package org.smartfrog.services.www.dbc; + +import org.smartfrog.sfcore.common.SmartFrogDeploymentException; +import org.smartfrog.sfcore.prim.PrimImpl; + +/** + * Special end-of-queue marker + */ +public class EndOfQueue extends QueuedFile { + + /** + * Static end of queue marker instance + */ + public static final EndOfQueue END_OF_QUEUE =new EndOfQueue(); + + /** + * No need to create any new instances, is there? + */ + private EndOfQueue() { + super(null,null); + } + + + /** + * override the base class with an error. + * + * @param owner owner for logging and error context + * + * @throws SmartFrogDeploymentException if the IO failed + */ + protected void execute(PrimImpl owner) throws SmartFrogDeploymentException { + throw new SmartFrogDeploymentException("This is the end of the queue"); + } + + + /** + * Returns a string representation of the object. + * + * @return a string representation of the object. + */ + public String toString() { + return "END OF THE QUEUE"; + } +} Added: trunk/core/components/www/src/org/smartfrog/services/www/dbc/QueuedFile.java =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/dbc/QueuedFile.java (rev 0) +++ trunk/core/components/www/src/org/smartfrog/services/www/dbc/QueuedFile.java 2007-07-11 20:09:12 UTC (rev 4634) @@ -0,0 +1,144 @@ +package org.smartfrog.services.www.dbc; + +import org.smartfrog.sfcore.common.SmartFrogException; +import org.smartfrog.sfcore.common.SmartFrogDeploymentException; +import org.smartfrog.sfcore.common.SmartFrogLivenessException; +import org.smartfrog.sfcore.prim.PrimImpl; +import org.smartfrog.services.filesystem.FileSystem; + +import java.io.File; +import java.io.IOException; + +/** + */ +public class QueuedFile { + + private File source; + private File dest; + private volatile boolean processed; + private volatile SmartFrogException fault; + + + public QueuedFile(File source, File dest) { + this.source = source; + this.dest = dest; + } + + public File getSource() { + return source; + } + + + public File getDest() { + return dest; + } + + public boolean isProcessed() { + return processed; + } + + /** + * set the processed bit. + * @param processed + */ + public synchronized void setProcessed(boolean processed) { + this.processed = processed; + } + + /** + * Get any fault that was caught during the copy + * @return a fault or null for 'no fault' + */ + public SmartFrogException getFault() { + return fault; + } + + /** + * log any exception; implicitly sets the processed flag + * @param fault the fault that occurred + */ + public synchronized void setFault(SmartFrogException fault) { + setProcessed(true); + this.fault = fault; + } + + + /** + * Do a blocking copy; throws a fault if somethig failed, and saves the + * result in the QueuedFile value. The processed field of the queued file is + * always copied. + * + * @param owner owner for logging and error context + * @throws SmartFrogDeploymentException if the IO failed + */ + protected void execute(PrimImpl owner) + throws SmartFrogDeploymentException { + //get the destination directory + //determine the destination file (with the target extension) + owner.sfLog().info("Deploying " + toString()); + try { + //do the blocking copy + FileSystem.fCopy(source, dest); + } catch (IOException e) { + SmartFrogDeploymentException fault = + new SmartFrogDeploymentException("Failed: " + this, + e, + owner, + owner.sfContext()); + setFault(fault); + throw fault; + } finally { + setProcessed(true); + } + } + + /** + * Check the health of this operation. + * + * The method returns false if the operation has not completed, + * true if it has and all is well. An exception is thrown + * if the copy failed. + * If the destination file is now missing, a {@link SmartFrogLivenessException} + * is thrown. + * @return true if the copy completed and the destination file is present + * @throws SmartFrogException for copy or liveness failures. + */ + public synchronized boolean ping() throws SmartFrogException { + if (!isProcessed()) { + return false; + } + if (getFault() != null) { + throw getFault(); + } else { + if (!getDest().exists()) { + throw new SmartFrogLivenessException( + "Deployed File " + + getDest() + + " has disappeared from " + + this); + } + } + return true; + } + + /** + * Delete the destination file, or queue it for later destruction + */ + public void deleteDestFile() { + if (dest != null && dest.exists() && !dest.delete()) { + dest.deleteOnExit(); + } + } + + + /** + * Returns a string representation of the object. + * + * @return a string representation of the object. + */ + public String toString() { + return source.getAbsolutePath() + + " copied to " + + dest.getAbsolutePath(); + } +} Modified: trunk/core/components/www/src/org/smartfrog/services/www/dbc/components.sf =================================================================== --- trunk/core/components/www/src/org/smartfrog/services/www/dbc/components.sf 2007-07-11 15:20:27 UTC (rev 4633) +++ trunk/core/components/www/src/org/smartfrog/services/www/dbc/components.sf 2007-07-11 20:09:12 UTC (rev 4634) @@ -22,23 +22,25 @@ /** - * schema for the base jetty server extends - * base webserver schema + * The deploy by copy component takes a destination directory. + * an optional startup component */ DeployByCopyServerSchema extends Schema { destDir extends FilenameType; startup extends OptionalCD; shutdown extends OptionalCD; + synchronousCopy extends Boolean; } /** - * this is not yet complete enough to be instantiable + * This server */ DeployByCopyServer extends ApplicationServer { sfClass "org.smartfrog.services.www.dbc.DeployByCopyServerImpl"; deployByCopyServerSchema extends DeployByCopyServerSchema; serverHost "localhost"; port 8080; + synchronousCopy true; supportsServletContext false; supportsWAR true; supportsEAR true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |