Merged V2.2 to HEAD

7462: Renamed ManageLinkValidationTaskDialog to ManageReviewTaskDialog as it is now more generic
         Enabled deployment and link validation in parallel review tasks
         Created separate JSP page for manage change request task dialog
         When a server is edited it is now scrolled to
         Some minor UI tidyup
   7467: Added ability to define excludes for a deployment via a regular expression
   7475: Incorporated new icons from Linton
   7492: Allows multiple callbacks for deployment. Adds new FAILED deployment event.
   7493: Added ability to view previous deployment attempts


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8380 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-02-26 14:19:37 +00:00
parent 27f525c54e
commit ff15cf4079
6 changed files with 299 additions and 167 deletions

View File

@@ -322,6 +322,10 @@
<title>Source Path</title>
<type>d:text</type>
</property>
<property name="wca:deployexcludes">
<title>Excludes</title>
<type>d:text</type>
</property>
<property name="wca:deployserverallocatedto">
<title>Allocated To</title>
<type>d:text</type>
@@ -450,6 +454,10 @@
<title>Source Path Used</title>
<type>d:text</type>
</property>
<property name="wca:deployexcludesused">
<title>Excludes Used</title>
<type>d:text</type>
</property>
<property name="wca:deployserverurlused">
<title>Source Path Used</title>
<type>d:text</type>

View File

@@ -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

View File

@@ -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,6 +55,7 @@ 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;
@@ -266,6 +268,7 @@ 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;
@@ -323,6 +326,15 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
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<String> patterns = new ArrayList<String>(1);
patterns.add(excludes);
regexMatcher.setPatterns(patterns);
}
// take a note of the current date/time
Date startDate = new Date();
@@ -352,8 +364,13 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
// TODO: Added new NameMatcher parameter to deploy methods. It acts as a filter.
// Any matching path names are ignored for deployment purposes.
List<DeploymentCallback> callbacks = new ArrayList<DeploymentCallback>();
if (callback != null)
{
callbacks.add(callback);
}
report = this.deployService.deployDifferenceFS(version, path, host, port,
remoteUsername, remotePassword, targetName, null, true, false, false, callback);
remoteUsername, remotePassword, targetName, regexMatcher, true, false, false, callbacks);
}
else
{
@@ -363,8 +380,13 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
// TODO: Added new NameMatcher parameter to deploy methods. It acts as a filter.
// Any matching path names are ignored for deployment purposes.
List<DeploymentCallback> callbacks = new ArrayList<DeploymentCallback>();
if (callback != null)
{
callbacks.add(callback);
}
report = this.deployService.deployDifference(version, path, host, port,
remoteUsername, remotePassword, targetPath, null, true, false, false, callback);
remoteUsername, remotePassword, targetPath, regexMatcher, true, false, false, callbacks);
}
}
catch (Throwable err)
@@ -442,6 +464,8 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
serverProps.get(WCMAppModel.PROP_DEPLOYSERVERTARGET));
reportProps.put(WCMAppModel.PROP_DEPLOYSOURCEPATHUSED,
serverProps.get(WCMAppModel.PROP_DEPLOYSOURCEPATH));
reportProps.put(WCMAppModel.PROP_DEPLOYEXCLUDESUSED,
serverProps.get(WCMAppModel.PROP_DEPLOYEXCLUDES));
reportProps.put(WCMAppModel.PROP_DEPLOYSERVERURLUSED,
serverProps.get(WCMAppModel.PROP_DEPLOYSERVERURL));

View File

@@ -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<DeploymentCallback> callbacks)
{
DeploymentDestination dest = getLock(hostName, port);
synchronized (dest)
@@ -170,13 +173,16 @@ 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<Integer, String>(version, srcPath),
dstPath);
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
if (version < 0)
{
String storeName = srcPath.substring(0, srcPath.indexOf(":"));
@@ -224,23 +230,29 @@ public class DeploymentServiceImpl implements DeploymentService
new Pair<Integer, String>(version, srcPath),
dstPath);
report.add(event);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
if (dontDo)
{
return report;
}
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<Integer, String>(version, srcPath),
dstPath);
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
return report;
}
if (!dstRoot.isDirectory())
@@ -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<Integer, String>(version, srcPath),
dstPath);
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
return report;
}
catch (AVMException e)
{
if (callbacks != null)
{
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.FAILED,
new Pair<Integer, String>(version, srcPath),
dstPath);
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
try
{
if (snapshot != -1)
@@ -279,6 +304,20 @@ public class DeploymentServiceImpl implements DeploymentService
throw new AVMException("Deployment to " + hostName + " failed.", e);
}
}
catch (Exception e)
{
if (callbacks != null)
{
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.FAILED,
new Pair<Integer, String>(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<DeploymentCallback> 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,10 +382,13 @@ public class DeploymentServiceImpl implements DeploymentService
source,
destination);
report.add(event);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
if (dontDo)
{
continue;
@@ -372,7 +414,7 @@ public class DeploymentServiceImpl implements DeploymentService
NameMatcher matcher,
boolean dontDelete, boolean dontDo,
DeploymentReport report,
DeploymentCallback callback)
List<DeploymentCallback> callbacks)
{
// Destination does not exist.
if (dst == null)
@@ -387,10 +429,13 @@ public class DeploymentServiceImpl implements DeploymentService
source,
destination);
report.add(event);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
if (dontDo)
{
return;
@@ -405,10 +450,13 @@ public class DeploymentServiceImpl implements DeploymentService
source,
destination);
report.add(event);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
if (dontDo)
{
return;
@@ -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<Integer, String> source =
@@ -435,10 +483,13 @@ public class DeploymentServiceImpl implements DeploymentService
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED,
source, destination);
report.add(event);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
if (dontDo)
{
return;
@@ -462,10 +513,13 @@ public class DeploymentServiceImpl implements DeploymentService
source,
destination);
report.add(event);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
if (dontDo)
{
return;
@@ -483,10 +537,13 @@ public class DeploymentServiceImpl implements DeploymentService
source,
destination);
report.add(event);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
if (dontDo)
{
return;
@@ -735,17 +792,27 @@ 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<DeploymentCallback> callbacks)
{
DeploymentReport report = new DeploymentReport();
DeploymentReceiverService service = getReceiver(hostName, port);
String ticket = null;
try
{
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.START,
new Pair<Integer, String>(version, srcPath),
target);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
report.add(event);
String storeName = srcPath.substring(0, srcPath.indexOf(':'));
System.out.println(storeName);
@@ -753,22 +820,38 @@ public class DeploymentServiceImpl implements DeploymentService
{
version = fAVMService.createSnapshot(storeName, null, null).get(storeName);
}
String ticket = service.begin(target, userName, password);
deployDirectoryPush(service, ticket, report, callback, version, srcPath, "/", matcher);
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<Integer, String>(version, srcPath),
target);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
report.add(event);
return report;
}
catch (Exception e)
{
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.FAILED,
new Pair<Integer, String>(version, srcPath),
target);
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
service.abort(ticket);
throw new AVMException("Deployment to: " + target + " failed.", e);
}
}
private void deployDirectoryPush(DeploymentReceiverService service, String ticket,
DeploymentReport report, DeploymentCallback callback,
DeploymentReport report, List<DeploymentCallback> callbacks,
int version,
String srcPath, String dstPath, NameMatcher matcher)
{
@@ -804,10 +887,13 @@ public class DeploymentServiceImpl implements DeploymentService
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.DELETED,
new Pair<Integer, String>(version, extendPath(srcPath, dst.getName())),
newDstPath);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
report.add(event);
}
dst = null;
@@ -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,10 +970,13 @@ public class DeploymentServiceImpl implements DeploymentService
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.DELETED,
new Pair<Integer, String>(version, extendPath(srcPath, dst.getName())),
newDstPath);
if (callback != null)
if (callbacks != null)
{
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<DeploymentCallback> callbacks, int version,
AVMNodeDescriptor src, String dstPath)
{
InputStream in = fAVMService.getFileInputStream(src);
@@ -916,10 +1005,13 @@ public class DeploymentServiceImpl implements DeploymentService
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED,
new Pair<Integer, String>(version, src.getPath()),
dstPath);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
report.add(event);
}
catch (Exception e)
@@ -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<DeploymentCallback> 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,17 +1046,20 @@ public class DeploymentServiceImpl implements DeploymentService
DeploymentEvent event = new DeploymentEvent(DeploymentEvent.Type.COPIED,
new Pair<Integer, String>(version, src.getPath()),
dstPath);
if (callback != null)
if (callbacks != null)
{
for (DeploymentCallback callback : callbacks)
{
callback.eventOccurred(event);
}
}
report.add(event);
Map<String, AVMNodeDescriptor> listing = fAVMService.getDirectoryListing(src);
for (AVMNodeDescriptor child : listing.values())
{
if (!excluded(matcher, child.getPath(), null))
{
copy(service, ticket, report, callback, version, child, dstPath, matcher);
copy(service, ticket, report, callbacks, version, child, dstPath, matcher);
}
}
}

View File

@@ -47,7 +47,8 @@ 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;

View File

@@ -3,6 +3,8 @@
*/
package org.alfresco.service.cmr.avm.deploy;
import java.util.List;
import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.util.NameMatcher;
@@ -35,7 +37,7 @@ public interface DeploymentService
boolean createDst,
boolean dontDelete,
boolean dontDo,
DeploymentCallback callback);
List<DeploymentCallback> callback);
/**
* Get A reference to an ActionService instance on a remote Alfresco Server.
@@ -70,5 +72,5 @@ public interface DeploymentService
boolean createDst,
boolean dontDelete,
boolean dontDo,
DeploymentCallback callback);
List<DeploymentCallback> callback);
}