diff --git a/config/alfresco/domain/transaction.properties b/config/alfresco/domain/transaction.properties
index 7caefb41f3..daab922c71 100644
--- a/config/alfresco/domain/transaction.properties
+++ b/config/alfresco/domain/transaction.properties
@@ -11,4 +11,11 @@ server.transaction.allow-writes=true
server.transaction.max-retries=40
server.transaction.min-retry-wait-ms=100
server.transaction.max-retry-wait-ms=2000
-server.transaction.wait-increment-ms=100
\ No newline at end of file
+server.transaction.wait-increment-ms=100
+
+# Values specific to the importer bootstrap on first boot - allow for a
+# long-running transaction on one node
+server.setup.transaction.max-retries=40
+server.setup.transaction.min-retry-wait-ms=15000
+server.setup.transaction.max-retry-wait-ms=15000
+server.setup.transaction.wait-increment-ms=0
\ No newline at end of file
diff --git a/config/alfresco/import-export-context.xml b/config/alfresco/import-export-context.xml
index 3cb6ac527e..af35554754 100644
--- a/config/alfresco/import-export-context.xml
+++ b/config/alfresco/import-export-context.xml
@@ -213,6 +213,9 @@
+
+
+
@@ -238,6 +241,24 @@
+
+
+
+
+
+
+ ${server.setup.transaction.max-retries}
+
+
+ ${server.setup.transaction.min-retry-wait-ms}
+
+
+ ${server.setup.transaction.max-retry-wait-ms}
+
+
+ ${server.setup.transaction.wait-increment-ms}
+
+
diff --git a/source/java/org/alfresco/jcr/test/TestData.java b/source/java/org/alfresco/jcr/test/TestData.java
index 98ed717546..6b14914be7 100644
--- a/source/java/org/alfresco/jcr/test/TestData.java
+++ b/source/java/org/alfresco/jcr/test/TestData.java
@@ -31,6 +31,7 @@ import java.util.Properties;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.security.authentication.AuthenticationContext;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
+import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeService;
@@ -110,6 +111,7 @@ public class TestData
bootstrap.setNodeService((NodeService) applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName()));
bootstrap.setNamespaceService((NamespaceService) applicationContext.getBean(ServiceRegistry.NAMESPACE_SERVICE.getLocalName()));
bootstrap.setTransactionService((TransactionService) applicationContext.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName()));
+ bootstrap.setRetryingTransactionHelper((RetryingTransactionHelper) applicationContext.getBean("storeImporterTransactionHelper"));
bootstrap.setStoreUrl(storeRef.toString());
List views = new ArrayList();
diff --git a/source/java/org/alfresco/repo/descriptor/DescriptorServiceImpl.java b/source/java/org/alfresco/repo/descriptor/DescriptorServiceImpl.java
index bac21f1e7b..62be916e2e 100644
--- a/source/java/org/alfresco/repo/descriptor/DescriptorServiceImpl.java
+++ b/source/java/org/alfresco/repo/descriptor/DescriptorServiceImpl.java
@@ -25,7 +25,6 @@
package org.alfresco.repo.descriptor;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
@@ -42,6 +41,7 @@ import org.alfresco.util.VersionNumber;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* Implementation of Descriptor Service.
@@ -68,7 +68,7 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
/** The heart beat service. */
@SuppressWarnings("unused")
private Object heartBeat;
-
+
/** The server descriptor. */
private Descriptor serverDescriptor;
@@ -128,7 +128,7 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
*/
public Descriptor getServerDescriptor()
{
- return serverDescriptor;
+ return this.serverDescriptor;
}
/*
@@ -137,7 +137,7 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
*/
public Descriptor getCurrentRepositoryDescriptor()
{
- return currentRepoDescriptor;
+ return this.currentRepoDescriptor;
}
/*
@@ -146,7 +146,7 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
*/
public Descriptor getInstalledRepositoryDescriptor()
{
- return installedRepoDescriptor;
+ return this.installedRepoDescriptor;
}
/*
@@ -155,7 +155,7 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
*/
public LicenseDescriptor getLicenseDescriptor()
{
- return (licenseService == null) ? null : licenseService.getLicense();
+ return this.licenseService == null ? null : this.licenseService.getLicense();
}
/*
@@ -165,15 +165,15 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
@Override
protected void onBootstrap(ApplicationEvent event)
{
- // initialise the repository descriptor
- // note: this requires that the repository schema has already been initialised
+ // Initialize the repository descriptor
+ // note: this requires that the repository schema has already been initialized
final RetryingTransactionCallback createDescriptorWork = new RetryingTransactionCallback()
{
public Descriptor execute() throws ClassNotFoundException
{
boolean initialiseHeartBeat = false;
- // initialise license service (if installed)
+ // Initialize license service (if installed)
DescriptorServiceImpl.this.licenseService = (LicenseService) constructSpecialService("org.alfresco.enterprise.license.LicenseComponent");
if (DescriptorServiceImpl.this.licenseService == null)
{
@@ -181,12 +181,21 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
initialiseHeartBeat = true;
}
+ // Make the license service available through the application context as a singleton for other beans
+ // that need it (e.g. the HeartBeat).
+ ApplicationContext applicationContext = getApplicationContext();
+ if (applicationContext instanceof ConfigurableApplicationContext)
+ {
+ ((ConfigurableApplicationContext) applicationContext).getBeanFactory().registerSingleton(
+ "licenseService", DescriptorServiceImpl.this.licenseService);
+ }
+
// verify license, but only if license component is installed
try
{
- licenseService.verifyLicense();
- LicenseDescriptor l = licenseService.getLicense();
- // Initialise the heartbeat unless it is disabled by the license
+ DescriptorServiceImpl.this.licenseService.verifyLicense();
+ LicenseDescriptor l = DescriptorServiceImpl.this.licenseService.getLicense();
+ // Initialize the heartbeat unless it is disabled by the license
if (initialiseHeartBeat || l == null || !l.isHeartBeatDisabled())
{
DescriptorServiceImpl.this.heartBeat = constructSpecialService("org.alfresco.enterprise.heartbeat.HeartBeat");
@@ -194,14 +203,14 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
}
catch (LicenseException e)
{
- // Initialise heart beat anyway
+ // Initialize heart beat anyway
DescriptorServiceImpl.this.heartBeat = constructSpecialService("org.alfresco.enterprise.heartbeat.HeartBeat");
throw e;
}
// persist the server descriptor values
- currentRepoDescriptor = DescriptorServiceImpl.this.currentRepoDescriptorDAO
- .updateDescriptor(serverDescriptor);
+ DescriptorServiceImpl.this.currentRepoDescriptor = DescriptorServiceImpl.this.currentRepoDescriptorDAO
+ .updateDescriptor(DescriptorServiceImpl.this.serverDescriptor);
// create the installed descriptor
Descriptor installed = DescriptorServiceImpl.this.installedRepoDescriptorDAO.getDescriptor();
@@ -212,12 +221,12 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
{
public Descriptor doWork() throws Exception
{
- return transactionService.getRetryingTransactionHelper().doInTransaction(createDescriptorWork,
- transactionService.isReadOnly(), false);
+ return DescriptorServiceImpl.this.transactionService.getRetryingTransactionHelper().doInTransaction(
+ createDescriptorWork, DescriptorServiceImpl.this.transactionService.isReadOnly(), false);
}
- }, AuthenticationUtil.getSystemUserName());
-
- ((ApplicationContext)event.getSource()).publishEvent(new DescriptorServiceAvailableEvent(this));
+ }, AuthenticationUtil.getSystemUserName());
+
+ ((ApplicationContext) event.getSource()).publishEvent(new DescriptorServiceAvailableEvent(this));
}
/*
@@ -242,7 +251,7 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
public void afterPropertiesSet() throws Exception
{
// initialise server descriptor
- serverDescriptor = this.serverDescriptorDAO.getDescriptor();
+ this.serverDescriptor = this.serverDescriptorDAO.getDescriptor();
}
/**
@@ -498,8 +507,8 @@ public class DescriptorServiceImpl extends AbstractLifecycleBean implements Desc
String label = getVersionLabel();
String build = getVersionBuild();
- boolean hasLabel = (label != null && label.length() > 0);
- boolean hasBuild = (build != null && build.length() > 0);
+ boolean hasLabel = label != null && label.length() > 0;
+ boolean hasBuild = build != null && build.length() > 0;
// add opening bracket if either a label or build number is present
if (hasLabel || hasBuild)
diff --git a/source/java/org/alfresco/repo/importer/ImporterBootstrap.java b/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
index a365772561..351d867098 100644
--- a/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
+++ b/source/java/org/alfresco/repo/importer/ImporterBootstrap.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2008 Alfresco Software Limited.
+ * 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
@@ -18,7 +18,7 @@
* 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
+ * FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
@@ -44,6 +44,7 @@ import org.alfresco.i18n.I18NUtil;
import org.alfresco.repo.security.authentication.AuthenticationContext;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
+import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
@@ -91,6 +92,7 @@ public class ImporterBootstrap extends AbstractLifecycleBean
private UUID_BINDING uuidBinding = null;
// Dependencies
private TransactionService transactionService;
+ private RetryingTransactionHelper retryingTransactionHelper;
private NamespaceService namespaceService;
private NodeService nodeService;
private ImporterService importerService;
@@ -140,8 +142,8 @@ public class ImporterBootstrap extends AbstractLifecycleBean
public void setUuidBinding(UUID_BINDING uuidBinding)
{
this.uuidBinding = uuidBinding;
- }
-
+ }
+
/**
* Sets the Transaction Service
*
@@ -151,8 +153,20 @@ public class ImporterBootstrap extends AbstractLifecycleBean
{
this.transactionService = transactionService;
}
-
+
/**
+ * Sets the retrying transaction helper specific to the importer bootstrap. This transaction helper's parameters are
+ * tuned to the longer-running import transaction.
+ *
+ * @param retryingTransactionHelper
+ * the retrying transaction helper
+ */
+ public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
+ {
+ this.retryingTransactionHelper = retryingTransactionHelper;
+ }
+
+ /**
* Sets the namespace service
*
* @param namespaceService the namespace service
@@ -314,6 +328,7 @@ public class ImporterBootstrap extends AbstractLifecycleBean
public void bootstrap()
{
PropertyCheck.mandatory(this, "transactionService", transactionService);
+ PropertyCheck.mandatory(this, "retryingTransactionHelper", retryingTransactionHelper);
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
PropertyCheck.mandatory(this, "nodeService", nodeService);
PropertyCheck.mandatory(this, "importerService", importerService);
@@ -342,7 +357,7 @@ public class ImporterBootstrap extends AbstractLifecycleBean
return null;
}
};
- return transactionService.getRetryingTransactionHelper().doInTransaction(doImportCallback, transactionService.isReadOnly(), false);
+ return retryingTransactionHelper.doInTransaction(doImportCallback, transactionService.isReadOnly(), false);
}
};
AuthenticationUtil.runAs(importRunAs, authenticationContext.getSystemUserName());
diff --git a/source/java/org/alfresco/service/license/LicenseDescriptor.java b/source/java/org/alfresco/service/license/LicenseDescriptor.java
index 60e5024a02..9390f2e301 100644
--- a/source/java/org/alfresco/service/license/LicenseDescriptor.java
+++ b/source/java/org/alfresco/service/license/LicenseDescriptor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2007 Alfresco Software Limited.
+ * 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
@@ -18,7 +18,7 @@
* 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
+ * FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
@@ -90,4 +90,11 @@ public interface LicenseDescriptor
* @return true
if this license allow the heartbeat to be disabled
*/
public boolean isHeartBeatDisabled();
+
+ /**
+ * Gets an alternative URL that the heart beat should post data to, or null
if the default URL is to be used.
+ *
+ * @return a URL or null
+ */
+ public String getHeartBeatUrl();
}