From e10bf8da0dc70e45e5ed7a8f1615e33a8480af4a Mon Sep 17 00:00:00 2001 From: Dave Ward Date: Tue, 13 Oct 2009 11:06:14 +0000 Subject: [PATCH] Merged V3.2 to HEAD 15471: MOB-279: Heartbeat now uses destination URL embedded in the license (if present) and also sends the following new parameters - memFree - memMax - memTotal - numUsers (this was there already) - numGroups - repoName 15349: Merged V3.1 to V3.2 15348: Fix ImportTest following fix to ETHREEOH-2219 15344: Merged V3.1 to V3.2 15339: ETHREEOH-2219: Give ImporterBootstrap its own retrying transaction helper with specific parameters tuned to its longer-running setup transaction. Should avoid startup errors on clustered installations. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16856 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/domain/transaction.properties | 9 ++- config/alfresco/import-export-context.xml | 21 +++++++ .../java/org/alfresco/jcr/test/TestData.java | 2 + .../descriptor/DescriptorServiceImpl.java | 55 +++++++++++-------- .../repo/importer/ImporterBootstrap.java | 27 +++++++-- .../service/license/LicenseDescriptor.java | 11 +++- 6 files changed, 93 insertions(+), 32 deletions(-) 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(); }