diff --git a/config/alfresco/model/wcmAppModel.xml b/config/alfresco/model/wcmAppModel.xml index 574c74ce47..d5095cd657 100644 --- a/config/alfresco/model/wcmAppModel.xml +++ b/config/alfresco/model/wcmAppModel.xml @@ -322,6 +322,10 @@ Source Path d:text + + Excludes + d:text + Allocated To d:text @@ -450,6 +454,10 @@ Source Path Used d:text + + Excludes Used + d:text + Source Path Used d:text diff --git a/source/java/org/alfresco/model/WCMAppModel.java b/source/java/org/alfresco/model/WCMAppModel.java index 240a11cd8d..c5ccf19f33 100644 --- a/source/java/org/alfresco/model/WCMAppModel.java +++ b/source/java/org/alfresco/model/WCMAppModel.java @@ -86,6 +86,7 @@ public interface WCMAppModel static final QName PROP_DEPLOYSERVERURL = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverurl"); static final QName PROP_DEPLOYSERVERTARGET = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservertarget"); static final QName PROP_DEPLOYSOURCEPATH = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deploysourcepath"); + static final QName PROP_DEPLOYEXCLUDES = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployexcludes"); static final QName PROP_DEPLOYSERVERALLOCATEDTO = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverallocatedto"); static final QName PROP_DEPLOYONAPPROVAL = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployonapproval"); @@ -111,6 +112,7 @@ public interface WCMAppModel static final QName PROP_DEPLOYSERVERUSERNAMEUSED = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverusernameused"); static final QName PROP_DEPLOYSERVERTARGETUSED = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservertargetused"); static final QName PROP_DEPLOYSOURCEPATHUSED = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deploysourcepathused"); + static final QName PROP_DEPLOYEXCLUDESUSED = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployexcludesused"); static final QName PROP_DEPLOYSERVERURLUSED = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverurlused"); // AVM webapp aspect diff --git a/source/java/org/alfresco/repo/avm/actions/AVMDeployWebsiteAction.java b/source/java/org/alfresco/repo/avm/actions/AVMDeployWebsiteAction.java index fb1bcdf4a9..dc060de470 100644 --- a/source/java/org/alfresco/repo/avm/actions/AVMDeployWebsiteAction.java +++ b/source/java/org/alfresco/repo/avm/actions/AVMDeployWebsiteAction.java @@ -15,11 +15,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing */ @@ -29,6 +29,7 @@ import java.io.PrintWriter; import java.io.Serializable; import java.io.StringWriter; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -54,12 +55,13 @@ import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; +import org.alfresco.util.RegexNameMatcher; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Deploys a website to a remote server. - * + * * @author gavinc */ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase @@ -84,26 +86,26 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase private static Log logger = LogFactory.getLog(AVMDeployWebsiteAction.class); private static Log delayDeploymentLogger = LogFactory.getLog("alfresco.deployment.delay"); - + /** * Calculate the URI representation of a server from the given set of properties - * - * @param props Set of properties to calculate URI from + * + * @param props Set of properties to calculate URI from */ public static String calculateServerUri(Map props) { StringBuilder uri = new StringBuilder(); - + // prefix the uri if necessary String type = (String)props.get(WCMAppModel.PROP_DEPLOYTYPE); if (WCMAppModel.CONSTRAINT_FILEDEPLOY.equals(type)) { uri.append(FILE_SERVER_PREFIX); } - + // append server name uri.append((String)props.get(WCMAppModel.PROP_DEPLOYSERVERHOST)); - + // append port (if present) Integer port = (Integer)props.get(WCMAppModel.PROP_DEPLOYSERVERPORT); if (port != null) @@ -111,23 +113,23 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase uri.append(":"); uri.append(port.toString()); } - + return uri.toString(); } - + /** * Sets the delay to use before starting the deployment - * + * * @param delay The delay in seconds */ public void setDelay(int delay) { this.delay = delay; } - + /** * Sets the default RMI port for Alfresco server deployments - * + * * @param defaultAlfrescoRmiPort port number */ public void setDefaultAlfrescoRmiPort(int defaultAlfrescoRmiPort) @@ -137,7 +139,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase /** * Sets the default RMI port for File system deployments - * + * * @param defaultReceiverRmiPort port number */ public void setDefaultReceiverRmiPort(int defaultReceiverRmiPort) @@ -147,7 +149,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase /** * Sets the default remote username to use for deployments - * + * * @param defaultRemoteUsername Default remote username */ public void setDefaultRemoteUsername(String defaultRemoteUsername) @@ -157,7 +159,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase /** * Sets the default remote password to use for deployments - * + * * @param defaultRemotePassword Default remote password */ public void setDefaultRemotePassword(String defaultRemotePassword) @@ -167,7 +169,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase /** * Sets the default target name to use on file system receivers - * + * * @param defaultTargetName Default target name */ public void setDefaultTargetName(String defaultTargetName) @@ -182,7 +184,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase { this.nodeService = service; } - + /** * @param contentService The ContentService instance */ @@ -211,7 +213,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase paramList.add(new ParameterDefinitionImpl(PARAM_CALLBACK, DataTypeDefinition.ANY, false, getParamDisplayLabel(PARAM_CALLBACK))); } - + @Override protected void executeImpl(Action action, NodeRef actionedUponNodeRef) { @@ -219,43 +221,43 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(actionedUponNodeRef); int version = avmVersionPath.getFirst(); String path = avmVersionPath.getSecond(); - + // get store name and path parts. String [] storePath = path.split(":"); if (storePath.length != 2) { throw new AVMSyncException("Malformed source path: " + path); } - + // get the NodeRef representing the website being deployed NodeRef websiteRef = (NodeRef)action.getParameterValue(PARAM_WEBPROJECT); if (this.nodeService.exists(websiteRef) == false) { - throw new IllegalStateException("The website NodeRef (" + websiteRef + + throw new IllegalStateException("The website NodeRef (" + websiteRef + ") provided does not exist!"); } - + // get the NodeRef representing the server to deploy to NodeRef serverRef = (NodeRef)action.getParameterValue(PARAM_SERVER); if (this.nodeService.exists(serverRef) == false) { - throw new IllegalStateException("The server NodeRef (" + serverRef + + throw new IllegalStateException("The server NodeRef (" + serverRef + ") provided does not exist!"); } - + // get the NodeRef representing the deployment attempt this one is part of NodeRef attemptRef = (NodeRef)action.getParameterValue(PARAM_ATTEMPT); - + // TODO: if attempt reference is null create one now for this deployment, for now throw error if (this.nodeService.exists(attemptRef) == false) { - throw new IllegalStateException("The attempt NodeRef (" + serverRef + + throw new IllegalStateException("The attempt NodeRef (" + serverRef + ") provided does not exist!"); } - + // get the callback object DeploymentCallback callback = (DeploymentCallback)action.getParameterValue(PARAM_CALLBACK); - + // get the other data from the deploymentserver object Map serverProps = nodeService.getProperties(serverRef); String serverUri = calculateServerUri(serverProps); @@ -266,14 +268,15 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase boolean fileServerDeployment = WCMAppModel.CONSTRAINT_FILEDEPLOY.equals( serverProps.get(WCMAppModel.PROP_DEPLOYTYPE)); String sourcePath = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSOURCEPATH); + String excludes = (String)serverProps.get(WCMAppModel.PROP_DEPLOYEXCLUDES); String targetName = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSERVERTARGET); String targetPath = path; - + if (fileServerDeployment == false) { - // if "localhost" is passed as the target server add "live" to the end of the + // if "localhost" is passed as the target server add "live" to the end of the // store name, this store will then get created automatically. - + // TODO: Check that the actual host name of the machine hasn't been passed if (port == null && (host.equalsIgnoreCase("localhost") || host.equalsIgnoreCase("127.0.0.1"))) @@ -281,7 +284,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase targetPath = storePath[0] + "live:" + storePath[1]; } } - + // get defaults for data not provided in server node if (port == null) { @@ -294,22 +297,22 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase port = this.defaultAlfRmiPort; } } - + if (remoteUsername == null || remoteUsername.length() == 0) { remoteUsername = this.defaultRemoteUsername; } - + if (remotePassword == null || remotePassword.length() == 0) { remotePassword = this.defaultRemotePassword; } - + if (targetName == null || targetName.length() == 0) { targetName = this.defaultTargetName; } - + // determine the actual source path if (sourcePath != null && sourcePath.length() > 0) { @@ -318,26 +321,35 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase { sourcePath = "/" + sourcePath; } - + // append to the root path path = path + sourcePath; } - + + // determine if a NameMatcher is required (if an exclude is present) + RegexNameMatcher regexMatcher = null; + if (excludes != null && excludes.length() > 0) + { + regexMatcher = new RegexNameMatcher(); + List patterns = new ArrayList(1); + patterns.add(excludes); + regexMatcher.setPatterns(patterns); + } // take a note of the current date/time Date startDate = new Date(); - + if (logger.isDebugEnabled()) - logger.debug("Starting deployment of " + actionedUponNodeRef.toString() + + logger.debug("Starting deployment of " + actionedUponNodeRef.toString() + " to " + serverUri + " at " + startDate); - + if (delayDeploymentLogger.isDebugEnabled() && delay > 0) { delayDeploymentLogger.debug("Delaying deployment by " + delay + "s..."); - - // add a delay for testing purposes if the delay logger level is debug + + // add a delay for testing purposes if the delay logger level is debug try { Thread.sleep(1000*delay); } catch (Throwable e) {} } - + // make the deploy call passing in the DeploymentCallback, if present Throwable deployError = null; DeploymentReport report = null; @@ -347,31 +359,41 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase if (fileServerDeployment) { if (logger.isDebugEnabled()) - logger.debug("Performing file server deployment to " + host + ":" + port + + logger.debug("Performing file server deployment to " + host + ":" + port + " using deploymentserver: " + serverProps); - + // TODO: Added new NameMatcher parameter to deploy methods. It acts as a filter. // Any matching path names are ignored for deployment purposes. - report = this.deployService.deployDifferenceFS(version, path, host, port, - remoteUsername, remotePassword, targetName, null, true, false, false, callback); + List callbacks = new ArrayList(); + if (callback != null) + { + callbacks.add(callback); + } + report = this.deployService.deployDifferenceFS(version, path, host, port, + remoteUsername, remotePassword, targetName, regexMatcher, true, false, false, callbacks); } else { if (logger.isDebugEnabled()) - logger.debug("Performing Alfresco deployment to " + host + ":" + port + + logger.debug("Performing Alfresco deployment to " + host + ":" + port + " using deploymentserver: " + serverProps); - + // TODO: Added new NameMatcher parameter to deploy methods. It acts as a filter. // Any matching path names are ignored for deployment purposes. - report = this.deployService.deployDifference(version, path, host, port, - remoteUsername, remotePassword, targetPath, null, true, false, false, callback); + List callbacks = new ArrayList(); + if (callback != null) + { + callbacks.add(callback); + } + report = this.deployService.deployDifference(version, path, host, port, + remoteUsername, remotePassword, targetPath, regexMatcher, true, false, false, callbacks); } } catch (Throwable err) { deployError = err; logger.error(deployError); - + // report the error to the callback object // TODO: See if this can be incorporated into the DeploymentCallback I/F if (callback != null) @@ -402,62 +424,64 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase if (logger.isDebugEnabled()) logger.debug("Failed to apply differences to " + serverUri); } - + // create the deployment report node - createDeploymentReportNode(report, attemptRef, serverProps, version, + createDeploymentReportNode(report, attemptRef, serverProps, version, websiteRef, startDate, deployError); } /** * Creates a deployment report node as a child of the given website. - * - * @param report The DeploymentReport result from the deploy, + * + * @param report The DeploymentReport result from the deploy, * will be null if the deploy failed * @param attempt NodeRef of the attempt the deploy was part of * @param serverProps The properties of the server the deploy was going to * @param version The version of the site bebing deployed (the snapshot) * @param websiteRef The NodeRef of the folder representing the website * @param startDate The date/time the deployment started - * @param error The error that caused the deployment to fail, null if the + * @param error The error that caused the deployment to fail, null if the * deployment was successful * @return The created deployment report NodeRef */ private NodeRef createDeploymentReportNode(DeploymentReport report, NodeRef attempt, - Map serverProps, int version, NodeRef websiteRef, + Map serverProps, int version, NodeRef websiteRef, Date startDate, Throwable error) { NodeRef reportRef = null; - + String serverUri = calculateServerUri(serverProps); Map reportProps = new HashMap(4, 1.0f); reportProps.put(WCMAppModel.PROP_DEPLOYSERVER, serverUri); reportProps.put(WCMAppModel.PROP_DEPLOYVERSION, version); reportProps.put(WCMAppModel.PROP_DEPLOYSTARTTIME, startDate); reportProps.put(WCMAppModel.PROP_DEPLOYENDTIME, new Date()); - reportProps.put(WCMAppModel.PROP_DEPLOYSERVERNAMEUSED, + reportProps.put(WCMAppModel.PROP_DEPLOYSERVERNAMEUSED, serverProps.get(WCMAppModel.PROP_DEPLOYSERVERNAME)); - reportProps.put(WCMAppModel.PROP_DEPLOYSERVERUSERNAMEUSED, + reportProps.put(WCMAppModel.PROP_DEPLOYSERVERUSERNAMEUSED, serverProps.get(WCMAppModel.PROP_DEPLOYSERVERUSERNAME)); - reportProps.put(WCMAppModel.PROP_DEPLOYSERVERTARGETUSED, + reportProps.put(WCMAppModel.PROP_DEPLOYSERVERTARGETUSED, serverProps.get(WCMAppModel.PROP_DEPLOYSERVERTARGET)); - reportProps.put(WCMAppModel.PROP_DEPLOYSOURCEPATHUSED, + reportProps.put(WCMAppModel.PROP_DEPLOYSOURCEPATHUSED, serverProps.get(WCMAppModel.PROP_DEPLOYSOURCEPATH)); - reportProps.put(WCMAppModel.PROP_DEPLOYSERVERURLUSED, + reportProps.put(WCMAppModel.PROP_DEPLOYEXCLUDESUSED, + serverProps.get(WCMAppModel.PROP_DEPLOYEXCLUDES)); + reportProps.put(WCMAppModel.PROP_DEPLOYSERVERURLUSED, serverProps.get(WCMAppModel.PROP_DEPLOYSERVERURL)); - + reportProps.put(WCMAppModel.PROP_DEPLOYSUCCESSFUL, (report != null)); if (report == null && error != null) { // add error message as fail reason if appropriate reportProps.put(WCMAppModel.PROP_DEPLOYFAILEDREASON, error.getMessage()); } - reportRef = this.nodeService.createNode(attempt, - WCMAppModel.ASSOC_DEPLOYMENTREPORTS, WCMAppModel.ASSOC_DEPLOYMENTREPORTS, + reportRef = this.nodeService.createNode(attempt, + WCMAppModel.ASSOC_DEPLOYMENTREPORTS, WCMAppModel.ASSOC_DEPLOYMENTREPORTS, WCMAppModel.TYPE_DEPLOYMENTREPORT, reportProps).getChildRef(); ContentWriter writer = contentService.getWriter(reportRef, ContentModel.PROP_CONTENT, true); writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); writer.setEncoding("UTF-8"); - + if (report == null) { if (error == null) @@ -484,14 +508,14 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase builder.append(event.getDestination()); builder.append("\r\n"); } - + writer.putContent(builder.toString()); } - + if (logger.isDebugEnabled()) - logger.debug("Created deplyoment report node (" + reportRef + ") for server " + + logger.debug("Created deplyoment report node (" + reportRef + ") for server " + serverUri); - + return reportRef; } } diff --git a/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java b/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java index c5f0efc6f2..fc53aefdc3 100644 --- a/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java +++ b/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -161,7 +160,11 @@ public class DeploymentServiceImpl implements DeploymentService /* (non-Javadoc) * @see org.alfresco.service.cmr.avm.deploy.DeploymentService#deployDifference(int, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean) */ - public DeploymentReport deployDifference(int version, String srcPath, String hostName, int port, String userName, String password, String dstPath, NameMatcher matcher, boolean createDst, boolean dontDelete, boolean dontDo, DeploymentCallback callback) + public DeploymentReport deployDifference(int version, String srcPath, String hostName, + int port, String userName, String password, + String dstPath, NameMatcher matcher, boolean createDst, + boolean dontDelete, boolean dontDo, + List callbacks) { DeploymentDestination dest = getLock(hostName, port); synchronized (dest) @@ -170,12 +173,15 @@ public class DeploymentServiceImpl implements DeploymentService { DeploymentReport report = new DeploymentReport(); AVMRemote remote = getRemote(hostName, port, userName, password); - if (callback != null) + if (callbacks != null) { DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.START, new Pair(version, srcPath), dstPath); - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } if (version < 0) { @@ -224,9 +230,12 @@ public class DeploymentServiceImpl implements DeploymentService new Pair(version, srcPath), dstPath); report.add(event); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } if (dontDo) { @@ -234,12 +243,15 @@ public class DeploymentServiceImpl implements DeploymentService } copyDirectory(version, srcRoot, dstParent, remote, matcher); remote.createSnapshot(storePath[0], "Deployment", "Post Deployment Snapshot."); - if (callback != null) + if (callbacks != null) { event = new DeploymentEvent(DeploymentEvent.Type.END, new Pair(version, srcPath), dstPath); - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } return report; } @@ -250,19 +262,32 @@ public class DeploymentServiceImpl implements DeploymentService // The corresponding directory exists so recursively deploy. try { - deployDirectoryPush(version, srcRoot, dstRoot, remote, matcher, dontDelete, dontDo, report, callback); + deployDirectoryPush(version, srcRoot, dstRoot, remote, matcher, dontDelete, dontDo, report, callbacks); remote.createSnapshot(storePath[0], "Deployment", "Post Deployment Snapshot."); - if (callback != null) + if (callbacks != null) { DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.END, new Pair(version, srcPath), dstPath); - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } return report; } catch (AVMException e) { + if (callbacks != null) + { + DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.FAILED, + new Pair(version, srcPath), + dstPath); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } + } try { if (snapshot != -1) @@ -276,9 +301,23 @@ public class DeploymentServiceImpl implements DeploymentService { throw new AVMException("Failed to rollback to version " + snapshot + " on " + hostName, ee); } - throw new AVMException("Deployment to " + hostName + "failed.", e); + throw new AVMException("Deployment to " + hostName + " failed.", e); } } + catch (Exception e) + { + if (callbacks != null) + { + DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.FAILED, + new Pair(version, srcPath), + dstPath); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } + } + throw new AVMException("Deployment to " + hostName + " failed.", e); + } finally { fTicketHolder.setTicket(null); @@ -300,7 +339,7 @@ public class DeploymentServiceImpl implements DeploymentService NameMatcher matcher, boolean dontDelete, boolean dontDo, DeploymentReport report, - DeploymentCallback callback) + List callbacks) { if (src.getGuid().equals(dst.getGuid())) { @@ -321,7 +360,7 @@ public class DeploymentServiceImpl implements DeploymentService AVMNodeDescriptor dstNode = dstList.get(name); if (!excluded(matcher, srcNode.getPath(), dstNode != null ? dstNode.getPath() : null)) { - deploySinglePush(version, srcNode, dst, dstNode, remote, matcher, dontDelete, dontDo, report, callback); + deploySinglePush(version, srcNode, dst, dstNode, remote, matcher, dontDelete, dontDo, report, callbacks); } } // Delete nodes that are missing in the source. @@ -343,9 +382,12 @@ public class DeploymentServiceImpl implements DeploymentService source, destination); report.add(event); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } if (dontDo) { @@ -372,7 +414,7 @@ public class DeploymentServiceImpl implements DeploymentService NameMatcher matcher, boolean dontDelete, boolean dontDo, DeploymentReport report, - DeploymentCallback callback) + List callbacks) { // Destination does not exist. if (dst == null) @@ -387,9 +429,12 @@ public class DeploymentServiceImpl implements DeploymentService source, destination); report.add(event); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } if (dontDo) { @@ -405,9 +450,12 @@ public class DeploymentServiceImpl implements DeploymentService source, destination); report.add(event); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } if (dontDo) { @@ -426,7 +474,7 @@ public class DeploymentServiceImpl implements DeploymentService // If the destination is also a directory, recursively deploy. if (dst.isDirectory()) { - deployDirectoryPush(version, src, dst, remote, matcher, dontDelete, dontDo, report, callback); + deployDirectoryPush(version, src, dst, remote, matcher, dontDelete, dontDo, report, callbacks); return; } Pair source = @@ -435,9 +483,12 @@ public class DeploymentServiceImpl implements DeploymentService DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED, source, destination); report.add(event); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } if (dontDo) { @@ -462,9 +513,12 @@ public class DeploymentServiceImpl implements DeploymentService source, destination); report.add(event); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } if (dontDo) { @@ -483,9 +537,12 @@ public class DeploymentServiceImpl implements DeploymentService source, destination); report.add(event); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } if (dontDo) { @@ -735,40 +792,66 @@ public class DeploymentServiceImpl implements DeploymentService /* (non-Javadoc) * @see org.alfresco.service.cmr.avm.deploy.DeploymentService#deployDifferenceFS(int, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean) */ - public DeploymentReport deployDifferenceFS(int version, String srcPath, String hostName, int port, String userName, String password, String target, NameMatcher matcher, boolean createDst, boolean dontDelete, boolean dontDo, DeploymentCallback callback) + public DeploymentReport deployDifferenceFS(int version, String srcPath, String hostName, + int port, String userName, String password, + String target, NameMatcher matcher, boolean createDst, + boolean dontDelete, boolean dontDo, + List callbacks) { DeploymentReport report = new DeploymentReport(); DeploymentReceiverService service = getReceiver(hostName, port); - DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.START, - new Pair(version, srcPath), - target); - if (callback != null) + String ticket = null; + try { - callback.eventOccurred(event); + DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.START, + new Pair(version, srcPath), + target); + if (callbacks != null) + { + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } + } + report.add(event); + String storeName = srcPath.substring(0, srcPath.indexOf(':')); + System.out.println(storeName); + if (version < 0) + { + version = fAVMService.createSnapshot(storeName, null, null).get(storeName); + } + ticket = service.begin(target, userName, password); + deployDirectoryPush(service, ticket, report, callbacks, version, srcPath, "/", matcher); + service.commit(ticket); + event = new DeploymentEvent(DeploymentEvent.Type.END, + new Pair(version, srcPath), + target); + if (callbacks != null) + { + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } + } + report.add(event); + return report; } - report.add(event); - String storeName = srcPath.substring(0, srcPath.indexOf(':')); - System.out.println(storeName); - if (version < 0) + catch (Exception e) { - version = fAVMService.createSnapshot(storeName, null, null).get(storeName); + DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.FAILED, + new Pair(version, srcPath), + target); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } + service.abort(ticket); + throw new AVMException("Deployment to: " + target + " failed.", e); } - String ticket = service.begin(target, userName, password); - deployDirectoryPush(service, ticket, report, callback, version, srcPath, "/", matcher); - service.commit(ticket); - event = new DeploymentEvent(DeploymentEvent.Type.END, - new Pair(version, srcPath), - target); - if (callback != null) - { - callback.eventOccurred(event); - } - report.add(event); - return report; } private void deployDirectoryPush(DeploymentReceiverService service, String ticket, - DeploymentReport report, DeploymentCallback callback, + DeploymentReport report, List callbacks, int version, String srcPath, String dstPath, NameMatcher matcher) { @@ -804,9 +887,12 @@ public class DeploymentServiceImpl implements DeploymentService DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.DELETED, new Pair(version, extendPath(srcPath, dst.getName())), newDstPath); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } report.add(event); } @@ -818,7 +904,7 @@ public class DeploymentServiceImpl implements DeploymentService { if (!excluded(matcher, src.getPath(), null)) { - copy(service, ticket, report, callback, version, src, dstPath, matcher); + copy(service, ticket, report, callbacks, version, src, dstPath, matcher); } src = null; continue; @@ -828,7 +914,7 @@ public class DeploymentServiceImpl implements DeploymentService { if (!excluded(matcher, src.getPath(), null)) { - copy(service, ticket, report, callback, version, src, dstPath, matcher); + copy(service, ticket, report, callbacks, version, src, dstPath, matcher); } src = null; continue; @@ -846,7 +932,7 @@ public class DeploymentServiceImpl implements DeploymentService String extendedPath = extendPath(dstPath, dst.getName()); if (!excluded(matcher, src.getPath(), extendedPath)) { - copyFile(service, ticket, report, callback, version, src, + copyFile(service, ticket, report, callbacks, version, src, extendedPath); } src = null; @@ -863,7 +949,7 @@ public class DeploymentServiceImpl implements DeploymentService String extendedPath = extendPath(dstPath, dst.getName()); if (!excluded(matcher, src.getPath(), extendedPath)) { - deployDirectoryPush(service, ticket, report, callback, version, src.getPath(), extendPath(dstPath, dst.getName()), matcher); + deployDirectoryPush(service, ticket, report, callbacks, version, src.getPath(), extendPath(dstPath, dst.getName()), matcher); } src = null; dst = null; @@ -871,7 +957,7 @@ public class DeploymentServiceImpl implements DeploymentService } if (!excluded(matcher, src.getPath(), null)) { - copy(service, ticket, report, callback, version, src, dstPath, matcher); + copy(service, ticket, report, callbacks, version, src, dstPath, matcher); } src = null; dst = null; @@ -884,9 +970,12 @@ public class DeploymentServiceImpl implements DeploymentService DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.DELETED, new Pair(version, extendPath(srcPath, dst.getName())), newDstPath); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } report.add(event); dst = null; @@ -904,7 +993,7 @@ public class DeploymentServiceImpl implements DeploymentService * @param dstPath */ private void copyFile(DeploymentReceiverService service, String ticket, - DeploymentReport report, DeploymentCallback callback, int version, + DeploymentReport report, List callbacks, int version, AVMNodeDescriptor src, String dstPath) { InputStream in = fAVMService.getFileInputStream(src); @@ -916,9 +1005,12 @@ public class DeploymentServiceImpl implements DeploymentService DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED, new Pair(version, src.getPath()), dstPath); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } report.add(event); } @@ -940,13 +1032,13 @@ public class DeploymentServiceImpl implements DeploymentService * @param parentPath */ private void copy(DeploymentReceiverService service, String ticket, - DeploymentReport report, DeploymentCallback callback, + DeploymentReport report, List callbacks, int version, AVMNodeDescriptor src, String parentPath, NameMatcher matcher) { String dstPath = extendPath(parentPath, src.getName()); if (src.isFile()) { - copyFile(service, ticket, report, callback, version, src, dstPath); + copyFile(service, ticket, report, callbacks, version, src, dstPath); return; } // src is a directory. @@ -954,9 +1046,12 @@ public class DeploymentServiceImpl implements DeploymentService DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED, new Pair(version, src.getPath()), dstPath); - if (callback != null) + if (callbacks != null) { - callback.eventOccurred(event); + for (DeploymentCallback callback : callbacks) + { + callback.eventOccurred(event); + } } report.add(event); Map listing = fAVMService.getDirectoryListing(src); @@ -964,7 +1059,7 @@ public class DeploymentServiceImpl implements DeploymentService { if (!excluded(matcher, child.getPath(), null)) { - copy(service, ticket, report, callback, version, child, dstPath, matcher); + copy(service, ticket, report, callbacks, version, child, dstPath, matcher); } } } diff --git a/source/java/org/alfresco/service/cmr/avm/deploy/DeploymentEvent.java b/source/java/org/alfresco/service/cmr/avm/deploy/DeploymentEvent.java index 9ac3d06ac5..77ae409852 100644 --- a/source/java/org/alfresco/service/cmr/avm/deploy/DeploymentEvent.java +++ b/source/java/org/alfresco/service/cmr/avm/deploy/DeploymentEvent.java @@ -15,11 +15,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ @@ -33,7 +33,7 @@ import org.alfresco.util.Pair; * Interface for Deployment Events. * @author britt */ -public class DeploymentEvent implements Serializable +public class DeploymentEvent implements Serializable { private static final long serialVersionUID = 2696116904379321786L; @@ -47,13 +47,14 @@ public class DeploymentEvent implements Serializable UPDATED, // Overwrote the destination. DELETED, // Deleted the destination node. START, // A Deployment has begun. - END // A Deployment has ended. + END, // A Deployment has ended. + FAILED // A Deployment failed. }; - + private Type fType; - + private Pair fSource; - + private String fDestination; public DeploymentEvent(Type type, Pair source, String destination) @@ -62,7 +63,7 @@ public class DeploymentEvent implements Serializable fSource = source; fDestination = destination; } - + /** * Get the type of the event. * @return The type. @@ -71,7 +72,7 @@ public class DeploymentEvent implements Serializable { return fType; } - + /** * Get the source node version and path. * @return @@ -89,7 +90,7 @@ public class DeploymentEvent implements Serializable { return fDestination; } - + /** * Get a String representation. */ diff --git a/source/java/org/alfresco/service/cmr/avm/deploy/DeploymentService.java b/source/java/org/alfresco/service/cmr/avm/deploy/DeploymentService.java index 31302523a7..d177d865fa 100644 --- a/source/java/org/alfresco/service/cmr/avm/deploy/DeploymentService.java +++ b/source/java/org/alfresco/service/cmr/avm/deploy/DeploymentService.java @@ -1,8 +1,10 @@ /** - * + * */ package org.alfresco.service.cmr.avm.deploy; +import java.util.List; + import org.alfresco.service.cmr.action.ActionService; import org.alfresco.util.NameMatcher; @@ -10,7 +12,7 @@ import org.alfresco.util.NameMatcher; * A service to handle AVM repository to remote AVM repository deployment. * @author britt */ -public interface DeploymentService +public interface DeploymentService { /** * Deploys the differences between what is is the local source path @@ -35,8 +37,8 @@ public interface DeploymentService boolean createDst, boolean dontDelete, boolean dontDo, - DeploymentCallback callback); - + List callback); + /** * Get A reference to an ActionService instance on a remote Alfresco Server. * @param hostName @@ -54,7 +56,7 @@ public interface DeploymentService * @param srcPath The path to deploy from. * @param hostName The hostname of the filesystem receiver. * @param port The port to connect to. - * @param userName The username for authentication + * @param userName The username for authentication * @param password The password for authentication * @param dstTarget The target on the deployment receiver. * @param createDst Flag for whether a missing destination should be created. @@ -68,7 +70,7 @@ public interface DeploymentService String dstTarget, NameMatcher matcher, boolean createDst, - boolean dontDelete, + boolean dontDelete, boolean dontDo, - DeploymentCallback callback); + List callback); }