diff --git a/config/alfresco/workflow/workflowModel.xml b/config/alfresco/workflow/workflowModel.xml
index e28fca32c0..bee2cb7edd 100644
--- a/config/alfresco/workflow/workflowModel.xml
+++ b/config/alfresco/workflow/workflowModel.xml
@@ -130,6 +130,51 @@
bpm:assignee
+
+
+
+
+
+ bpm:startTask
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+ d:text
+
+
+
+ bpm:assignee
+
+
diff --git a/source/java/org/alfresco/repo/deploy/ASRDeploymentTest.java b/source/java/org/alfresco/repo/deploy/ASRDeploymentTest.java
index d9bfce46d5..304e0d7999 100644
--- a/source/java/org/alfresco/repo/deploy/ASRDeploymentTest.java
+++ b/source/java/org/alfresco/repo/deploy/ASRDeploymentTest.java
@@ -25,17 +25,13 @@
package org.alfresco.repo.deploy;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.alfresco.repo.avm.AVMServiceTestBase;
-import org.alfresco.repo.avm.util.BulkLoader;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.service.cmr.avm.AVMException;
@@ -49,10 +45,7 @@ import org.alfresco.service.cmr.avm.deploy.DeploymentService;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.namespace.QName;
-import org.alfresco.util.Deleter;
import org.alfresco.util.NameMatcher;
-import java.util.Map;
-import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* End to end test of deployment to an alfresco system receiver (ASR).
@@ -99,6 +92,16 @@ public class ASRDeploymentTest extends AVMServiceTestBase
* set up our test tree
*/
fService.createDirectory("main:/", "a");
+
+ String rootText = "Angel is an American television series, a spin-off of the television series Buffy the Vampire Slayer. The series was created by Buffy's creator, Joss Whedon, in collaboration with David Greenwalt, and first aired on October 5, 1999. Like Buffy, it was produced by Whedon's production company, Mutant Enemy.";
+ fService.createFile("main:/", "rootFile").close();
+ ContentWriter writer = fService.getContentWriter("main:/rootFile");
+
+ // Force a conversion
+ writer.setEncoding("UTF-16");
+ writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
+ writer.putContent(rootText);
+
fService.createDirectory("main:/a", "b");
fService.createDirectory("main:/a/b", "c");
fService.createDirectory("main:/", "d");
@@ -107,7 +110,7 @@ public class ASRDeploymentTest extends AVMServiceTestBase
fService.createFile("main:/a/b/c", "foo").close();
String fooText="I am main:/a/b/c/foo";
- ContentWriter writer = fService.getContentWriter("main:/a/b/c/foo");
+ writer = fService.getContentWriter("main:/a/b/c/foo");
writer.setEncoding("UTF-8");
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.putContent("I am main:/a/b/c/foo");
@@ -146,8 +149,9 @@ public class ASRDeploymentTest extends AVMServiceTestBase
// validate the deployment report
assertTrue("first deployment no start", firstDeployment.contains(new DeploymentEvent(DeploymentEvent.Type.START, null, destRef)));
assertTrue("first deployment no finish", firstDeployment.contains(new DeploymentEvent(DeploymentEvent.Type.END, null, destRef)));
- assertTrue("first deployment wrong size", firstDeployment.size() == 11);
+ assertTrue("first deployment wrong size", firstDeployment.size() == 12);
assertTrue("Update missing: /a", firstDeployment.contains(new DeploymentEvent(DeploymentEvent.Type.CREATED, null, destRef + "/a")));
+ assertTrue("Update missing: /rootFile", firstDeployment.contains(new DeploymentEvent(DeploymentEvent.Type.CREATED, null, destRef + "/rootFile")));
assertTrue("Update missing: /a/b", firstDeployment.contains(new DeploymentEvent(DeploymentEvent.Type.CREATED, null, destRef + "/a/b")));
assertTrue("Update missing: /a/b/c", firstDeployment.contains(new DeploymentEvent(DeploymentEvent.Type.CREATED, null, destRef + "/a/b/c")));
assertTrue("Update missing: /d/e", firstDeployment.contains(new DeploymentEvent(DeploymentEvent.Type.CREATED, null, destRef + "/d/e")));
@@ -158,12 +162,12 @@ public class ASRDeploymentTest extends AVMServiceTestBase
// Check that files exist in the destination AVM Store
{
- // fService.getNodeProperties(-1, destRef + "/a");
- //
- // Map props = fService.getNodeProperties(-1, destRef + "/a/b/buffy");
- // ContentReader reader = fService.getContentReader(-1, destRef + "/a/b/buffy");
- // assertNotNull("content reader is null", reader);
- // assertTrue("UTF-16 buffy text is not correct", reader.getContentString().equals(buffyText));
+ fService.getNodeProperties(-1, destRef + "/a");
+
+ Map props = fService.getNodeProperties(-1, destRef + "/a/b/buffy");
+ ContentReader reader = fService.getContentReader(-1, destRef + "/a/b/buffy");
+ assertNotNull("content reader is null", reader);
+ assertTrue("UTF-16 buffy text is not correct", reader.getContentString().equals(buffyText));
}
/**
@@ -199,12 +203,11 @@ public class ASRDeploymentTest extends AVMServiceTestBase
assertTrue("Bar not deleted", smallUpdate.contains(new DeploymentEvent(DeploymentEvent.Type.DELETED, null, destRef + "/a/b/c/bar")));
// Check that files exist in the destination AVM Store
- {
-
- // fService.getNodeProperties(-1, destRef + "/a/b/buffy");
- // ContentReader reader = fService.getContentReader(-1, destRef + "/a/b/buffy");
- // assertNotNull("content reader is null", reader);
- // assertTrue("UTF-16 buffy text is not correct", reader.getContentString().equals(buffyText));
+ {
+ fService.getNodeProperties(-1, destRef + "/a/b/buffy");
+ ContentReader reader = fService.getContentReader(-1, destRef + "/a/b/buffy");
+ assertNotNull("content reader is null", reader);
+ assertTrue("UTF-16 buffy text is not correct", reader.getContentString().equals(buffyText));
}
/**
diff --git a/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java b/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java
index 58a94ae3a5..37ecb936a9 100644
--- a/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java
+++ b/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java
@@ -533,22 +533,26 @@ public class DeploymentServiceImpl implements DeploymentService
OutputStream out = remote.createFile(dstParent.getPath(), src.getName());
try
{
- InputStream in = fAVMService.getFileInputStream(src);
- copyStream(in, out);
- copyMetadata(version, src, remote.lookup(-1, dstParent.getPath() + '/' + src.getName()), remote);
+ InputStream in = fAVMService.getFileInputStream(src);
+ copyStream(in, out);
}
finally
{
- try
- {
- out.close();
- }
- catch (IOException e)
+ if(out != null)
{
+ // whatever happens close stream
+ try
+ {
+ out.close();
+ }
+ catch (IOException e)
+ {
throw new AVMException("I/O Exception", e);
+ }
}
- out = null;
}
+
+ copyMetadata(version, src, remote.lookup(-1, dstParent.getPath() + '/' + src.getName()), remote);
return;
}
@@ -597,9 +601,29 @@ public class DeploymentServiceImpl implements DeploymentService
{
return;
}
- InputStream in = fAVMService.getFileInputStream(src);
+
OutputStream out = remote.getFileOutputStream(dst.getPath());
- copyStream(in, out);
+ try
+ {
+ InputStream in = fAVMService.getFileInputStream(src);
+ copyStream(in, out);
+ }
+ finally
+ {
+ if(out != null)
+ {
+ // whatever happens close stream
+ try
+ {
+ out.close();
+ }
+ catch (IOException e)
+ {
+ throw new AVMException("I/O Exception", e);
+ }
+ }
+ }
+
copyMetadata(version, src, dst, remote);
return;
}
@@ -617,9 +641,28 @@ public class DeploymentServiceImpl implements DeploymentService
// Destination is a directory and the source is a file.
// Delete the destination directory and copy the file over.
remote.removeNode(dstParent.getPath(), dst.getName());
- InputStream in = fAVMService.getFileInputStream(src);
+
OutputStream out = remote.createFile(dstParent.getPath(), src.getName());
- copyStream(in, out);
+ try
+ {
+ InputStream in = fAVMService.getFileInputStream(src);
+ copyStream(in, out);
+ }
+ finally
+ {
+ if(out != null)
+ {
+ // whatever happens close stream
+ try
+ {
+ out.close();
+ }
+ catch (IOException e)
+ {
+ throw new AVMException("I/O Exception", e);
+ }
+ }
+ }
copyMetadata(version, src, remote.lookup(-1, dstParent.getPath() + '/' + dst.getName()), remote);
}
@@ -664,9 +707,27 @@ public class DeploymentServiceImpl implements DeploymentService
newParent.getPath() + '/' + child.getName());
processEvent(event, callbacks);
- InputStream in = fAVMService.getFileInputStream(child);
OutputStream out = remote.createFile(newParent.getPath(), child.getName());
- copyStream(in, out);
+ try
+ {
+ InputStream in = fAVMService.getFileInputStream(child);
+ copyStream(in, out);
+ }
+ finally
+ {
+ if(out != null)
+ {
+ // whatever happens close stream
+ try
+ {
+ out.close();
+ }
+ catch (IOException e)
+ {
+ throw new AVMException("I/O Exception", e);
+ }
+ }
+ }
copyMetadata(version, child, remote.lookup(-1, newParent.getPath() + '/' + child.getName()), remote);
}
else
@@ -686,6 +747,11 @@ public class DeploymentServiceImpl implements DeploymentService
/**
* Utility for copying from one stream to another.
+ *
+ * in is closed.
+ *
+ * out is not closed.
+ *
* @param in The input stream.
* @param out The output stream.
*/
@@ -700,6 +766,8 @@ public class DeploymentServiceImpl implements DeploymentService
out.write(buff, 0, read);
}
in.close();
+ //out.flush();
+ //out.close();
}
catch (IOException e)
{
@@ -976,14 +1044,14 @@ public class DeploymentServiceImpl implements DeploymentService
* @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 void deployDifferenceFS(int version,
- String srcPath,
+ final String srcPath,
String adapterName,
String hostName,
int port,
String userName,
String password,
String target,
- NameMatcher matcher,
+ final NameMatcher matcher,
boolean createDst,
boolean dontDelete,
boolean dontDo,
@@ -995,7 +1063,7 @@ public class DeploymentServiceImpl implements DeploymentService
*/
String lockStr = hostName + "." + target;
QName lockQName = QName.createQName("{org.alfresco.deployment.lock}" + lockStr);
- Lock lock = new Lock(lockQName);
+ final Lock lock = new Lock(lockQName);
lock.makeLock();
@@ -1019,7 +1087,7 @@ public class DeploymentServiceImpl implements DeploymentService
try
{
// Kick off the event queue that will process deployment call-backs
- LinkedBlockingQueue eventQueue = new LinkedBlockingQueue();
+ final LinkedBlockingQueue eventQueue = new LinkedBlockingQueue();
EventQueueWorker eventQueueWorker = new EventQueueWorker(currentEffectiveUser, eventQueue, callbacks);
eventQueueWorker.setName(eventQueueWorker.getClass().getName());
eventQueueWorker.setPriority(Thread.currentThread().getPriority());
@@ -1064,8 +1132,8 @@ public class DeploymentServiceImpl implements DeploymentService
// Go parallel to reduce the problems of high network latency
- LinkedBlockingQueue sendQueue = new LinkedBlockingQueue();
- List errors = Collections.synchronizedList(new ArrayList());
+ final LinkedBlockingQueue sendQueue = new LinkedBlockingQueue();
+ final List errors = Collections.synchronizedList(new ArrayList());
SendQueueWorker[] workers = new SendQueueWorker[numberOfSendingThreads];
for(int i = 0; i < numberOfSendingThreads; i++)
@@ -1084,7 +1152,23 @@ public class DeploymentServiceImpl implements DeploymentService
{
DeploymentToken token = service.begin(target, storeName, version, userName, password.toCharArray());
ticket = token.getTicket();
- deployDirectoryPushFSR(service, ticket, version, srcPath, "/", matcher, eventQueue, sendQueue, errors, lock);
+
+ // run this in its own txn
+ final DeploymentReceiverService fservice = service;
+ final String fTicket = ticket;
+ final int fVersion = version;
+ RetryingTransactionCallback pushFSR = new RetryingTransactionCallback()
+ {
+ public Integer execute() throws Throwable
+ {
+ deployDirectoryPushFSR(fservice, fTicket, fVersion, srcPath, "/", matcher, eventQueue, sendQueue, errors, lock);
+ return 0;
+ }
+ };
+
+ RetryingTransactionHelper trn = trxService.getRetryingTransactionHelper();
+ trn.doInTransaction(pushFSR, false, true);
+
}
catch (Exception e)
{
diff --git a/source/java/org/alfresco/repo/deploy/DeploymentServiceTest.java b/source/java/org/alfresco/repo/deploy/DeploymentServiceTest.java
new file mode 100644
index 0000000000..2e47f84e6c
--- /dev/null
+++ b/source/java/org/alfresco/repo/deploy/DeploymentServiceTest.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2005-2009 Alfresco Software Limited.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * 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:
+ * http://www.alfresco.com/legal/licensing"
+ */
+package org.alfresco.repo.deploy;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.config.JNDIConstants;
+import org.alfresco.jlan.smb.dcerpc.UUID;
+import org.alfresco.repo.action.ActionImpl;
+import org.alfresco.repo.avm.AVMNodeConverter;
+import org.alfresco.repo.avm.AVMNodeType;
+import org.alfresco.repo.content.MimetypeMap;
+import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.security.permissions.AccessDeniedException;
+import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
+import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
+import org.alfresco.service.cmr.avm.AVMService;
+import org.alfresco.service.cmr.avm.deploy.DeploymentCallback;
+import org.alfresco.service.cmr.avm.deploy.DeploymentReport;
+import org.alfresco.service.cmr.avm.deploy.DeploymentReportCallback;
+import org.alfresco.service.cmr.avm.deploy.DeploymentService;
+import org.alfresco.service.cmr.avmsync.AVMDifference;
+import org.alfresco.service.cmr.repository.ContentReader;
+import org.alfresco.service.cmr.repository.ContentWriter;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.transaction.TransactionService;
+import org.alfresco.util.GUID;
+import org.alfresco.util.NameMatcher;
+import org.alfresco.wcm.AbstractWCMServiceImplTest;
+import org.alfresco.wcm.actions.WCMSandboxRevertSnapshotAction;
+import org.alfresco.wcm.actions.WCMSandboxSubmitAction;
+import org.alfresco.wcm.actions.WCMSandboxUndoAction;
+import org.alfresco.wcm.asset.AssetInfo;
+import org.alfresco.wcm.sandbox.SandboxInfo;
+import org.alfresco.wcm.util.WCMUtil;
+import org.alfresco.wcm.webproject.WebProjectInfo;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.context.support.FileSystemXmlApplicationContext;
+
+/**
+ * Test of deployment to a Test Server.
+ *
+ * Through the WCM application rather than directly through AVM.
+ *
+ * @author Mark Rogers
+ */
+public class DeploymentServiceTest extends AbstractWCMServiceImplTest
+{
+ private static Log logger = LogFactory.getLog(DeploymentServiceTest.class);
+
+ // base sandbox
+ private static final String TEST_SANDBOX = TEST_WEBPROJ_DNS+"-sandbox";
+
+ private static final int SCALE_USERS = 5;
+ private static final int SCALE_WEBPROJECTS = 2;
+
+ //
+ // services
+ //
+
+ private AVMService avmService; // non-locking-aware
+ private DeploymentService deploymentService = null;
+ private NameMatcher matcher = null;
+
+ private File log = null;
+ private File metadata = null;
+ private File data = null;
+ private File target = null;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ // Get the required services
+ avmService = (AVMService)ctx.getBean("AVMService");
+ deploymentService = (DeploymentService)ctx.getBean("DeploymentService");
+ NameMatcher matcher = (NameMatcher)ctx.getBean("globalPathExcluder");
+
+ super.setUp();
+ log = new File("deplog");
+ log.mkdir();
+ metadata = new File("depmetadata");
+ metadata.mkdir();
+ data = new File("depdata");
+ data.mkdir();
+ target = new File("sampleTarget");
+ target.mkdir();
+
+ /**
+ * Start the FSR
+ */
+ @SuppressWarnings("unused")
+ FileSystemXmlApplicationContext receiverContext =
+ new FileSystemXmlApplicationContext("../deployment/config/application-context.xml");
+
+
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ if (CLEAN)
+ {
+ // Switch back to Admin
+ AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
+
+ deleteUser(USER_ONE);
+ deleteUser(USER_TWO);
+ deleteUser(USER_THREE);
+ deleteUser(USER_FOUR);
+ }
+
+ super.tearDown();
+ }
+
+ private String TEST_USER = "Giles";
+ private String TEST_PASSWORD = "Watcher";
+ private String TEST_TARGET = "sampleTarget";
+
+ public void testSimple() throws Exception
+ {
+
+ int storeCnt = avmService.getStores().size();
+
+ String projectName = "DeploymentServiceTestSimple";
+
+ // create web project (also creates staging sandbox and admin's author sandbox)
+ WebProjectInfo wpInfo = wpService.createWebProject(projectName, projectName, TEST_WEBPROJ_TITLE, TEST_WEBPROJ_DESCRIPTION, TEST_WEBPROJ_DEFAULT_WEBAPP, TEST_WEBPROJ_DONT_USE_AS_TEMPLATE, null);
+ String wpStoreId = wpInfo.getStoreId();
+
+ // list 2 sandboxes
+ assertEquals(2, sbService.listSandboxes(wpStoreId).size());
+
+ // list 4 extra AVM stores (2 per sandbox)
+ assertEquals(storeCnt+4, avmService.getStores().size()); // 2x stating (main,preview), 2x admin author (main, preview)
+
+ // get admin's sandbox
+ SandboxInfo authorInfo = sbService.getAuthorSandbox(wpStoreId);
+ assertNotNull(authorInfo);
+
+ // get staging sandbox
+ SandboxInfo stagingInfo = sbService.getStagingSandbox(wpStoreId);
+ assertNotNull(stagingInfo);
+
+ DeploymentReport report = new DeploymentReport();
+ List callbacks = new ArrayList();
+ callbacks.add(new DeploymentReportCallback(report));
+
+ /**
+ * Test Server Admin Sandbox Webapps
+ */
+ String srcPath = projectName + "--admin:/www/avm_webapps";
+ deploymentService.deployDifferenceFS(-1, srcPath, "default", "localhost", 44100, TEST_USER, TEST_PASSWORD, TEST_TARGET, matcher, false, false, false, callbacks);
+
+ /**
+ * Test Server Admin Sandbox ROOT Webapp
+ */
+ assetService.createFolder(authorInfo.getSandboxId(), "/", "hello", null);
+ srcPath = projectName + "--admin:/www/avm_webapps/ROOT";
+ deploymentService.deployDifferenceFS(-1, srcPath, "default", "localhost", 44100, TEST_USER, TEST_PASSWORD, TEST_TARGET, matcher, false, false, false, callbacks);
+
+ /**
+ * Live Server - Staging ROOT
+ */
+ srcPath = projectName + ":/www/avm_webapps/ROOT";
+ deploymentService.deployDifferenceFS(-1, srcPath, "default", "localhost", 44100, TEST_USER, TEST_PASSWORD, TEST_TARGET, matcher, false, false, false, callbacks);
+
+ wpService.deleteWebProject(projectName);
+ }
+
+}