diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml index 07fb3d9de5..9624c43f87 100644 --- a/config/alfresco/core-services-context.xml +++ b/config/alfresco/core-services-context.xml @@ -458,12 +458,6 @@ - - ${version.store.onlyUseDeprecatedV1} - - - - ${version.store.versionComparatorClass} @@ -514,38 +508,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 500 - - - diff --git a/config/alfresco/dbscripts/create/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoCreate-ActivityTables.sql b/config/alfresco/dbscripts/create/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoCreate-ActivityTables.sql index 3de1040693..1f038c7296 100644 --- a/config/alfresco/dbscripts/create/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoCreate-ActivityTables.sql +++ b/config/alfresco/dbscripts/create/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoCreate-ActivityTables.sql @@ -53,16 +53,3 @@ CREATE TABLE alf_activity_post KEY post_jobtasknode_idx (job_task_node), KEY post_status_idx (status) ) ENGINE=InnoDB; - - --- --- Record script finish --- -DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.0-ActivityTables'; -INSERT INTO alf_applied_patch - (id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report) - VALUES - ( - 'patch.db-V3.0-ActivityTables', 'Manually executed script upgrade V3.0: Activity Tables', - 0, 125, -1, 126, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed' - ); \ No newline at end of file diff --git a/config/alfresco/dbscripts/create/org.hibernate.dialect.PostgreSQLDialect/AlfrescoCreate-ActivityTables.sql b/config/alfresco/dbscripts/create/org.hibernate.dialect.PostgreSQLDialect/AlfrescoCreate-ActivityTables.sql index 6d4de97710..19ed68c221 100644 --- a/config/alfresco/dbscripts/create/org.hibernate.dialect.PostgreSQLDialect/AlfrescoCreate-ActivityTables.sql +++ b/config/alfresco/dbscripts/create/org.hibernate.dialect.PostgreSQLDialect/AlfrescoCreate-ActivityTables.sql @@ -56,16 +56,3 @@ CREATE TABLE alf_activity_post ); CREATE INDEX post_jobtasknode_idx ON alf_activity_post (job_task_node); CREATE INDEX post_status_idx ON alf_activity_post (status); - - --- --- Record script finish --- -DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.0-ActivityTables'; -INSERT INTO alf_applied_patch - (id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report) - VALUES - ( - 'patch.db-V3.0-ActivityTables', 'Manually executed script upgrade V3.0: Activity Tables', - 0, 125, -1, 126, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed' - ); \ No newline at end of file diff --git a/config/alfresco/dbscripts/db-schema-context.xml b/config/alfresco/dbscripts/db-schema-context.xml index 20176cd409..392131a4b2 100644 --- a/config/alfresco/dbscripts/db-schema-context.xml +++ b/config/alfresco/dbscripts/db-schema-context.xml @@ -55,7 +55,6 @@ - @@ -89,7 +88,6 @@ - diff --git a/config/alfresco/dbscripts/upgrade/3.1/org.hibernate.dialect.MySQLInnoDBDialect/IPv6-patch.sql b/config/alfresco/dbscripts/upgrade/3.1/org.hibernate.dialect.MySQLInnoDBDialect/IPv6-patch.sql deleted file mode 100644 index 7baf781753..0000000000 --- a/config/alfresco/dbscripts/upgrade/3.1/org.hibernate.dialect.MySQLInnoDBDialect/IPv6-patch.sql +++ /dev/null @@ -1,21 +0,0 @@ --- --- Title: Increase the ipAddress field length to allow IPv6 adresses --- Database: MySQL --- Since: V3.1 schema 1009 --- --- Please contact support@alfresco.com if you need assistance with the upgrade. --- - -ALTER TABLE alf_server MODIFY ip_address varchar(39) NOT NULL; - --- --- Record script finish --- -DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.1-Allow-IPv6'; -INSERT INTO alf_applied_patch - (id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report) - VALUES - ( - 'patch.db-V3.1-Allow-IPv6', 'Manually executed script upgrade V3.1: Increase the ipAddress field length', - 0, 2019, -1, 2020, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed' - ); diff --git a/config/alfresco/dbscripts/upgrade/3.1/org.hibernate.dialect.PostgreSQLDialect/IPv6-patch.sql b/config/alfresco/dbscripts/upgrade/3.1/org.hibernate.dialect.PostgreSQLDialect/IPv6-patch.sql deleted file mode 100644 index 52919ad710..0000000000 --- a/config/alfresco/dbscripts/upgrade/3.1/org.hibernate.dialect.PostgreSQLDialect/IPv6-patch.sql +++ /dev/null @@ -1,21 +0,0 @@ --- --- Title: Increase the ipAddress field length to allow IPv6 adresses --- Database: PostgreSQL --- Since: V3.1 schema 1009 --- --- Please contact support@alfresco.com if you need assistance with the upgrade. --- - -ALTER TABLE alf_server ALTER COLUMN ip_address TYPE varchar(39); - --- --- Record script finish --- -DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.1-Allow-IPv6'; -INSERT INTO alf_applied_patch - (id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report) - VALUES - ( - 'patch.db-V3.1-Allow-IPv6', 'Manually executed script upgrade V3.1: Increase the ipAddress field length', - 0, 1009, -1, 1010, null, 'UNKOWN', TRUE, TRUE, 'Script completed' - ); diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index 85a18ff848..91e8a7a72e 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -203,7 +203,6 @@ patch.tagRootCategory.description=Adds 'Tags' as new top-level category root. patch.sitesFolder.description=Adds 'Sites' folder to Company Home. patch.updateDmPermissions.description=Update ACLs on all DM node objects to the new 3.0 permission model -patch.updateDmPermissions.result=Updated ACLs. Created {0} defining ACLs. patch.db-V3.0-0-CreateActivitiesExtras.description=Replaced by 'patch.db-V3.0-ActivityTables', which must run first. @@ -211,9 +210,6 @@ patch.sitePermissionRefactorPatch.description=Create permission groups for sites patch.sitePermissionRefactorPatch.result=Groups have been created for all sites and user's allocated accordingly. patch.migrateVersionStore.description=Version Store migration (from lightWeightVersionStore to version2Store) -patch.migrateVersionStore.incomplete=Version Store migration incomplete. -patch.migrateVersionStore.done=Version Store migration completed. -patch.migrateVersionStore.bypassingPatch=Bypass Version Store migration patch since scheduled to run as job patch.inviteEmailTemplate.description=Adds invite email template to invite space diff --git a/config/alfresco/node-services-context.xml b/config/alfresco/node-services-context.xml index 61ff230c80..8a4ae7595e 100644 --- a/config/alfresco/node-services-context.xml +++ b/config/alfresco/node-services-context.xml @@ -179,7 +179,6 @@ ${version.store.version2Store} - diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index 8d140a0d7f..4009435815 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -754,156 +754,74 @@ 4.2.x - - + patch.db-V3.0-0-CreateActivitiesExtras patch.db-V3.0-0-CreateActivitiesExtras.description 0 125 126 - - - - + + 4.2.x - + patch.db-V3.0-ActivityTables patch.schemaUpgradeScript.description 0 125 126 - - - - - - - classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-ActivityTables.sql + + 4.2.x - - + patch.createSiteStore patch.noOpPatch.description 0 126 127 + + 4.2.x + - - + patch.sitesFolder patch.sitesFolder.description 0 127 128 - - - - - - - - - - /${spaces.company_home.childname}/st:sites - - - - /${spaces.company_home.childname} - alfresco/bootstrap/sitesSpace.xml - alfresco/messages/bootstrap-spaces - + + 4.2.x - - + patch.sitePermissionRefactorPatch patch.sitePermissionRefactorPatch.description 0 128 129 - - - - - - - - - - - - - - + + 4.2.x - - + patch.migrateVersionStore patch.migrateVersionStore.description 0 129 130 - - - - - - - - - - - - - - - - - - - ${version.store.migrateVersionStore.threadCount} - - - ${version.store.migrateVersionStore.batchSize} - - - ${version.store.migrateVersionStore.runAsScheduledJob} - - - ${version.store.migrateVersionStore.limitPerJobCycle} - - - false + + 4.2.x - - + patch.inviteEmailTemplate patch.inviteEmailTemplate.description 0 130 131 - - - - - - - - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname}/${spaces.templates.email.invite.childname} - - - - /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} - alfresco/bootstrap/invite/invite-email.xml - alfresco/messages/bootstrap-spaces - + + 4.2.x @@ -1241,14 +1159,14 @@ - + patch.db-V3.1-Allow-IPv6 patch.schemaUpgradeScript.description 0 3003 3004 - - classpath:alfresco/dbscripts/upgrade/3.1/${db.script.dialect}/IPv6-patch.sql + + 4.2.x diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties index 50da4d63fd..02d51e8fd5 100644 --- a/config/alfresco/repository.properties +++ b/config/alfresco/repository.properties @@ -504,27 +504,6 @@ version.store.enableAutoVersioning=true version.store.deprecated.lightWeightVersionStore=workspace://lightWeightVersionStore version.store.version2Store=workspace://version2Store -version.store.migrateVersionStore.threadCount=3 -version.store.migrateVersionStore.batchSize=1 - -version.store.migrateCleanupJob.threadCount=3 -version.store.migrateCleanupJob.batchSize=1 - - -# WARNING: For non-production testing only !!! Do not change (to avoid version store issues, including possible mismatch). Should be false since lightWeightVersionStore is deprecated. -version.store.onlyUseDeprecatedV1=false - -# The CRON expression to trigger migration of the version store from V1 (2.x) to V2 (3.x) -# By default, this is effectively 'never' but can be modified as required. -# Examples: -# Never: * * * * * ? 2099 -# Once every thirty minutes: 0 0/30 * * * ? -# See http://www.quartz-scheduler.org/docs/tutorials/crontrigger.html -version.store.migrateVersionStore.cronExpression=* * * * * ? 2099 -# Limit number of version histories to migrate per job cycle, where -1 = unlimited. Note: if limit > 0 then need to schedule job to run regularly in order to complete the migration. -version.store.migrateVersionStore.limitPerJobCycle=-1 -version.store.migrateVersionStore.runAsScheduledJob=false - # Optional Comparator class name to sort versions. # Set to: org.alfresco.repo.version.common.VersionLabelComparator # if upgrading from a version that used unordered sequences in a cluster. diff --git a/config/alfresco/scheduled-jobs-context.xml b/config/alfresco/scheduled-jobs-context.xml index ab580f86e7..56419bf05b 100644 --- a/config/alfresco/scheduled-jobs-context.xml +++ b/config/alfresco/scheduled-jobs-context.xml @@ -200,82 +200,6 @@ - - - org.alfresco.repo.admin.patch.impl.MigrateVersionStorePatch$MigrateVersionStoreJob - - - - - - - - - - - - - - - - - - - ${version.store.migrateVersionStore.cronExpression} - - - ${system.cronJob.startDelayMinutes} - - - - - - - - - org.alfresco.repo.version.MigrationCleanupJob - - - - - - - - - - - ${version.store.onlyUseDeprecatedV1} - - - ${version.store.migrateCleanupJob.batchSize} - - - ${version.store.migrateCleanupJob.threadCount} - - - ${version.store.migrateVersionStore.runAsScheduledJob} - - - - - - - - - - - - - - - 1 - - - 0 - - - - diff --git a/source/java/org/alfresco/repo/admin/patch/impl/MigrateVersionStorePatch.java b/source/java/org/alfresco/repo/admin/patch/impl/MigrateVersionStorePatch.java deleted file mode 100644 index 4a50d09b54..0000000000 --- a/source/java/org/alfresco/repo/admin/patch/impl/MigrateVersionStorePatch.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.admin.patch.impl; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.admin.patch.AbstractPatch; -import org.alfresco.repo.importer.ImporterBootstrap; -import org.alfresco.repo.lock.JobLockService; -import org.alfresco.repo.lock.LockAcquisitionException; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.tenant.TenantService; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.repo.version.VersionMigrator; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.quartz.Job; -import org.quartz.JobDataMap; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Migrate version store from workspace://lightWeightVersionStore to workspace://version2Store - */ -public class MigrateVersionStorePatch extends AbstractPatch -{ - private static Log logger = LogFactory.getLog(MigrateVersionStorePatch.class); - - // Lock key - public static final QName LOCK = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "MigrateVersionStore"); - - // The maximum time this lock will be held for (30 mins) - unless refreshed - //public static final long LOCK_TTL = 1000 * 60 * 30; - public static final long LOCK_TTL = 30000; - - - private static final String MSG_DONE = "patch.migrateVersionStore.done"; - private static final String MSG_INCOMPLETE = "patch.migrateVersionStore.incomplete"; - - private VersionMigrator versionMigrator; - private TenantService tenantService; - private ImporterBootstrap version2ImporterBootstrap; - private JobLockService jobLockService; - - private int batchSize = 1; - private int threadCount = 2; - - private int limitPerJobCycle = -1; // if run as scheduled job then can limit the number of version histories to migrate (per job invocation) - - private boolean migrationComplete = false; - - private boolean deleteImmediately = false; - - private boolean runAsScheduledJob = false; - private boolean useDeprecatedV1 = false; - - private ThreadLocal runningAsJob = new ThreadLocal(); - - /** - * Default constructor - */ - public MigrateVersionStorePatch() - { - runningAsJob.set(Boolean.FALSE); - } - - public void setVersionMigrator(VersionMigrator versionMigrator) - { - this.versionMigrator = versionMigrator; - } - - public void setTenantService(TenantService tenantService) - { - this.tenantService = tenantService; - } - - public void setImporterBootstrap(ImporterBootstrap version2ImporterBootstrap) - { - this.version2ImporterBootstrap = version2ImporterBootstrap; - } - - public void setJobLockService(JobLockService jobLockService) - { - this.jobLockService = jobLockService; - } - - public void setBatchSize(int batchSize) - { - this.batchSize = batchSize; - } - - public void setThreadCount(int threadCount) - { - this.threadCount = threadCount; - } - - public void setLimitPerJobCycle(int limitPerJobCycle) - { - this.limitPerJobCycle = limitPerJobCycle; - } - - public void setDeleteImmediately(boolean deleteImmediately) - { - this.deleteImmediately = deleteImmediately; - } - - /** - * Set whether the patch execution should just bypass any actual work i.e. the admin has - * chosen to manually trigger the work. - * - * @param runAsScheduledJob true to leave all work up to the scheduled job - */ - public void setRunAsScheduledJob(boolean runAsScheduledJob) - { - this.runAsScheduledJob = runAsScheduledJob; - } - - public void setOnlyUseDeprecatedV1(boolean useDeprecatedV1) - { - this.useDeprecatedV1 = useDeprecatedV1; - } - - public void init() - { - if (batchSize < 1) - { - String errorMessage = "batchSize ("+batchSize+") cannot be less than 1"; - logger.error(errorMessage); - throw new AlfrescoRuntimeException(errorMessage); - } - - if (threadCount < 1) - { - String errorMessage = "threadCount ("+threadCount+") cannot be less than 1"; - logger.error(errorMessage); - throw new AlfrescoRuntimeException(errorMessage); - } - - super.init(); - } - - /** - * Method called when executed as a scheduled job. - */ - private void executeViaJob() - { - AuthenticationUtil.RunAsWork patchRunAs = new AuthenticationUtil.RunAsWork() - { - public String doWork() throws Exception - { - RetryingTransactionCallback patchTxn = new RetryingTransactionCallback() - { - public String execute() throws Exception - { - try - { - runningAsJob.set(Boolean.TRUE); - String report = applyInternal(); - // done - return report; - } - finally - { - runningAsJob.set(Boolean.FALSE); // Back to default - } - } - }; - return transactionHelper.doInTransaction(patchTxn); - } - }; - String report = AuthenticationUtil.runAs(patchRunAs, AuthenticationUtil.getSystemUserName()); - if (report != null) - { - logger.info(report); - } - } - - /** - * Gets a set of work to do and executes it within this transaction. - * Can be kicked off via a job or called as a patch. - * - * Note that this is not wrapped in a transaction. The patch manages - * its own transactions. - */ - @Override - protected String applyInternal() throws Exception - { - if (useDeprecatedV1) - { - // Nothing to do - return null; - } - - if (migrationComplete) - { - // Nothing to do - return null; - } - - final boolean isRunningAsJob = runningAsJob.get().booleanValue(); - - // Do we bug out of patch execution - if (runAsScheduledJob && !isRunningAsJob) - { - return I18NUtil.getMessage("patch.migrateVersionStore.bypassingPatch"); - } - - // Lock - final String lockToken = getLock(); - if (lockToken == null) - { - // Some other process is busy - if (isRunningAsJob) - { - // Fine, we're doing batches (or lock still present) - - if (logger.isDebugEnabled()) - { - logger.debug("Cannot get lock - an earlier job is still busy (or previous lock has not yet expired after failure - TTL was "+LOCK_TTL+" ms)"); - } - return null; - } - else - { - throw new RuntimeException("Unable to get job lock during patch execution. Only one server should perform the upgrade."); - } - } - - if (isRunningAsJob && (! this.deleteImmediately)) - { - if (logger.isDebugEnabled()) - { - logger.debug("VersionMigrator is running as a background job will immediately delete old versions (after they are migrated"); - } - - this.deleteImmediately = true; - } - - try - { - RetryingTransactionCallback preMigrate = new RetryingTransactionCallback() - { - public Boolean execute() throws Throwable - { - if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_READ_WRITE) - { - // Nothing to do - return false; - } - - if (tenantService.isEnabled() && tenantService.isTenantUser()) - { - // bootstrap new version store - StoreRef bootstrapStoreRef = version2ImporterBootstrap.getStoreRef(); - - if (! nodeService.exists(bootstrapStoreRef)) - { - bootstrapStoreRef = tenantService.getName(AuthenticationUtil.getRunAsUser(), bootstrapStoreRef); - version2ImporterBootstrap.setStoreUrl(bootstrapStoreRef.toString()); - version2ImporterBootstrap.bootstrap(); - } - } - - if (AuthenticationUtil.getRunAsUser() == null) - { - logger.info("Set system user"); - AuthenticationUtil.setRunAsUser(AuthenticationUtil.getSystemUserName()); - } - - return true; - } - }; - Boolean doMigration = transactionHelper.doInTransaction(preMigrate); - if(!doMigration.booleanValue()) - { - return null; - } - - Boolean migrated = versionMigrator.migrateVersions(batchSize, threadCount, limitPerJobCycle, deleteImmediately, lockToken, isRunningAsJob); - - migrationComplete = (migrated != null ? migrated : true); - - // return the result message - if (migrated != null) - { - if (migrationComplete) - { - return I18NUtil.getMessage(MSG_DONE); - } - else if (! isRunningAsJob) - { - return I18NUtil.getMessage(MSG_INCOMPLETE); - } - } - - return null; - } - finally - { - releaseLock(lockToken); - } - } - - /** - * Attempts to get the lock. If the lock couldn't be taken, then null is returned. - * - * @return Returns the lock token or null - */ - private String getLock() - { - String lockToken = null; - try - { - lockToken = jobLockService.getLock(LOCK, LOCK_TTL); - if (lockToken != null) - { - if (logger.isTraceEnabled()) - { - logger.trace("Got lock: "+lockToken+" with TTL of "+LOCK_TTL+" ms ["+AlfrescoTransactionSupport.getTransactionId()+"]["+Thread.currentThread().getId()+"]"); - } - } - } - catch (LockAcquisitionException e) - { - // ignore - } - return lockToken; - } - - /** - * Attempts to release the lock. - */ - private void releaseLock(String lockToken) - { - if (lockToken == null) - { - throw new IllegalArgumentException("Must provide existing lockToken"); - } - jobLockService.releaseLock(lockToken, LOCK); - - if (logger.isTraceEnabled()) - { - logger.trace("Released lock: "+lockToken+" ["+AlfrescoTransactionSupport.getTransactionId()+"]["+Thread.currentThread().getId()+"]"); - } - } - - - - /** - * Job to initiate the {@link MigrateVersionStorePatch} - * - * @author janv - * @since 3.3.1 - */ - public static class MigrateVersionStoreJob implements Job - { - public MigrateVersionStoreJob() - { - } - - /** - * Calls the cleaner to do its work - */ - public void execute(JobExecutionContext context) throws JobExecutionException - { - JobDataMap jobData = context.getJobDetail().getJobDataMap(); - - // extract the migrator to use - Object migrateVersionStoreObj = jobData.get("migrateVersionStore"); - if (migrateVersionStoreObj == null || !(migrateVersionStoreObj instanceof MigrateVersionStorePatch)) - { - throw new AlfrescoRuntimeException("'migrateVersionStore' data must contain valid 'MigrateVersionStore' reference"); - } - - MigrateVersionStorePatch migrateVersionStore = (MigrateVersionStorePatch) migrateVersionStoreObj; - migrateVersionStore.executeViaJob(); - } - } - -} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/admin/patch/impl/SitePermissionRefactorPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/SitePermissionRefactorPatch.java deleted file mode 100644 index 8c33a2de32..0000000000 --- a/source/java/org/alfresco/repo/admin/patch/impl/SitePermissionRefactorPatch.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.admin.patch.impl; - -import java.util.List; -import java.util.Set; - -import org.alfresco.repo.admin.patch.AbstractPatch; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.site.SiteServiceImpl; -import org.alfresco.service.cmr.security.AccessPermission; -import org.alfresco.service.cmr.security.AuthorityService; -import org.alfresco.service.cmr.security.AuthorityType; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.cmr.site.SiteInfo; -import org.alfresco.service.cmr.site.SiteService; -import org.alfresco.service.namespace.QName; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Patch's the site permission model to use groups to contain users. - * - * @author Roy Wetherall - */ -public class SitePermissionRefactorPatch extends AbstractPatch -{ - /** Messages */ - private static final String STATUS_MSG = "patch.sitePermissionRefactorPatch.result"; - - /** Services */ - private SiteService siteService; - private PermissionService permissionService; - private AuthorityService authorityService; - - /** - * Set site service - * - * @param siteService the site service - */ - public void setSiteService(SiteService siteService) - { - this.siteService = siteService; - } - - /** - * Set the permission service - * - * @param permissionService the permission service - */ - public void setPermissionService(PermissionService permissionService) - { - this.permissionService = permissionService; - } - - /** - * The authority service - * - * @param authorityService the authority service - */ - public void setAuthorityService(AuthorityService authorityService) - { - this.authorityService = authorityService; - } - - /** - * @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal() - */ - @Override - protected String applyInternal() throws Exception - { - // NOTE: SiteService is not currently MT-enabled (eg. getSiteRoot) so skip if applied to tenant - if (AuthenticationUtil.isRunAsUserTheSystemUser() || !AuthenticationUtil.isMtEnabled()) - { - // Set all the sites in the repository - List sites = this.siteService.listSites(null, null); - for (SiteInfo siteInfo : sites) - { - // Create the site's groups - String siteGroup = authorityService.createAuthority( - AuthorityType.GROUP, - ((SiteServiceImpl)this.siteService).getSiteGroup(siteInfo.getShortName(), - false)); - QName siteType = nodeService.getType(siteInfo.getNodeRef()); - Set permissions = permissionService.getSettablePermissions(siteType); - for (String permission : permissions) - { - // Create a group for the permission - String permissionGroup = authorityService.createAuthority( - AuthorityType.GROUP, - ((SiteServiceImpl)this.siteService).getSiteRoleGroup( - siteInfo.getShortName(), - permission, - false)); - authorityService.addAuthority(siteGroup, permissionGroup); - - // Assign the group the relevant permission on the site - permissionService.setPermission(siteInfo.getNodeRef(), permissionGroup, permission, true); - } - - // Take the current members and assign them to the appropriate groups - Set currentPermissions = this.permissionService.getAllSetPermissions(siteInfo.getNodeRef()); - for (AccessPermission permission : currentPermissions) - { - // Only support user's being transfered (if public the everyone group will stay on the node) - if (permission.getAuthorityType() == AuthorityType.USER) - { - // Add this authority to the appropriate group - String group = ((SiteServiceImpl)this.siteService).getSiteRoleGroup( - siteInfo.getShortName(), - permission.getPermission(), - true); - this.authorityService.addAuthority(group, permission.getAuthority()); - - // Remove the permission from the node - this.permissionService.deletePermission(siteInfo.getNodeRef(), permission.getAuthority(), permission.getPermission()); - } - } - } - } - - // Report status - return I18NUtil.getMessage(STATUS_MSG); - } -} diff --git a/source/java/org/alfresco/repo/version/MigrationCleanupJob.java b/source/java/org/alfresco/repo/version/MigrationCleanupJob.java deleted file mode 100644 index cdc9cc24f0..0000000000 --- a/source/java/org/alfresco/repo/version/MigrationCleanupJob.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2005-2013 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.version; - -import java.util.List; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.tenant.Tenant; -import org.alfresco.repo.tenant.TenantAdminService; -import org.alfresco.repo.tenant.TenantUtil; -import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.quartz.Job; -import org.quartz.JobDataMap; -import org.quartz.JobExecutionContext; -import org.quartz.JobExecutionException; - -/** - * Cleanup of Version Store Migration - to delete old/migrated version histories from old version store. Typically this is configured to run once on startup. - */ -public class MigrationCleanupJob implements Job -{ - private static Log logger = LogFactory.getLog(MigrationCleanupJob.class); - - private static final String KEY_VERSION_MIGRATOR = "versionMigrator"; - private static final String KEY_TENANT_ADMIN_SERVICE = "tenantAdminService"; - private static final String KEY_BATCH_SIZE = "batchSize"; - private static final String KEY_THREAD_COUNT = "threadCount"; - private static final String KEY_ONLY_USE_DEPRECATED_V1 = "onlyUseDeprecatedV1"; - private static final String KEY_MIGRATE_RUN_AS_JOB = "migrateRunAsScheduledJob"; - - private int batchSize = 1; - private int threadCount = 2; - - private boolean useDeprecatedV1 = false; - private boolean migrateRunAsJob = false; - - public void execute(JobExecutionContext context) throws JobExecutionException - { - JobDataMap jobData = context.getJobDetail().getJobDataMap(); - - String migrateRunAsJobStr = (String)jobData.get(KEY_MIGRATE_RUN_AS_JOB); - if (migrateRunAsJobStr != null) - { - try - { - migrateRunAsJob = new Boolean(migrateRunAsJobStr); - } - catch (Exception e) - { - logger.warn("Invalid 'migrateRunAsJob' value, using default: " + migrateRunAsJob, e); - } - } - - if (migrateRunAsJob) - { - // skip cleanup - if (logger.isDebugEnabled()) - { - logger.debug("Skipping migration cleanup since migration is running as a job (which walso performs the delete)"); - } - - return; - } - - String onlyUseDeprecatedV1Str = (String)jobData.get(KEY_ONLY_USE_DEPRECATED_V1); - if (onlyUseDeprecatedV1Str != null) - { - try - { - useDeprecatedV1 = new Boolean(onlyUseDeprecatedV1Str); - } - catch (Exception e) - { - logger.warn("Invalid 'onlyUseDeprecatedV1' value, using default: " + useDeprecatedV1, e); - } - } - - - if (useDeprecatedV1) - { - // skip cleanup - if (logger.isDebugEnabled()) - { - logger.debug("Skipping migration cleanup since only using deprecated version1 store"); - } - - return; - } - - final VersionMigrator migrationCleanup = (VersionMigrator)jobData.get(KEY_VERSION_MIGRATOR); - final TenantAdminService tenantAdminService = (TenantAdminService)jobData.get(KEY_TENANT_ADMIN_SERVICE); - - if (migrationCleanup == null) - { - throw new JobExecutionException("Missing job data: " + KEY_VERSION_MIGRATOR); - } - - String batchSizeStr = (String)jobData.get(KEY_BATCH_SIZE); - if (batchSizeStr != null) - { - try - { - batchSize = new Integer(batchSizeStr); - } - catch (Exception e) - { - logger.warn("Invalid 'batchSize' value, using default: " + batchSize, e); - } - } - - if (batchSize < 1) - { - String errorMessage = "batchSize ("+batchSize+") cannot be less than 1"; - logger.error(errorMessage); - throw new AlfrescoRuntimeException(errorMessage); - } - - String threadCountStr = (String)jobData.get(KEY_THREAD_COUNT); - if (threadCountStr != null) - { - try - { - threadCount = new Integer(threadCountStr); - } - catch (Exception e) - { - logger.warn("Invalid 'threadCount' value, using default: " + threadCount, e); - } - } - - if (threadCount < 1) - { - String errorMessage = "threadCount ("+threadCount+") cannot be less than 1"; - logger.error(errorMessage); - throw new AlfrescoRuntimeException(errorMessage); - } - - if (AuthenticationUtil.getRunAsUser() == null) - { - logger.info("Set system user"); - AuthenticationUtil.setRunAsUser(AuthenticationUtil.getSystemUserName()); - } - - // perform the cleanup of the old version store - migrationCleanup.executeCleanup(batchSize, threadCount); - - if ((tenantAdminService != null) && tenantAdminService.isEnabled()) - { - List tenants = tenantAdminService.getAllTenants(); - for (Tenant tenant : tenants) - { - TenantUtil.runAsSystemTenant(new TenantRunAsWork() - { - public Object doWork() throws Exception - { - migrationCleanup.executeCleanup(batchSize, threadCount); - return null; - } - }, tenant.getTenantDomain()); - } - } - } -} diff --git a/source/java/org/alfresco/repo/version/Version2ServiceImpl.java b/source/java/org/alfresco/repo/version/Version2ServiceImpl.java index 5fac2d3307..ab98fa8f8c 100644 --- a/source/java/org/alfresco/repo/version/Version2ServiceImpl.java +++ b/source/java/org/alfresco/repo/version/Version2ServiceImpl.java @@ -66,28 +66,13 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe { private static Log logger = LogFactory.getLog(Version2ServiceImpl.class); - protected boolean useDeprecatedV1 = false; // bypass V2, only use V1 - private PermissionService permissionService; - private VersionServiceImpl version1Service = new VersionServiceImpl(); - private VersionMigrator versionMigrator; - public void setPermissionService(PermissionService permissionService) { this.permissionService = permissionService; } - public void setVersionMigrator(VersionMigrator versionMigrator) - { - this.versionMigrator = versionMigrator; - } - - public void setOnlyUseDeprecatedV1(boolean useDeprecatedV1) - { - this.useDeprecatedV1 = useDeprecatedV1; - } - /** * Initialise method */ @@ -95,22 +80,9 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe public void initialise() { super.initialise(); - - if (useDeprecatedV1) - { - logger.warn("version.store.onlyUseDeprecatedV1=true - using deprecated 'lightWeightVersionStore' by default (not 'version2Store')"); - } - else - { - version1Service.setNodeService(dbNodeService); - version1Service.setDbNodeService(dbNodeService); - } } - /* (non-Javadoc) - * @see org.alfresco.repo.service.cmr.version.VersionService#getVersionStoreReference() - */ @Override public StoreRef getVersionStoreReference() { @@ -120,14 +92,10 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - return super.getVersionStoreReference(); - } - return new StoreRef(StoreRef.PROTOCOL_WORKSPACE, Version2Model.STORE_ID); } + @Override public Version createVersion( NodeRef nodeRef, Map versionProperties) @@ -139,11 +107,6 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - return super.createVersion(nodeRef, versionProperties); - } - long startTime = System.currentTimeMillis(); int versionNumber = 0; // deprecated (unused) @@ -159,9 +122,7 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe return version; } - /* (non-Javadoc) - * @see org.alfresco.repo.service.cmr.version.VersionService#createVersion(java.util.Collection, java.util.Map) - */ + @Override public Collection createVersion( Collection nodeRefs, Map versionProperties) @@ -178,11 +139,6 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe * parents get versioned before the children and the children are not already versioned then the parents * child references will be pointing to the node ref, rather than the version history. */ - if (useDeprecatedV1) - { - return super.createVersion(nodeRefs, versionProperties); - } - long startTime = System.currentTimeMillis(); Collection result = new ArrayList(nodeRefs.size()); @@ -203,6 +159,7 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe return result; } + @Override protected Version createVersion( NodeRef nodeRef, Map origVersionProperties, @@ -215,11 +172,6 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - return super.createVersion(nodeRef, origVersionProperties, versionNumber); - } - long startTime = System.currentTimeMillis(); // Copy the version properties (to prevent unexpected side effects to the caller) @@ -259,39 +211,6 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe NodeRef versionHistoryRef = getVersionHistoryNodeRef(nodeRef); NodeRef currentVersionRef = null; - if (versionHistoryRef == null) - { - // check for lazy migration - if (! versionMigrator.isMigrationComplete()) - { - NodeRef oldVHRef = version1Service.getVersionHistoryNodeRef(nodeRef); - if (oldVHRef != null) - { - if (logger.isDebugEnabled()) - { - logger.debug("Lazily migrate old version history (background migration in progress): "+oldVHRef); - } - - try - { - versionMigrator.migrateVersion(oldVHRef, true); - } - catch (Throwable t) - { - throw new AlfrescoRuntimeException("Failed to lazily migrate old version history: "+oldVHRef, t); - } - - // should now be able to get new version history - versionHistoryRef = getVersionHistoryNodeRef(nodeRef); - - if (versionHistoryRef == null) - { - throw new AlfrescoRuntimeException("Failed to find lazily migrated version history for node: "+nodeRef); - } - } - } - } - Version currentVersion = null; if (versionHistoryRef == null) @@ -438,9 +357,7 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe return childAssocRef.getChildRef(); } - /* (non-Javadoc) - * @see org.alfresco.repo.service.cmr.version.VersionService#getVersionHistory(org.alfresco.service.cmr.repository.NodeRef) - */ + @Override public VersionHistory getVersionHistory(NodeRef nodeRef) { if (logger.isDebugEnabled()) @@ -449,11 +366,6 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - return super.getVersionHistory(nodeRef); - } - VersionHistory versionHistory = null; // Get the version history regardless of whether the node is still 'live' or not @@ -462,30 +374,10 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe { versionHistory = buildVersionHistory(versionHistoryRef, nodeRef); } - else - { - // to allow (optional) lazy migration - if (! versionMigrator.isMigrationComplete()) - { - NodeRef oldVHRef = version1Service.getVersionHistoryNodeRef(nodeRef); - if (oldVHRef != null) - { - if (logger.isDebugEnabled()) - { - logger.debug("Get old version history (background migration in progress): "+oldVHRef); - } - - versionHistory = version1Service.getVersionHistory(nodeRef); - } - } - } - return versionHistory; } - /* (non-Javadoc) - * @see org.alfresco.repo.service.cmr.version.VersionService#getCurrentVersion(org.alfresco.service.cmr.repository.NodeRef) - */ + @Override public Version getCurrentVersion(NodeRef nodeRef) { if (logger.isDebugEnabled()) @@ -494,11 +386,6 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - return super.getCurrentVersion(nodeRef); - } - Version version = null; // get the current version, if the 'live' (versioned) node has the "versionable" aspect @@ -807,13 +694,9 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe * @param nodeRef the node reference * @return a constructed version history object */ + @Override protected VersionHistory buildVersionHistory(NodeRef versionHistoryRef, NodeRef nodeRef) { - if (useDeprecatedV1) - { - return super.buildVersionHistory(versionHistoryRef, nodeRef); - } - VersionHistory versionHistory = null; // List of versions with current one last and root one first. @@ -850,13 +733,9 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe * @param versionRef the version reference * @return object containing verison data */ + @Override protected Version getVersion(NodeRef versionRef) { - if (useDeprecatedV1) - { - return super.getVersion(versionRef); - } - if (versionRef == null) { return null; @@ -894,16 +773,10 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe { versionProperties.put(VersionBaseModel.PROP_VERSION_LABEL, (String)value); } - else if (key.equals(Version2Model.PROP_QNAME_VERSION_NUMBER)) - { - // deprecated (unused) - //versionProperties.put(VersionBaseModel.PROP_VERSION_NUMBER, (Integer)value); - } else { if (keyName.equals(Version.PROP_DESCRIPTION) || - keyName.equals(VersionBaseModel.PROP_VERSION_LABEL) || - keyName.equals(VersionBaseModel.PROP_VERSION_NUMBER)) + keyName.equals(VersionBaseModel.PROP_VERSION_LABEL)) { // ignore reserved localname (including cm:description, cm:versionLabel) } @@ -935,13 +808,9 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe * @param nodeRef a node reference * @return a reference to the version history node, null of none */ + @Override protected NodeRef getVersionHistoryNodeRef(NodeRef nodeRef) { - if (useDeprecatedV1) - { - return super.getVersionHistoryNodeRef(nodeRef); - } - // assume noderef is a 'live' node NodeRef vhNodeRef = this.dbNodeService.getChildByName(getRootNode(), Version2Model.CHILD_QNAME_VERSION_HISTORIES, nodeRef.getId()); @@ -1070,9 +939,7 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe } } - /** - * @see org.alfresco.cms.version.VersionService#revert(NodeRef) - */ + @Override public void revert(NodeRef nodeRef) { if (logger.isDebugEnabled()) @@ -1081,19 +948,10 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - super.revert(nodeRef, getCurrentVersion(nodeRef), true); - } - else - { - revert(nodeRef, getCurrentVersion(nodeRef), true); - } + revert(nodeRef, getCurrentVersion(nodeRef), true); } - /** - * @see org.alfresco.service.cmr.version.VersionService#revert(org.alfresco.service.cmr.repository.NodeRef, boolean) - */ + @Override public void revert(NodeRef nodeRef, boolean deep) { if (logger.isDebugEnabled()) @@ -1102,19 +960,10 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - super.revert(nodeRef, getCurrentVersion(nodeRef), deep); - } - else - { - revert(nodeRef, getCurrentVersion(nodeRef), deep); - } + revert(nodeRef, getCurrentVersion(nodeRef), deep); } - /** - * @see org.alfresco.service.cmr.version.VersionService#revert(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.version.Version) - */ + @Override public void revert(NodeRef nodeRef, Version version) { if (logger.isDebugEnabled()) @@ -1123,19 +972,10 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - super.revert(nodeRef, version, true); - } - else - { - revert(nodeRef, version, true); - } + revert(nodeRef, version, true); } - /** - * @see org.alfresco.service.cmr.version.VersionService#revert(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.version.Version, boolean) - */ + @Override public void revert(NodeRef nodeRef, Version version, boolean deep) { if (logger.isDebugEnabled()) @@ -1149,261 +989,245 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("revert nodeRef:" + nodeRef); } - if (useDeprecatedV1) + // Check the mandatory parameters + ParameterCheck.mandatory("nodeRef", nodeRef); + ParameterCheck.mandatory("version", version); + + // Cross check that the version provided relates to the node reference provided + if (nodeRef.getId().equals(((NodeRef)version.getVersionProperty(Version2Model.PROP_FROZEN_NODE_REF)).getId()) == false) { - super.revert(nodeRef, version, deep); + // Error since the version provided does not correspond to the node reference provided + throw new VersionServiceException(MSGID_ERR_REVERT_MISMATCH); } - else - { - // Check the mandatory parameters - ParameterCheck.mandatory("nodeRef", nodeRef); - ParameterCheck.mandatory("version", version); - - // Cross check that the version provided relates to the node reference provided - if (nodeRef.getId().equals(((NodeRef)version.getVersionProperty(Version2Model.PROP_FROZEN_NODE_REF)).getId()) == false) + + // Turn off any auto-version policy behaviours + this.policyBehaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); + try + { + // The current (old) values + Map oldProps = this.nodeService.getProperties(nodeRef); + Set oldAspectQNames = this.nodeService.getAspects(nodeRef); + QName oldNodeTypeQName = nodeService.getType(nodeRef); + // Store the current version label + String currentVersionLabel = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL); + + // The frozen (which will become new) values + // Get the node that represents the frozen state + NodeRef versionNodeRef = version.getFrozenStateNodeRef(); + Map newProps = this.nodeService.getProperties(versionNodeRef); + VersionUtil.convertFrozenToOriginalProps(newProps); + Set newAspectQNames = this.nodeService.getAspects(versionNodeRef); + + // RevertDetails - given to policy behaviours + VersionRevertDetailsImpl revertDetails = new VersionRevertDetailsImpl(); + revertDetails.setNodeRef(nodeRef); + revertDetails.setNodeType(oldNodeTypeQName); + + // Do we want to maintain any existing property values? + Collection propsToLeaveAlone = new ArrayList(); + Collection assocsToLeaveAlone = new ArrayList(); + + TypeDefinition typeDef = dictionaryService.getType(oldNodeTypeQName); + if(typeDef != null) { - // Error since the version provided does not correspond to the node reference provided - throw new VersionServiceException(MSGID_ERR_REVERT_MISMATCH); + for(QName assocName : typeDef.getAssociations().keySet()) + { + if(getRevertAssocAction(oldNodeTypeQName, assocName, revertDetails) == RevertAssocAction.IGNORE) + { + assocsToLeaveAlone.add(assocName); + } + } } - - // Turn off any auto-version policy behaviours - this.policyBehaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); - try - { - // The current (old) values - Map oldProps = this.nodeService.getProperties(nodeRef); - Set oldAspectQNames = this.nodeService.getAspects(nodeRef); - QName oldNodeTypeQName = nodeService.getType(nodeRef); - // Store the current version label - String currentVersionLabel = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL); - - // The frozen (which will become new) values - // Get the node that represents the frozen state - NodeRef versionNodeRef = version.getFrozenStateNodeRef(); - Map newProps = this.nodeService.getProperties(versionNodeRef); - VersionUtil.convertFrozenToOriginalProps(newProps); - Set newAspectQNames = this.nodeService.getAspects(versionNodeRef); - - // RevertDetails - given to policy behaviours - VersionRevertDetailsImpl revertDetails = new VersionRevertDetailsImpl(); - revertDetails.setNodeRef(nodeRef); - revertDetails.setNodeType(oldNodeTypeQName); - - // Do we want to maintain any existing property values? - Collection propsToLeaveAlone = new ArrayList(); - Collection assocsToLeaveAlone = new ArrayList(); - - TypeDefinition typeDef = dictionaryService.getType(oldNodeTypeQName); - if(typeDef != null) - { - for(QName assocName : typeDef.getAssociations().keySet()) - { - if(getRevertAssocAction(oldNodeTypeQName, assocName, revertDetails) == RevertAssocAction.IGNORE) + + for (QName aspect : oldAspectQNames) + { + AspectDefinition aspectDef = dictionaryService.getAspect(aspect); + if(aspectDef != null) + { + if (getRevertAspectAction(aspect, revertDetails) == RevertAspectAction.IGNORE) + { + propsToLeaveAlone.addAll(aspectDef.getProperties().keySet()); + } + for(QName assocName : aspectDef.getAssociations().keySet()) + { + if(getRevertAssocAction(aspect, assocName, revertDetails) == RevertAssocAction.IGNORE) { - assocsToLeaveAlone.add(assocName); - } - } - } - - for (QName aspect : oldAspectQNames) - { - AspectDefinition aspectDef = dictionaryService.getAspect(aspect); - if(aspectDef != null) - { - if (getRevertAspectAction(aspect, revertDetails) == RevertAspectAction.IGNORE) - { - propsToLeaveAlone.addAll(aspectDef.getProperties().keySet()); - } - for(QName assocName : aspectDef.getAssociations().keySet()) - { - if(getRevertAssocAction(aspect, assocName, revertDetails) == RevertAssocAction.IGNORE) - { - assocsToLeaveAlone.addAll(aspectDef.getAssociations().keySet()); - } - } - } - } - - for(QName prop : propsToLeaveAlone) + assocsToLeaveAlone.addAll(aspectDef.getAssociations().keySet()); + } + } + } + } + + for(QName prop : propsToLeaveAlone) + { + if(oldProps.containsKey(prop)) { - if(oldProps.containsKey(prop)) - { - newProps.put(prop, oldProps.get(prop)); - } + newProps.put(prop, oldProps.get(prop)); } - - this.nodeService.setProperties(nodeRef, newProps); + } + + this.nodeService.setProperties(nodeRef, newProps); - Set aspectsToRemove = new HashSet(oldAspectQNames); - aspectsToRemove.removeAll(newAspectQNames); - - Set aspectsToAdd = new HashSet(newAspectQNames); - aspectsToAdd.removeAll(oldAspectQNames); - - // add aspects that are not on the current node - for (QName aspect : aspectsToAdd) + Set aspectsToRemove = new HashSet(oldAspectQNames); + aspectsToRemove.removeAll(newAspectQNames); + + Set aspectsToAdd = new HashSet(newAspectQNames); + aspectsToAdd.removeAll(oldAspectQNames); + + // add aspects that are not on the current node + for (QName aspect : aspectsToAdd) + { + if (getRevertAspectAction(aspect, revertDetails) != RevertAspectAction.IGNORE) + { + this.nodeService.addAspect(nodeRef, aspect, null); + } + } + + // remove aspects that are not on the frozen node + for (QName aspect : aspectsToRemove) + { + if (getRevertAspectAction(aspect, revertDetails) != RevertAspectAction.IGNORE) { - if (getRevertAspectAction(aspect, revertDetails) != RevertAspectAction.IGNORE) - { - this.nodeService.addAspect(nodeRef, aspect, null); - } + this.nodeService.removeAspect(nodeRef, aspect); } - - // remove aspects that are not on the frozen node - for (QName aspect : aspectsToRemove) + } + + // Re-add the versionable aspect to the reverted node + if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false) + { + this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null); + } + + // Re-set the version label property (since it should not be modified from the original) + this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, currentVersionLabel); + + // Add/remove the child nodes + List children = new ArrayList(this.nodeService.getChildAssocs(nodeRef)); + List versionedChildren = this.nodeService.getChildAssocs(versionNodeRef); + for (ChildAssociationRef versionedChild : versionedChildren) + { + if (children.contains(versionedChild) == false) { - if (getRevertAspectAction(aspect, revertDetails) != RevertAspectAction.IGNORE) - { - this.nodeService.removeAspect(nodeRef, aspect); - } - } - - // Re-add the versionable aspect to the reverted node - if (this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == false) - { - this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null); - } - - // Re-set the version label property (since it should not be modified from the original) - this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, currentVersionLabel); - - // Add/remove the child nodes - List children = new ArrayList(this.nodeService.getChildAssocs(nodeRef)); - List versionedChildren = this.nodeService.getChildAssocs(versionNodeRef); - for (ChildAssociationRef versionedChild : versionedChildren) - { - if (children.contains(versionedChild) == false) + NodeRef childRef = null; + ChildAssociationRef assocToKeep = null; + if (this.nodeService.exists(versionedChild.getChildRef()) == true) { - NodeRef childRef = null; - ChildAssociationRef assocToKeep = null; - if (this.nodeService.exists(versionedChild.getChildRef()) == true) + // The node was a primary child of the parent, but that is no longer the case. Despite this + // the node still exits so this means it has been moved. + // The best thing to do in this situation will be to re-add the node as a child, but it will not + // be a primary child + String childRefName = (String) this.nodeService.getProperty(versionedChild.getChildRef(), ContentModel.PROP_NAME); + childRef = this.nodeService.getChildByName(nodeRef, versionedChild.getTypeQName(), childRefName); + // we can faced with association that allow duplicate names + if (childRef == null) { - // The node was a primary child of the parent, but that is no longer the case. Despite this - // the node still exits so this means it has been moved. - // The best thing to do in this situation will be to re-add the node as a child, but it will not - // be a primary child - String childRefName = (String) this.nodeService.getProperty(versionedChild.getChildRef(), ContentModel.PROP_NAME); - childRef = this.nodeService.getChildByName(nodeRef, versionedChild.getTypeQName(), childRefName); - // we can faced with association that allow duplicate names - if (childRef == null) + List allAssocs = nodeService.getParentAssocs(versionedChild.getChildRef(), versionedChild.getTypeQName(), RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef assocToCheck : allAssocs) { - List allAssocs = nodeService.getParentAssocs(versionedChild.getChildRef(), versionedChild.getTypeQName(), RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef assocToCheck : allAssocs) + if (children.contains(assocToCheck)) { - if (children.contains(assocToCheck)) - { - childRef = assocToCheck.getChildRef(); - assocToKeep = assocToCheck; - break; - } + childRef = assocToCheck.getChildRef(); + assocToKeep = assocToCheck; + break; } } - if (childRef == null ) - { - childRef = this.nodeService.addChild(nodeRef, versionedChild.getChildRef(), versionedChild.getTypeQName(), versionedChild.getQName()).getChildRef(); - } } - else + if (childRef == null ) { - if (versionedChild.isPrimary() == true) - { - // Only try to restore missing children if we are doing a deep revert - // Look and see if we have a version history for the child node - if (deep == true && getVersionHistoryNodeRef(versionedChild.getChildRef()) != null) - { - // We're going to try and restore the missing child node and recreate the assoc - childRef = restore( - versionedChild.getChildRef(), - nodeRef, - versionedChild.getTypeQName(), - versionedChild.getQName()); - } - // else the deleted child did not have a version history so we can't restore the child - // and so we can't revert the association - } - - // else - // Since this was never a primary assoc and the child has been deleted we won't recreate - // the missing node as it was never owned by the node and we wouldn't know where to put it. - } - if (childRef != null) - { - if (assocToKeep != null) - { - children.remove(assocToKeep); - } - else - { - children.remove(nodeService.getPrimaryParent(childRef)); - } - } + childRef = this.nodeService.addChild(nodeRef, versionedChild.getChildRef(), versionedChild.getTypeQName(), versionedChild.getQName()).getChildRef(); + } } else { - children.remove(versionedChild); - } - } - for (ChildAssociationRef ref : children) - { - if (!assocsToLeaveAlone.contains(ref.getTypeQName())) - { - this.nodeService.removeChild(nodeRef, ref.getChildRef()); - } - } - - // Add/remove the target associations - for (AssociationRef assocRef : this.nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL)) - { - if (!assocsToLeaveAlone.contains(assocRef.getTypeQName())) - { - this.nodeService.removeAssociation(assocRef.getSourceRef(), assocRef.getTargetRef(), assocRef.getTypeQName()); - } - } - for (AssociationRef versionedAssoc : this.nodeService.getTargetAssocs(versionNodeRef, RegexQNamePattern.MATCH_ALL)) - { - if (!assocsToLeaveAlone.contains(versionedAssoc.getTypeQName())) - { - - if (this.nodeService.exists(versionedAssoc.getTargetRef()) == true) + if (versionedChild.isPrimary() == true) { - this.nodeService.createAssociation(nodeRef, versionedAssoc.getTargetRef(), versionedAssoc.getTypeQName()); + // Only try to restore missing children if we are doing a deep revert + // Look and see if we have a version history for the child node + if (deep == true && getVersionHistoryNodeRef(versionedChild.getChildRef()) != null) + { + // We're going to try and restore the missing child node and recreate the assoc + childRef = restore( + versionedChild.getChildRef(), + nodeRef, + versionedChild.getTypeQName(), + versionedChild.getQName()); + } + // else the deleted child did not have a version history so we can't restore the child + // and so we can't revert the association } - } - - // else - // Since the target of the assoc no longer exists we can't recreate the assoc + + // else + // Since this was never a primary assoc and the child has been deleted we won't recreate + // the missing node as it was never owned by the node and we wouldn't know where to put it. + } + if (childRef != null) + { + if (assocToKeep != null) + { + children.remove(assocToKeep); + } + else + { + children.remove(nodeService.getPrimaryParent(childRef)); + } + } } + else + { + children.remove(versionedChild); + } } - finally + for (ChildAssociationRef ref : children) { - // Turn auto-version policies back on - this.policyBehaviourFilter.enableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); + if (!assocsToLeaveAlone.contains(ref.getTypeQName())) + { + this.nodeService.removeChild(nodeRef, ref.getChildRef()); + } } - invokeAfterVersionRevert(nodeRef, version); + // Add/remove the target associations + for (AssociationRef assocRef : this.nodeService.getTargetAssocs(nodeRef, RegexQNamePattern.MATCH_ALL)) + { + if (!assocsToLeaveAlone.contains(assocRef.getTypeQName())) + { + this.nodeService.removeAssociation(assocRef.getSourceRef(), assocRef.getTargetRef(), assocRef.getTypeQName()); + } + } + for (AssociationRef versionedAssoc : this.nodeService.getTargetAssocs(versionNodeRef, RegexQNamePattern.MATCH_ALL)) + { + if (!assocsToLeaveAlone.contains(versionedAssoc.getTypeQName())) + { + + if (this.nodeService.exists(versionedAssoc.getTargetRef()) == true) + { + this.nodeService.createAssociation(nodeRef, versionedAssoc.getTargetRef(), versionedAssoc.getTypeQName()); + } + } + + // else + // Since the target of the assoc no longer exists we can't recreate the assoc + } } + finally + { + // Turn auto-version policies back on + this.policyBehaviourFilter.enableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); + } + + invokeAfterVersionRevert(nodeRef, version); } - /* (non-Javadoc) - * @see org.alfresco.repo.service.cmr.version.VersionService#restore(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName) - */ + @Override public NodeRef restore( NodeRef nodeRef, NodeRef parentNodeRef, QName assocTypeQName, QName assocQName) { - if (useDeprecatedV1) - { - return super.restore(nodeRef, parentNodeRef, assocTypeQName, assocQName, true); - } - return restore(nodeRef, parentNodeRef, assocTypeQName, assocQName, true); } - /* (non-Javadoc) - * @see org.alfresco.repo.service.cmr.version.VersionService#restore(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName, boolean) - */ + @Override public NodeRef restore( NodeRef nodeRef, NodeRef parentNodeRef, @@ -1417,11 +1241,6 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) - { - return super.restore(nodeRef, parentNodeRef, assocTypeQName, assocQName, deep); - } - NodeRef restoredNodeRef = null; // Check that the node does not exist @@ -1493,9 +1312,7 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe return headVersion; } - /* (non-Javadoc) - * @see org.alfresco.repo.service.cmr.version.VersionService#deleteVersionHistory(org.alfresco.service.cmr.repository.NodeRef) - */ + @Override public void deleteVersionHistory(NodeRef nodeRef) throws AspectMissingException { @@ -1505,45 +1322,35 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) + // Get the version history node for the node is question and delete it + NodeRef versionHistoryNodeRef = getVersionHistoryNodeRef(nodeRef); + + if (versionHistoryNodeRef != null) { - super.deleteVersionHistory(nodeRef); - } - else - { - // Get the version history node for the node is question and delete it - NodeRef versionHistoryNodeRef = getVersionHistoryNodeRef(nodeRef); - - if (versionHistoryNodeRef != null) + try { - try + // Disable auto-version behaviour + this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE); + + // Delete the version history node + this.dbNodeService.deleteNode(versionHistoryNodeRef); + + if (this.nodeService.exists(nodeRef) == true && this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) { - // Disable auto-version behaviour - this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_VERSIONABLE); - - // Delete the version history node - this.dbNodeService.deleteNode(versionHistoryNodeRef); - - if (this.nodeService.exists(nodeRef) == true && this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE) == true) - { - - // Reset the version label property on the versionable node - this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, null); - } + // Reset the version label property on the versionable node + this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, null); } - finally - { - this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE); - } + + } + finally + { + this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_VERSIONABLE); } - } } - /* (non-Javadoc) - * @see org.alfresco.service.cmr.version.VersionService#deleteVersion(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.version.Version) - */ + @Override public void deleteVersion(NodeRef nodeRef, Version version) { if (logger.isDebugEnabled()) @@ -1552,47 +1359,37 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); } - if (useDeprecatedV1) + // Check the mandatory parameters + ParameterCheck.mandatory("nodeRef", nodeRef); + ParameterCheck.mandatory("version", version); + + Version currentVersion = getCurrentVersion(nodeRef); + + // Delete the version node + this.dbNodeService.deleteNode(VersionUtil.convertNodeRef(version.getFrozenStateNodeRef())); + + if (currentVersion.getVersionLabel().equals(version.getVersionLabel())) { - super.deleteVersion(nodeRef, version); // throws UnsupportedOperationException - } - else - { - // Check the mandatory parameters - ParameterCheck.mandatory("nodeRef", nodeRef); - ParameterCheck.mandatory("version", version); - - Version currentVersion = getCurrentVersion(nodeRef); - - // Delete the version node - this.dbNodeService.deleteNode(VersionUtil.convertNodeRef(version.getFrozenStateNodeRef())); - - if (currentVersion.getVersionLabel().equals(version.getVersionLabel())) + Version headVersion = getHeadVersion(nodeRef); + if (headVersion != null) { - Version headVersion = getHeadVersion(nodeRef); - if (headVersion != null) - { - // Reset the version label property on the versionable node to new head version - // Disable the VersionableAspect for this change though, we don't want - // to have this create a new version for the property change! - policyBehaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); - this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, headVersion.getVersionLabel()); - } - else - { - deleteVersionHistory(nodeRef); - } + // Reset the version label property on the versionable node to new head version + // Disable the VersionableAspect for this change though, we don't want + // to have this create a new version for the property change! + policyBehaviourFilter.disableBehaviour(nodeRef, ContentModel.ASPECT_VERSIONABLE); + this.nodeService.setProperty(nodeRef, ContentModel.PROP_VERSION_LABEL, headVersion.getVersionLabel()); + } + else + { + deleteVersionHistory(nodeRef); } } } - /* (non-Javadoc) - * @see org.alfresco.service.cmr.version.VersionService#isAVersion(org.alfresco.service.cmr.repository.NodeRef) - */ - @Override + @Override public boolean isAVersion(NodeRef nodeRef) { - if (logger.isDebugEnabled()) + if (logger.isDebugEnabled()) { logger.debug("Run as user " + AuthenticationUtil.getRunAsUser()); logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); @@ -1606,13 +1403,10 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe return this.dbNodeService.hasAspect(realNodeRef, Version2Model.ASPECT_VERSION); } - /* (non-Javadoc) - * @see org.alfresco.service.cmr.version.VersionService#isVersioned(org.alfresco.service.cmr.repository.NodeRef) - */ @Override public boolean isVersioned(NodeRef nodeRef) { - if (logger.isDebugEnabled()) + if (logger.isDebugEnabled()) { logger.debug("Run as user " + AuthenticationUtil.getRunAsUser()); logger.debug("Fully authenticated " + AuthenticationUtil.getFullyAuthenticatedUser()); @@ -1625,5 +1419,4 @@ public class Version2ServiceImpl extends VersionServiceImpl implements VersionSe } return this.dbNodeService.hasAspect(realNodeRef, ContentModel.ASPECT_VERSIONABLE); } - } diff --git a/source/java/org/alfresco/repo/version/VersionMigrator.java b/source/java/org/alfresco/repo/version/VersionMigrator.java deleted file mode 100644 index 03269c05d4..0000000000 --- a/source/java/org/alfresco/repo/version/VersionMigrator.java +++ /dev/null @@ -1,1151 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.version; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.admin.patch.impl.MigrateVersionStorePatch; -import org.alfresco.repo.batch.BatchProcessor; -import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorkerAdaptor; -import org.alfresco.repo.lock.JobLockService; -import org.alfresco.repo.node.MLPropertyInterceptor; -import org.alfresco.repo.policy.BehaviourFilter; -import org.alfresco.repo.policy.PolicyScope; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.transaction.AlfrescoTransactionSupport; -import org.alfresco.repo.transaction.RetryingTransactionHelper; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.repo.version.common.VersionUtil; -import org.alfresco.service.cmr.dictionary.ClassDefinition; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.dictionary.PropertyDefinition; -import org.alfresco.service.cmr.repository.AssociationRef; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.rule.RuleService; -import org.alfresco.service.cmr.version.Version; -import org.alfresco.service.cmr.version.VersionHistory; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.service.transaction.TransactionService; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; -import org.springframework.extensions.surf.util.I18NUtil; - -/** - * Version2 Migrator - */ -public class VersionMigrator implements ApplicationEventPublisherAware -{ - protected static Log logger = LogFactory.getLog(VersionMigrator.class); - - public static final StoreRef VERSION_STORE_REF_OLD = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, VersionModel.STORE_ID); - public static final StoreRef VERSION_STORE_REF_NEW = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, Version2Model.STORE_ID); - - private static final String MSG_PATCH_NOOP = "version_service.migration.patch.noop"; - private static final String MSG_PATCH_COMPLETE = "version_service.migration.patch.complete"; - private static final String MSG_PATCH_IN_PROGRESS = "version_service.migration.patch.in_progress"; - private static final String MSG_PATCH_SKIP1 = "version_service.migration.patch.warn.skip1"; - private static final String MSG_PATCH_SKIP2 = "version_service.migration.patch.warn.skip2"; - - private static final String MSG_DELETE_COMPLETE = "version_service.migration.delete.complete"; - private static final String MSG_DELETE_SKIP1 = "version_service.migration.delete.warn.skip1"; - private static final String MSG_DELETE_SKIP2 = "version_service.migration.delete.warn.skip2"; - - private static boolean busy = false; - - private static final String CLEAN_OLD_VERSION_STORE = "CleanOldVersionStore"; - private static final String MIGRATE_VERSION_STORE = "MigrateVersionStore"; - - public final static String PREFIX_MIGRATED = "migrated-"; - - private VersionServiceImpl version1Service = new VersionServiceImpl(); - - private Version2ServiceImpl version2Service; - private NodeService dbNodeService; - private BehaviourFilter policyBehaviourFilter; - private DictionaryService dictionaryService; - private TransactionService transactionService; - private NodeService versionNodeService; // NodeService impl which redirects to appropriate VersionService - private RuleService ruleService; - private JobLockService jobLockService; - private ApplicationEventPublisher applicationEventPublisher; - - private Boolean migrationComplete = null; - - private int loggingInterval = 500; - - //private String lockToken = null; - - public void setVersion2ServiceImpl(Version2ServiceImpl versionService) - { - this.version2Service = versionService; - } - - public void setDbNodeService(NodeService nodeService) - { - this.dbNodeService = nodeService; - } - - public void setPolicyBehaviourFilter(BehaviourFilter policyBehaviourFilter) - { - this.policyBehaviourFilter = policyBehaviourFilter; - } - - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - public void setTransactionService(TransactionService transactionService) - { - this.transactionService = transactionService; - } - - public void setVersionNodeService(NodeService versionNodeService) - { - this.versionNodeService = versionNodeService; - } - - public void setRuleService(RuleService ruleService) - { - this.ruleService = ruleService; - } - - public void setJobLockService(JobLockService jobLockService) - { - this.jobLockService = jobLockService; - } - - public void setLoggingInterval(int loggingInterval) - { - this.loggingInterval = loggingInterval; - } - - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) - { - this.applicationEventPublisher = applicationEventPublisher; - } - - - public void init() - { - version1Service.setNodeService(dbNodeService); - version1Service.setDbNodeService(dbNodeService); - - version2Service.setDbNodeService(dbNodeService); - } - - public NodeRef migrateVersionHistory(NodeRef oldVHNodeRef, NodeRef versionedNodeRef) - { - VersionHistory vh = v1BuildVersionHistory(oldVHNodeRef, versionedNodeRef); - - // create new version history node - NodeRef newVHNodeRef = v2CreateVersionHistory(versionedNodeRef); - - Version[] oldVersions = (Version[])vh.getAllVersions().toArray(new Version[]{}); - - // Disable auditable behaviour - so that migrated versions maintain their original auditable properties (eg. created, creator) - this.policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_AUDITABLE); - - try - { - for (int i = (oldVersions.length-1); i >= 0; i--) - { - // migrate versions - v2CreateNewVersion(newVHNodeRef, oldVersions[i]); - } - } - finally - { - // Enable auditable behaviour - this.policyBehaviourFilter.enableBehaviour(ContentModel.ASPECT_AUDITABLE); - } - - return newVHNodeRef; - } - - private NodeRef v2CreateVersionHistory(NodeRef nodeRef) - { - return version2Service.createVersionHistory(nodeRef); - } - - private NodeRef v2CreateNewVersion(NodeRef newVersionHistoryRef, Version oldVersion) - { - NodeRef versionedNodeRef = oldVersion.getVersionedNodeRef(); // nodeRef to versioned node in live store - NodeRef frozenStateNodeRef = oldVersion.getFrozenStateNodeRef(); // nodeRef to version node in version store - - String versionLabel = oldVersion.getVersionLabel(); - String versionDescription = oldVersion.getDescription(); - - QName sourceType = versionNodeService.getType(frozenStateNodeRef); - Set nodeAspects = versionNodeService.getAspects(frozenStateNodeRef); - Map nodeProperties = versionNodeService.getProperties(frozenStateNodeRef); - List nodeChildAssocs = versionNodeService.getChildAssocs(frozenStateNodeRef); - List nodeAssocs = versionNodeService.getTargetAssocs(frozenStateNodeRef, RegexQNamePattern.MATCH_ALL); - - long nodeDbId = (Long)nodeProperties.get(ContentModel.PROP_NODE_DBID); - - // ALFCOM-2658 - nodeProperties.put(ContentModel.PROP_NODE_UUID, frozenStateNodeRef.getId()); - - int versionNumber = 0; - - // get oldVersion auditable properties (of the version node itself, rather than the live versioned node) - NodeRef versionNode = VersionUtil.convertNodeRef(frozenStateNodeRef); - Date versionCreated = (Date)dbNodeService.getProperty(versionNode, ContentModel.PROP_CREATED); - String versionCreator = (String)dbNodeService.getProperty(versionNode, ContentModel.PROP_CREATOR); - Date versionModified = (Date)dbNodeService.getProperty(versionNode, ContentModel.PROP_MODIFIED); - String versionModifier = (String)dbNodeService.getProperty(versionNode, ContentModel.PROP_MODIFIER); - Date versionAccessed = (Date)dbNodeService.getProperty(versionNode, ContentModel.PROP_ACCESSED); - - Map versionMetaDataProperties = version1Service.getVersionMetaData(versionNode); - - // Create the node details - PolicyScope nodeDetails = new PolicyScope(sourceType); - - // add properties - for (Map.Entry entry : nodeProperties.entrySet()) - { - nodeDetails.addProperty(sourceType, entry.getKey(), entry.getValue()); - } - - // add newVersion auditable properties (of the version node itself, rather than the live versioned node) - will be set on create - nodeDetails.addProperty(sourceType, ContentModel.PROP_CREATED, versionCreated); - nodeDetails.addProperty(sourceType, ContentModel.PROP_CREATOR, versionCreator); - nodeDetails.addProperty(sourceType, ContentModel.PROP_MODIFIED, versionModified); - nodeDetails.addProperty(sourceType, ContentModel.PROP_MODIFIER, versionModifier); - nodeDetails.addProperty(sourceType, ContentModel.PROP_ACCESSED, versionAccessed); - - // add aspects - for (QName aspect : nodeAspects) - { - // add aspect - nodeDetails.addAspect(aspect); - - // copy the aspect properties - ClassDefinition classDefinition = dictionaryService.getClass(aspect); - if (classDefinition != null) - { - Map propertyDefinitions = classDefinition.getProperties(); - for (QName propertyName : propertyDefinitions.keySet()) - { - Serializable propValue = nodeProperties.get(propertyName); - nodeDetails.addProperty(aspect, propertyName, propValue); - } - } - } - - // add child assocs (since 3.3 Ent - applies only to direct upgrade from 2.x to 3.3 Ent or higher) - for (ChildAssociationRef childAssoc : nodeChildAssocs) - { - nodeDetails.addChildAssociation(sourceType, childAssoc); - } - - // add target assocs (since 3.3 Ent - applies only to direct upgrade from 2.x to 3.3 Ent or higher) - for (AssociationRef assoc : nodeAssocs) - { - nodeDetails.addAssociation(sourceType, assoc); - } - - NodeRef newVersionRef = version2Service.createNewVersion( - sourceType, - newVersionHistoryRef, - version2Service.getStandardVersionProperties(versionedNodeRef, nodeDbId, nodeAspects, versionNumber, versionLabel, versionDescription), - versionMetaDataProperties, - versionNumber, - nodeDetails); - - return newVersionRef; - } - - /** - * Check whether the V1 history represented by oldVersionHistoryRef represents - * a versioned working copy node (Alfresco V2.1.7 can create these) - * - * @param oldVersionHistoryRef - * @return - */ - protected boolean v1CheckForVersionedWorkingCopy(NodeRef oldVersionHistoryRef) - { - boolean valid = true; - - // Get versioned nodeRef from one of the versions - note: assumes all versions refer to the same versioned nodeRef - Collection versions = dbNodeService.getChildAssocs(oldVersionHistoryRef); - if (versions.size() > 0) - { - Iterator itr = versions.iterator(); - ChildAssociationRef childAssocRef = itr.next(); - NodeRef versionRef = childAssocRef.getChildRef(); - - Version version = version1Service.getVersion(versionRef); - @SuppressWarnings("unchecked") - List frozenAspects = (List)dbNodeService.getProperty(versionRef, VersionModel.PROP_QNAME_FROZEN_ASPECTS); - if(frozenAspects.contains(ContentModel.ASPECT_WORKING_COPY) && frozenAspects.contains(ContentModel.ASPECT_VERSIONABLE)) - { - valid = false; - } - } - - return valid; - } - - protected NodeRef v1GetVersionedNodeRef(NodeRef oldVersionHistoryRef) - { - NodeRef versionedNodeRef = null; - - // Get versioned nodeRef from one of the versions - note: assumes all versions refer to the same versioned nodeRef - Collection versions = dbNodeService.getChildAssocs(oldVersionHistoryRef); - if (versions.size() > 0) - { - Iterator itr = versions.iterator(); - ChildAssociationRef childAssocRef = itr.next(); - NodeRef versionRef = childAssocRef.getChildRef(); - - Version version = version1Service.getVersion(versionRef); - - versionedNodeRef = version.getVersionedNodeRef(); - } - - return versionedNodeRef; - } - - private VersionHistory v1BuildVersionHistory(NodeRef oldVersionHistoryRef, NodeRef versionedNodeRef) - { - return version1Service.buildVersionHistory(oldVersionHistoryRef, versionedNodeRef); - } - - protected void v1DeleteVersionHistory(NodeRef oldVersionHistoryRef) - { - dbNodeService.deleteNode(oldVersionHistoryRef); - } - - private void v1MarkVersionHistory(NodeRef oldVersionHistoryRef) - { - String migratedName = PREFIX_MIGRATED+oldVersionHistoryRef.getId(); - dbNodeService.setProperty(oldVersionHistoryRef, ContentModel.PROP_NAME, migratedName); - } - - public List getVersionHistories(final NodeRef rootNodeRef) - { - return dbNodeService.getChildAssocs(rootNodeRef); - } - - protected void migrateVersion(NodeRef oldVHNodeRef, boolean deleteImmediately) throws Throwable - { - if(v1CheckForVersionedWorkingCopy(oldVHNodeRef)) - { - NodeRef versionedNodeRef = v1GetVersionedNodeRef(oldVHNodeRef); - migrateVersionHistory(oldVHNodeRef, versionedNodeRef); - } - else - { - logger.warn("Have found a versioned working copy node " + oldVHNodeRef + ", skipping"); - } - - if (deleteImmediately) - { - // delete old version history node - v1DeleteVersionHistory(oldVHNodeRef); - } - else - { - // mark old version history node for later cleanup - v1MarkVersionHistory(oldVHNodeRef); - } - } - - public boolean isMigrationComplete() - { - if (migrationComplete == null) - { - NodeRef oldRootNodeRef = dbNodeService.getRootNode(VersionMigrator.VERSION_STORE_REF_OLD); - final List childAssocRefs = getVersionHistories(oldRootNodeRef); - - migrationComplete = (childAssocRefs.size() == 0); - } - - return migrationComplete; - } - - /** - * Attempts to refresh the lock. - * - * @return Returns the lock token - */ - private void refreshLock(String lockToken) - { - if ((lockToken == null) || (jobLockService == null)) - { - return; - } - jobLockService.refreshLock(lockToken, MigrateVersionStorePatch.LOCK, MigrateVersionStorePatch.LOCK_TTL); - - if (logger.isTraceEnabled()) - { - logger.trace("Refreshed lock: "+lockToken+" with TTL of "+MigrateVersionStorePatch.LOCK_TTL+" ms ["+AlfrescoTransactionSupport.getTransactionId()+"]["+Thread.currentThread().getId()+"]"); - } - } - - /** - * Construct the migration data structures for the BatchProcessor - * - * ALF-5621: construct the BatchProcessor migration work in a new transaction to ensure the - * transaction is not alive during the batch processing work. - * - * @param batchSize - * @param threadCount - * @param limit - * @param deleteImmediately - * @param lockToken - * @param isRunningAsJob - * - * @return MigrationWork, encapsulating what needs to be done for version migration - */ - private MigrationWork getMigrationWork(final int batchSize, final int threadCount, final int limit, final boolean deleteImmediately, final String lockToken, final boolean isRunningAsJob) - { - RetryingTransactionCallback buildMigrationWork = new RetryingTransactionCallback() - { - public MigrationWork execute() throws Throwable - { - final NodeRef oldRootNodeRef = dbNodeService.getRootNode(VersionMigrator.VERSION_STORE_REF_OLD); - final NodeRef newRootNodeRef = dbNodeService.getRootNode(VersionMigrator.VERSION_STORE_REF_NEW); - - refreshLock(lockToken); - - long startTime = System.currentTimeMillis(); - - final List childAssocRefs = getVersionHistories(oldRootNodeRef); - - int toDo = childAssocRefs.size(); - - if (toDo == 0) - { - if (logger.isDebugEnabled()) - { - logger.debug(I18NUtil.getMessage(MSG_PATCH_NOOP)); - } - migrationComplete = true; - return null; - } - - migrationComplete = false; - - if (logger.isInfoEnabled()) - { - logger.info("Found "+childAssocRefs.size()+" version histories in old version store (in "+((System.currentTimeMillis()-startTime)/1000)+" secs)"); - } - - if (logger.isDebugEnabled()) - { - logger.debug("batchSize="+batchSize+", batchWorkerThreadCount="+threadCount+", deleteImmediately="+deleteImmediately); - } - - long splitTime = System.currentTimeMillis(); - - boolean firstMigration = false; - - if (! isRunningAsJob) - { - List newChildAssocRefs = getVersionHistories(newRootNodeRef); - firstMigration = (newChildAssocRefs.size() == 0); - - if (logger.isInfoEnabled()) - { - if (! firstMigration) - { - logger.warn("This is not the first migration attempt. Found "+newChildAssocRefs.size()+" version histories in new version store (in "+((System.currentTimeMillis()-splitTime)/1000)+" secs)"); - } - } - } - - // note: assumes patch runs before cleanup starts - int toMigrateCount = 0; - int totalCount = 0; - int alreadyMigratedCount = 0; - - boolean wasMLAware = MLPropertyInterceptor.setMLAware(true); - - List> batchProcessorWork = new ArrayList>(2); - - try - { - // - // split into batches (ignore version histories that have already been migrated) - // - - splitTime = System.currentTimeMillis(); - - final List tmpBatch = new ArrayList(batchSize); - - int maxToDo = childAssocRefs.size(); - - if (limit > -1) - { - maxToDo = limit; - - if (logger.isInfoEnabled()) - { - logger.info("Limit this job cycle to max of "+limit+" version histories"); - } - } - - for (final ChildAssociationRef childAssocRef : childAssocRefs) - { - // short-cut if first migration - if (!firstMigration) - { - if (isMigrated(childAssocRef)) - { - // skip - already migrated - alreadyMigratedCount++; - continue; - } - } - - toMigrateCount++; - - if (tmpBatch.size() < batchSize) - { - tmpBatch.add(childAssocRef.getChildRef()); - } - - if ((tmpBatch.size() == batchSize) || - (toMigrateCount >= maxToDo) || - (totalCount == childAssocRefs.size())) - { - if (tmpBatch.size() > 0) - { - // Each thread gets 1 batch to execute - batchProcessorWork.add(new ArrayList(tmpBatch)); - tmpBatch.clear(); - } - } - - if (toMigrateCount >= maxToDo) - { - break; - } - } - } - finally - { - MLPropertyInterceptor.setMLAware(wasMLAware); - } - - return new MigrationWork(toMigrateCount, alreadyMigratedCount, toDo, batchProcessorWork, splitTime, startTime); - } - }; - - MigrationWork work = transactionService.getRetryingTransactionHelper().doInTransaction(buildMigrationWork, false, true); - return work; - } - - /** - * Do the Version migration work - * @return Returns null if no work to do, true if the work is done, false is incomplete (or in progress) - */ - public Boolean migrateVersions(final int batchSize, final int threadCount, final int limit, final boolean deleteImmediately, final String lockToken, final boolean isRunningAsJob) - { - RetryingTransactionCallback buildMigrationWork = new RetryingTransactionCallback() - { - public MigrationWork execute() throws Throwable - { - final NodeRef oldRootNodeRef = dbNodeService.getRootNode(VersionMigrator.VERSION_STORE_REF_OLD); - final NodeRef newRootNodeRef = dbNodeService.getRootNode(VersionMigrator.VERSION_STORE_REF_NEW); - - refreshLock(lockToken); - - long startTime = System.currentTimeMillis(); - - final List childAssocRefs = getVersionHistories(oldRootNodeRef); - - int toDo = childAssocRefs.size(); - - if (toDo == 0) - { - if (logger.isDebugEnabled()) - { - logger.debug(I18NUtil.getMessage(MSG_PATCH_NOOP)); - } - migrationComplete = true; - return null; - } - - migrationComplete = false; - - if (logger.isInfoEnabled()) - { - logger.info("Found "+childAssocRefs.size()+" version histories in old version store (in "+((System.currentTimeMillis()-startTime)/1000)+" secs)"); - } - - if (logger.isDebugEnabled()) - { - logger.debug("batchSize="+batchSize+", batchWorkerThreadCount="+threadCount+", deleteImmediately="+deleteImmediately); - } - - long splitTime = System.currentTimeMillis(); - - boolean firstMigration = false; - - if (! isRunningAsJob) - { - List newChildAssocRefs = getVersionHistories(newRootNodeRef); - firstMigration = (newChildAssocRefs.size() == 0); - - if (logger.isInfoEnabled()) - { - if (! firstMigration) - { - logger.warn("This is not the first migration attempt. Found "+newChildAssocRefs.size()+" version histories in new version store (in "+((System.currentTimeMillis()-splitTime)/1000)+" secs)"); - } - } - } - - // note: assumes patch runs before cleanup starts - int toMigrateCount = 0; - int totalCount = 0; - int alreadyMigratedCount = 0; - List> batchProcessorWork = new ArrayList>(2); - - boolean wasMLAware = MLPropertyInterceptor.setMLAware(true); - - try - { - // - // split into batches (ignore version histories that have already been migrated) - // - - splitTime = System.currentTimeMillis(); - - final List tmpBatch = new ArrayList(batchSize); - - int maxToDo = childAssocRefs.size(); - - if (limit > -1) - { - maxToDo = limit; - - if (logger.isInfoEnabled()) - { - logger.info("Limit this job cycle to max of "+limit+" version histories"); - } - } - - for (final ChildAssociationRef childAssocRef : childAssocRefs) - { - // short-cut if first migration - if (!firstMigration) - { - if (isMigrated(childAssocRef)) - { - // skip - already migrated - alreadyMigratedCount++; - continue; - } - } - - toMigrateCount++; - - if (tmpBatch.size() < batchSize) - { - tmpBatch.add(childAssocRef.getChildRef()); - } - - if ((tmpBatch.size() == batchSize) || - (toMigrateCount >= maxToDo) || - (totalCount == childAssocRefs.size())) - { - if (tmpBatch.size() > 0) - { - // Each thread gets 1 batch to execute - batchProcessorWork.add(new ArrayList(tmpBatch)); - tmpBatch.clear(); - } - } - - if (toMigrateCount >= maxToDo) - { - break; - } - } - - return new MigrationWork(toMigrateCount, alreadyMigratedCount, toDo, batchProcessorWork, splitTime, startTime); - } - finally - { - MLPropertyInterceptor.setMLAware(wasMLAware); - } - } - }; - - MigrationWork migrationWork = transactionService.getRetryingTransactionHelper().doInTransaction(buildMigrationWork, false, true); - if(migrationWork == null) - { - return Boolean.TRUE; - } - - List> batchProcessorWork = migrationWork.getBatchProcessorWork(); - int toMigrateCount = migrationWork.getToMigrateCount(); - int toDo = migrationWork.getToDo(); - long splitTime = migrationWork.getSplitTime(); - int alreadyMigratedCount = migrationWork.getAlreadyMigratedCount(); - long startTime = migrationWork.getStartTime(); - - int batchErrorCount = 0; - int batchCount = 0; - - boolean wasMLAware = MLPropertyInterceptor.setMLAware(true); - - try - { - batchCount = batchProcessorWork.size(); - - if (batchCount > 0) - { - if (logger.isDebugEnabled()) - { - logger.debug("Split "+toMigrateCount+" into "+batchCount+" batches in "+(System.currentTimeMillis()-splitTime)+" ms"); - } - - // - // do the work - // - - final String runAsUser = AuthenticationUtil.getRunAsUser(); - - BatchProcessWorkerAdaptor> batchProcessorWorker = new BatchProcessWorkerAdaptor>() - { - public void beforeProcess() throws Throwable - { - // Disable rules - ruleService.disableRules(); - - // Authentication - AuthenticationUtil.setRunAsUser(runAsUser); - } - - public void afterProcess() throws Throwable - { - // Enable rules - ruleService.enableRules(); - // Clear authentication - AuthenticationUtil.clearCurrentSecurityContext(); - } - - public void process(List vhBatch) throws Throwable - { - long startTime = System.currentTimeMillis(); - - refreshLock(lockToken); - - for (NodeRef oldVHNodeRef : vhBatch) - { - migrateVersion(oldVHNodeRef, deleteImmediately); - } - - if (logger.isTraceEnabled()) - { - logger.trace("Migrated batch of "+vhBatch.size()+" version histories in "+(System.currentTimeMillis()-startTime)+ " ms ["+AlfrescoTransactionSupport.getTransactionId()+"]["+Thread.currentThread().getId()+"]"); - } - } - }; - - boolean splitTxns = true; - - if (threadCount > 1) - { - // process first batch only - to avoid retries on qname, acl - - List> batchProcessorWorkFirst = new ArrayList>(2); - batchProcessorWorkFirst.add(new ArrayList(batchProcessorWork.get(0))); - BatchProcessor> batchProcessorFirst = new BatchProcessor>( - MIGRATE_VERSION_STORE, - transactionService.getRetryingTransactionHelper(), - batchProcessorWorkFirst, threadCount, 1, - applicationEventPublisher, logger, loggingInterval); - - batchProcessorFirst.process(batchProcessorWorker, splitTxns); - - batchErrorCount = batchProcessorFirst.getTotalErrors(); - - batchProcessorWork.remove(0); - } - - if (batchProcessorWork.size() > 0) - { - // process remaining batches - BatchProcessor> batchProcessor = new BatchProcessor>( - MIGRATE_VERSION_STORE, - transactionService.getRetryingTransactionHelper(), - batchProcessorWork, threadCount, 1, - applicationEventPublisher, logger, loggingInterval); - - batchProcessor.process(batchProcessorWorker, splitTxns); - - batchErrorCount = batchErrorCount + batchProcessor.getTotalErrors(); - } - } - - if (alreadyMigratedCount > 0) - { - logger.warn(I18NUtil.getMessage(MSG_PATCH_SKIP2, alreadyMigratedCount)); - } - - if (batchCount > 0) - { - if (batchErrorCount > 0) - { - logger.warn(I18NUtil.getMessage(MSG_PATCH_SKIP1, batchErrorCount, batchCount, ((System.currentTimeMillis()-startTime)/1000))); - } - else - { - if ((limit == -1) || ((toMigrateCount+alreadyMigratedCount) == toDo)) - { - logger.info(I18NUtil.getMessage(MSG_PATCH_COMPLETE, toMigrateCount, toDo, ((System.currentTimeMillis()-startTime)/1000), deleteImmediately)); - migrationComplete = true; - } - else - { - logger.info(I18NUtil.getMessage(MSG_PATCH_IN_PROGRESS, toMigrateCount, toDo, ((System.currentTimeMillis()-startTime)/1000), deleteImmediately)); - } - } - } - } - finally - { - MLPropertyInterceptor.setMLAware(wasMLAware); - } - - return migrationComplete; - } - - public void executeCleanup(final int batchSize, final int threadCount) - { - if (! busy) - { - try - { - busy = true; - - CleanupWork work = new CleanupWork(batchSize, threadCount); - work.setLoggingInterval(loggingInterval); - work.setApplicationEventPublisher(applicationEventPublisher); - work.execute(); - } - finally - { - busy = false; - } - } - } - - private class CleanupWork - { - private BatchProcessor> batchProcessor; - private int toDo; - private int threadCount; - private int batchSize; - private int batchErrorCount; - private int batchCount; - private long splitTime; - private int notMigratedCount; - private int loggingInterval; - private Collection> batchProcessorWork; - private ApplicationEventPublisher applicationEventPublisher; - - private long startTime; - - public CleanupWork(final int batchSize, final int threadCount) - { - this.batchSize = batchSize; - this.threadCount = threadCount; - } - - public void setLoggingInterval(int loggingInterval) - { - this.loggingInterval = loggingInterval; - } - - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) - { - this.applicationEventPublisher = applicationEventPublisher; - } - - private void setup() - { - final RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper(); - txHelper.setMaxRetries(1); - txHelper.doInTransaction(new RetryingTransactionCallback() - { - public Object execute() throws Throwable - { - startTime = System.currentTimeMillis(); - - if (logger.isDebugEnabled()) - { - logger.debug("batchSize="+batchSize+", batchWorkerThreadCount="+threadCount); - } - - NodeRef oldRootNodeRef = dbNodeService.getRootNode(VersionMigrator.VERSION_STORE_REF_OLD); - List childAssocRefs = getVersionHistories(oldRootNodeRef); - - toDo = childAssocRefs.size(); - - if (toDo == 0) - { - migrationComplete = true; - } - else - { - if (logger.isInfoEnabled()) - { - logger.info("Found "+toDo+" version histories to delete from old version store (in "+((System.currentTimeMillis()-startTime)/1000)+" secs)"); - } - - // note: assumes cleanup runs after patch has completed - - notMigratedCount = 0; - batchErrorCount = 0; - batchCount = 0; - - boolean wasMLAware = MLPropertyInterceptor.setMLAware(true); - - try - { - // - // split into batches - // - - splitTime = System.currentTimeMillis(); - - int totalCount = 0; - - batchProcessorWork = new ArrayList>(2); - final List tmpBatch = new ArrayList(batchSize); - - for (final ChildAssociationRef childAssocRef : childAssocRefs) - { - totalCount++; - - if (!isMigrated(childAssocRef)) - { - notMigratedCount++; - } - else - { - if (tmpBatch.size() < batchSize) - { - tmpBatch.add(childAssocRef.getChildRef()); - } - - if ((tmpBatch.size() == batchSize) || (totalCount == childAssocRefs.size())) - { - // Each thread gets 1 batch to execute - batchProcessorWork.add(new ArrayList(tmpBatch)); - tmpBatch.clear(); - } - } - } - - batchCount = batchProcessorWork.size(); - } - finally - { - MLPropertyInterceptor.setMLAware(wasMLAware); - } - } - - return null; - } - }, true, true); - } - - private void cleanup() - { - // Note, this is not run in an enclosing transaction. The BatchProcessor will create - // transactions as necessary to perform the work. - - boolean wasMLAware = MLPropertyInterceptor.setMLAware(true); - - try - { - if (batchCount > 0) - { - if (logger.isDebugEnabled()) - { - logger.debug("Split into "+batchCount+" batches in "+(System.currentTimeMillis()-splitTime)+" ms"); - } - - // - // do the work - // - - BatchProcessWorkerAdaptor> batchProcessorWorker = new BatchProcessWorkerAdaptor>() - { - public void process(List vhBatch) throws Throwable - { - long startTime = System.currentTimeMillis(); - - for (NodeRef oldVHNodeRef : vhBatch) - { - // delete old version history node - v1DeleteVersionHistory(oldVHNodeRef); - } - - if (logger.isTraceEnabled()) - { - logger.trace("Deleted batch of "+vhBatch.size()+" migrated version histories in "+(System.currentTimeMillis()-startTime)+ " ms ["+AlfrescoTransactionSupport.getTransactionId()+"]["+Thread.currentThread().getId()+"]"); - } - } - }; - - batchProcessor = new BatchProcessor>( - CLEAN_OLD_VERSION_STORE, - transactionService.getRetryingTransactionHelper(), - batchProcessorWork, threadCount, 1, - applicationEventPublisher, logger, loggingInterval); - - boolean splitTxns = true; - batchProcessor.process(batchProcessorWorker, splitTxns); - batchErrorCount = batchProcessor.getTotalErrors(); - } - } - finally - { - MLPropertyInterceptor.setMLAware(wasMLAware); - } - } - - private void processResults() - { - final RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper(); - txHelper.setMaxRetries(1); - txHelper.doInTransaction(new RetryingTransactionCallback() - { - public Object execute() throws Throwable - { - boolean wasMLAware = MLPropertyInterceptor.setMLAware(true); - - try - { - if (notMigratedCount > 0) - { - logger.warn(I18NUtil.getMessage(MSG_DELETE_SKIP2, notMigratedCount)); - } - - if (batchCount > 0) - { - if (batchErrorCount > 0) - { - logger.warn(I18NUtil.getMessage(MSG_DELETE_SKIP1, batchErrorCount, ((System.currentTimeMillis()-startTime)/1000))); - } - else - { - logger.info(I18NUtil.getMessage(MSG_DELETE_COMPLETE, (toDo - notMigratedCount), toDo, ((System.currentTimeMillis()-startTime)/1000))); - - if (notMigratedCount == 0) - { - migrationComplete = null; - isMigrationComplete(); - } - } - } - } - finally - { - MLPropertyInterceptor.setMLAware(wasMLAware); - } - - return null; - } - }, true, true); - } - - public void execute() - { - setup(); - cleanup(); - processResults(); - } - } - - protected boolean isMigrated(ChildAssociationRef vhChildAssocRef) - { - return (((String)dbNodeService.getProperty(vhChildAssocRef.getChildRef(), ContentModel.PROP_NAME)).startsWith(VersionMigrator.PREFIX_MIGRATED)); - } - - private static class MigrationWork - { - private int toMigrateCount; - private int alreadyMigratedCount; - private int toDo; - private long splitTime; - private long startTime; - private List> batchProcessorWork; - - MigrationWork(int toMigrateCount, int alreadyMigratedCount, - int toDo, List> batchProcessorWork, long splitTime, long startTime) { - super(); - this.toMigrateCount = toMigrateCount; - this.alreadyMigratedCount = alreadyMigratedCount; - this.toDo = toDo; - this.splitTime = splitTime; - this.startTime = startTime; - this.batchProcessorWork = batchProcessorWork; - } - - int getToMigrateCount() { - return toMigrateCount; - } - - int getAlreadyMigratedCount() { - return alreadyMigratedCount; - } - - int getToDo() { - return toDo; - } - - long getSplitTime() { - return splitTime; - } - - long getStartTime() { - return startTime; - } - - List> getBatchProcessorWork() - { - return batchProcessorWork; - } - } -} diff --git a/source/java/org/alfresco/repo/version/VersionServiceImpl.java b/source/java/org/alfresco/repo/version/VersionServiceImpl.java index e98c3ffbf1..bad29dec01 100644 --- a/source/java/org/alfresco/repo/version/VersionServiceImpl.java +++ b/source/java/org/alfresco/repo/version/VersionServiceImpl.java @@ -72,7 +72,8 @@ import org.springframework.extensions.surf.util.ParameterCheck; * * NOTE: deprecated since 3.1 (migrate and use Version2 Service) */ -public class VersionServiceImpl extends AbstractVersionServiceImpl implements VersionService, VersionModel +@SuppressWarnings("deprecation") +public abstract class VersionServiceImpl extends AbstractVersionServiceImpl implements VersionService, VersionModel { private static Log logger = LogFactory.getLog(VersionServiceImpl.class); @@ -182,12 +183,6 @@ public class VersionServiceImpl extends AbstractVersionServiceImpl implements Ve super.initialise(); } - // TODO - temp - protected void initialiseWithoutBind() - { - super.initialise(); - } - /** * Gets the reference to the version store * diff --git a/source/test-java/org/alfresco/repo/version/BaseVersionStoreTest.java b/source/test-java/org/alfresco/repo/version/BaseVersionStoreTest.java index ea4e45aa8a..1532bc8266 100644 --- a/source/test-java/org/alfresco/repo/version/BaseVersionStoreTest.java +++ b/source/test-java/org/alfresco/repo/version/BaseVersionStoreTest.java @@ -73,7 +73,6 @@ public abstract class BaseVersionStoreTest extends BaseSpringTest protected NodeService nodeService; protected PermissionService permissionService; protected CheckOutCheckInService checkOutCheckInService; - protected VersionMigrator versionMigrator; protected SearchService versionSearchService; protected DictionaryService dictionaryService; protected PolicyComponent policyComponent; @@ -174,7 +173,6 @@ public abstract class BaseVersionStoreTest extends BaseSpringTest this.permissionService = (PermissionService)this.applicationContext.getBean("permissionService"); this.checkOutCheckInService = (CheckOutCheckInService) applicationContext.getBean("checkOutCheckInService"); this.versionSearchService = (SearchService)this.applicationContext.getBean("versionSearchService"); - this.versionMigrator = (VersionMigrator)this.applicationContext.getBean("versionMigrator"); this.dictionaryService = (DictionaryService)this.applicationContext.getBean("dictionaryService"); this.policyComponent = (PolicyComponent)this.applicationContext.getBean("policyComponent"); this.policyBehaviourFilter = (BehaviourFilter)this.applicationContext.getBean("policyBehaviourFilter"); diff --git a/source/test-java/org/alfresco/repo/version/VersionMigratorTest.java b/source/test-java/org/alfresco/repo/version/VersionMigratorTest.java deleted file mode 100644 index 49b60e301b..0000000000 --- a/source/test-java/org/alfresco/repo/version/VersionMigratorTest.java +++ /dev/null @@ -1,628 +0,0 @@ -/* - * Copyright (C) 2005-2010 Alfresco Software Limited. - * - * This file is part of Alfresco - * - * Alfresco is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Alfresco 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.version; - -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.node.integrity.IntegrityChecker; -import org.alfresco.repo.policy.PolicyComponent; -import org.alfresco.repo.transaction.RetryingTransactionHelper; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.coci.CheckOutCheckInService; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.AssociationRef; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.version.Version; -import org.alfresco.service.cmr.version.VersionHistory; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.namespace.RegexQNamePattern; -import org.alfresco.test_category.OwnJVMTestsCategory; -import org.alfresco.util.EqualsHelper; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.experimental.categories.Category; - -/** - * Test simple version store migration - */ -@Category(OwnJVMTestsCategory.class) -public class VersionMigratorTest extends BaseVersionStoreTest -{ - private static Log logger = LogFactory.getLog(VersionMigratorTest.class); - - protected VersionServiceImpl version1Service = new VersionServiceImpl(); - - protected Version2ServiceImpl version2Service; - protected NodeService versionNodeService; - - protected VersionMigrator versionMigrator; - protected PolicyComponent policyComponent; - protected DictionaryService dictionaryService; - protected CheckOutCheckInService cociService; - protected IntegrityChecker integrityChecker; - - public VersionMigratorTest() - { - //super.setDefaultRollback(false); // default is true - } - - protected void onSetUpInTransaction() throws Exception - { - super.onSetUpInTransaction(); - - this.versionMigrator = (VersionMigrator)applicationContext.getBean("versionMigrator"); - this.policyComponent = (PolicyComponent)applicationContext.getBean("policyComponent"); - this.dictionaryService = (DictionaryService)applicationContext.getBean("dictionaryService"); - this.version2Service = (Version2ServiceImpl)applicationContext.getBean("versionService"); - this.versionNodeService = (NodeService)applicationContext.getBean("versionNodeService"); // note: auto-switches between V1 and V2 - - this.cociService = (CheckOutCheckInService)applicationContext.getBean("CheckoutCheckinService"); - this.integrityChecker = (IntegrityChecker)applicationContext.getBean("integrityChecker"); - - // Version1Service is used to create the version nodes in Version1Store (workspace://lightWeightVersionStore) - version1Service.setDbNodeService(dbNodeService); - version1Service.setNodeService(dbNodeService); - version1Service.setPolicyComponent(policyComponent); - version1Service.setDictionaryService(dictionaryService); - version1Service.initialiseWithoutBind(); // TODO - temp - if use intialise, get: "More than one CalculateVersionLabelPolicy behaviour has been registered for the type {http://www.alfresco.org/model/content/1.0}content" - - super.setVersionService(version1Service); - } - - /** - * Test migration of a simple versioned node (one version, no children) - */ - public void testMigrateOneVersion() throws Exception - { - if (version2Service.useDeprecatedV1 == true) - { - logger.info("testMigrateOneVersion: skip"); - return; - } - - NodeRef versionableNode = createNewVersionableNode(); - - logger.info("testMigrateOneVersion: versionedNodeRef = " + versionableNode); - - // Get the next version label - String nextVersionLabel = peekNextVersionLabel(versionableNode, versionProperties); - - // Snap-shot the node created date-time - Date beforeVersionDate = (Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED); - long beforeVersionTime = beforeVersionDate.getTime(); - logger.info("beforeVersion Date/Time: " + beforeVersionDate + " [" + beforeVersionTime + "]"); - - Version oldVersion = createVersion(versionableNode); - - // get and store old version details for later comparison - versionNodeService will retrieve these from the old version store - - QName oldVersionType = versionNodeService.getType(oldVersion.getFrozenStateNodeRef()); - Set oldVersionAspects = versionNodeService.getAspects(oldVersion.getFrozenStateNodeRef()); - Map oldVersionProps = versionNodeService.getProperties(oldVersion.getFrozenStateNodeRef()); - - logger.info("oldVersion props: " + oldVersion); - logger.info("oldVersion created: " + oldVersion.getFrozenModifiedDate() + " [" + oldVersion.getFrozenModifiedDate().getTime()+"]"); - - logger.info("oldVersion props via versionNodeService: " + oldVersionProps); - - VersionHistory vh = version1Service.getVersionHistory(versionableNode); - assertEquals(1, vh.getAllVersions().size()); - - NodeRef oldVHNodeRef = version1Service.getVersionHistoryNodeRef(versionableNode); - - Thread.sleep(70000); - - // Migrate and delete old version history ! - NodeRef versionedNodeRef = versionMigrator.v1GetVersionedNodeRef(oldVHNodeRef); - NodeRef newVHNodeRef = versionMigrator.migrateVersionHistory(oldVHNodeRef, versionedNodeRef); - versionMigrator.v1DeleteVersionHistory(oldVHNodeRef); - - VersionHistory vh2 = version2Service.getVersionHistory(versionableNode); - assertEquals(1, vh2.getAllVersions().size()); - - Version newVersion = vh2.getRootVersion(); - - logger.info("newVersion props: " + newVersion); - logger.info("newVersion created: " + newVersion.getFrozenModifiedDate() + " [" + newVersion.getFrozenModifiedDate().getTime()+"]"); - - // check new version - switch to new version service to do the check - super.setVersionService(version2Service); - checkNewVersion(beforeVersionTime, nextVersionLabel, newVersion, versionableNode); - - // get and compare new version details - - versionNodeService will retrieve these from the new version store - - QName newVersionType = versionNodeService.getType(newVersion.getFrozenStateNodeRef()); - Set newVersionAspects = versionNodeService.getAspects(newVersion.getFrozenStateNodeRef()); - Map newVersionProps = versionNodeService.getProperties(newVersion.getFrozenStateNodeRef()); - - logger.info("newVersion props via versionNodeService: " + newVersionProps); - - assertEquals(oldVersionType, newVersionType); - - assertEquals(oldVersionAspects.size(), newVersionAspects.size()); - for (QName key : oldVersionAspects) - { - assertTrue(""+key, newVersionAspects.contains(key)); - } - - // note: since 3.4, "cm:accessed" is not returned/migrated if null - int expectedPropCount = oldVersionProps.size(); - - if (oldVersionProps.get(ContentModel.PROP_ACCESSED) == null) - { - expectedPropCount--; - } - - assertEquals(expectedPropCount, newVersionProps.size()); - for (QName key : oldVersionProps.keySet()) - { - if (! (key.equals(ContentModel.PROP_ACCESSED) && (oldVersionProps.get(key) == null))) - { - assertEquals(""+key, oldVersionProps.get(key), newVersionProps.get(key)); - } - } - - // ALFCOM-2658 - assertEquals(oldVersion.getFrozenStateNodeRef().getId(), newVersion.getFrozenStateNodeRef().getId()); - - logger.info("testMigrateOneVersion: Migrated from oldVHNodeRef = " + oldVHNodeRef + " to newVHNodeRef = " + newVHNodeRef); - } - - /** - * Test migration of a multiple versioned nodes - */ - public void testMigrateMultipleVersions() throws Exception - { - if (version2Service.useDeprecatedV1 == true) - { - logger.info("testMigrateOneVersion: skip"); - return; - } - - NodeRef versionableNode = createNewVersionableNode(); - - // Get the next version label and snapshot the date-time - String nextVersionLabel1 = peekNextVersionLabel(versionableNode, versionProperties); - - // Snap-shot the node created date-time - long beforeVersionTime1 = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime(); - - Version version1 = createVersion(versionableNode); - logger.info(version1); - - // Get the next version label and snapshot the date-time - String nextVersionLabel2 = peekNextVersionLabel(versionableNode, versionProperties); - - // Snap-shot the node created date-time - long beforeVersionTime2 = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime(); - - Version version2 = createVersion(versionableNode); - logger.info(version2); - - // Get the next version label and snapshot the date-time - String nextVersionLabel3 = peekNextVersionLabel(versionableNode, versionProperties); - - // Snap-shot the node created date-time - long beforeVersionTime3 = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime(); - - Version version3 = createVersion(versionableNode); - logger.info(version3); - - VersionHistory vh1 = version1Service.getVersionHistory(versionableNode); - assertEquals(3, vh1.getAllVersions().size()); - - logger.info("testMigrateMultipleVersions: versionedNodeRef = " + versionableNode); - - NodeRef oldVHNodeRef = version1Service.getVersionHistoryNodeRef(versionableNode); - - // Migrate and delete old version history ! - NodeRef versionedNodeRef = versionMigrator.v1GetVersionedNodeRef(oldVHNodeRef); - NodeRef newVHNodeRef = versionMigrator.migrateVersionHistory(oldVHNodeRef, versionedNodeRef); - versionMigrator.v1DeleteVersionHistory(oldVHNodeRef); - - VersionHistory vh2 = version2Service.getVersionHistory(versionableNode); - assertEquals(3, vh2.getAllVersions().size()); - - // TODO move check version history into BaseVersionStoreTest - // check new versions - switch to new version service to do the check - super.setVersionService(version2Service); - - Version[] newVersions = vh2.getAllVersions().toArray(new Version[]{}); - - checkVersion(beforeVersionTime1, nextVersionLabel1, newVersions[2], versionableNode); - checkVersion(beforeVersionTime2, nextVersionLabel2, newVersions[1], versionableNode); - checkNewVersion(beforeVersionTime3, nextVersionLabel3, newVersions[0], versionableNode); - - // ALFCOM-2658 - assertEquals(version1.getFrozenStateNodeRef().getId(), newVersions[2].getFrozenStateNodeRef().getId()); - assertEquals(version2.getFrozenStateNodeRef().getId(), newVersions[1].getFrozenStateNodeRef().getId()); - assertEquals(version3.getFrozenStateNodeRef().getId(), newVersions[0].getFrozenStateNodeRef().getId()); - - logger.info("testMigrateMultipleVersions: Migrated from oldVHNodeRef = " + oldVHNodeRef + " to newVHNodeRef = " + newVHNodeRef); - } - - public void testMigrateMultipleNodesSuccessful() throws Exception - { - testMigrateMultipleNodes(false); - } - - public void test_ETHREEOH_2091() throws Exception - { - // test partial migration (with skipped nodes) - testMigrateMultipleNodes(true); - } - - /** - * Test migration of a multiple nodes (each with one version) - */ - private void testMigrateMultipleNodes(final boolean withSkip) - { - if (version2Service.useDeprecatedV1 == true) - { - logger.info("testMigrateOneVersion: skip"); - return; - } - - final int nodeCount = 5; - assert(nodeCount > 3); - - final NodeRef[] versionableNodes = new NodeRef[nodeCount]; - - setComplete(); - endTransaction(); - - RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper(); - - for (int i = 0; i < nodeCount; i++) - { - final int idx = i; - - txHelper.doInTransaction(new RetryingTransactionCallback() - { - public NodeRef execute() throws Throwable - { - NodeRef versionableNode = null; - if ((idx % 2) == 0) - { - versionableNode = createNewVersionableNode(); - } - else - { - versionableNode = createNewVersionableContentNode(true); - } - createVersion(versionableNode); - versionableNodes[idx] = versionableNode; - - return null; - } - }); - } - - setComplete(); - endTransaction(); - - txHelper.doInTransaction(new RetryingTransactionCallback() - { - public NodeRef execute() throws Throwable - { - // check old version histories - for (int i = 0; i< nodeCount; i++) - { - VersionHistory vh1 = version1Service.getVersionHistory(versionableNodes[i]); - assertNotNull(vh1); - assertEquals(1, vh1.getAllVersions().size()); - } - - return null; - } - }); - - setComplete(); - endTransaction(); - - if (withSkip) - { - // remove test model - those nodes should fail - currently all - add separate create ... - - // TODO ... - dictionaryDAO.removeModel(QName.createQName("http://www.alfresco.org/test/versionstorebasetest/1.0", "versionstorebasetestmodel")); - } - - txHelper = transactionService.getRetryingTransactionHelper(); - - txHelper.doInTransaction(new RetryingTransactionCallback() - { - public NodeRef execute() throws Throwable - { - // Migrate (and don't delete old version history) ! - versionMigrator.migrateVersions(1, 1, -1, false, null, false); - - return null; - } - }); - - setComplete(); - endTransaction(); - - txHelper.doInTransaction(new RetryingTransactionCallback() - { - public NodeRef execute() throws Throwable - { - // check new version histories - for (int i = 0; i < nodeCount; i++) - { - VersionHistory vh2 = version2Service.getVersionHistory(versionableNodes[i]); - - if (withSkip && ((i % 2) == 0)) - { - assertNull(vh2); - } - else - { - assertNotNull(vh2); - assertEquals(1, vh2.getAllVersions().size()); - } - } - - return null; - } - }); - } - - private NodeRef createNewVersionableContentNode(boolean versionable) - { - // Use this map to retrieve the versionable nodes in later tests - this.versionableNodes = new HashMap(); - - // Create node (this node has some content) - NodeRef nodeRef = this.dbNodeService.createNode( - rootNodeRef, - ContentModel.ASSOC_CHILDREN, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myNode"), - ContentModel.TYPE_CONTENT, - this.nodeProperties).getChildRef(); - - if (versionable) - { - this.dbNodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, new HashMap()); - } - - assertNotNull(nodeRef); - this.versionableNodes.put(nodeRef.getId(), nodeRef); - - // Add the content to the node - ContentWriter contentWriter = this.contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); - contentWriter.putContent(TEST_CONTENT); - - // Set author - Map authorProps = new HashMap(1, 1.0f); - authorProps.put(ContentModel.PROP_AUTHOR, "Charles Dickens"); - this.dbNodeService.addAspect(nodeRef, ContentModel.ASPECT_AUTHOR, authorProps); - - return nodeRef; - } - - public void test_ETHREEOH_1540() throws Exception - { - // Create the node used for tests - NodeRef nodeRef = nodeService.createNode( - rootNodeRef, - ContentModel.ASSOC_CHILDREN, - QName.createQName(TEST_NAMESPACE, "MyVersionableNode"), - TEST_TYPE_QNAME, - this.nodeProperties).getChildRef(); - - nodeService.addAspect(nodeRef, ContentModel.ASPECT_TITLED, null); - nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, "name"); - - // Add the initial content to the node - ContentWriter contentWriter = this.contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); - contentWriter.setMimetype("text/plain"); - contentWriter.setEncoding("UTF-8"); - contentWriter.putContent("my content"); - - VersionHistory vh1 = version1Service.getVersionHistory(nodeRef); - assertNull(vh1); - - version2Service.useDeprecatedV1 = true; - - // Add the version aspect to the created node - nodeService.addAspect(nodeRef, ContentModel.ASPECT_VERSIONABLE, null); - - vh1 = version1Service.getVersionHistory(nodeRef); - assertNull(vh1); - - NodeRef workingCopyNodeRef = cociService.checkout(nodeRef); - - vh1 = version1Service.getVersionHistory(nodeRef); - assertNull(vh1); - - int v1count = 3; - - for (int i = 1; i <= v1count; i++) - { - Map versionProperties = new HashMap(); - versionProperties.put(Version.PROP_DESCRIPTION, "This is a test checkin - " + i); - - cociService.checkin(workingCopyNodeRef, versionProperties); - - vh1 = version1Service.getVersionHistory(nodeRef); - assertEquals(i, vh1.getAllVersions().size()); - - workingCopyNodeRef = cociService.checkout(nodeRef); - - vh1 = version1Service.getVersionHistory(nodeRef); - assertEquals(i, vh1.getAllVersions().size()); - } - - NodeRef oldVHNodeRef = version1Service.getVersionHistoryNodeRef(nodeRef); - - version2Service.useDeprecatedV1 = false; - - // Migrate and delete old version history ! - NodeRef versionedNodeRef = versionMigrator.v1GetVersionedNodeRef(oldVHNodeRef); - - //int nextVersionNumber = versionCounterService.nextVersionNumber(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, VersionModel.STORE_ID)); - //versionCounterService.setVersionNumber(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, Version2Model.STORE_ID), nextVersionNumber); - - // to force the error: https://issues.alfresco.com/jira/browse/ETHREEOH-1540 - //versionCounterService.setVersionNumber(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, Version2Model.STORE_ID), 0); - - NodeRef newVHNodeRef = versionMigrator.migrateVersionHistory(oldVHNodeRef, versionedNodeRef); - versionMigrator.v1DeleteVersionHistory(oldVHNodeRef); - - VersionHistory vh2 = version2Service.getVersionHistory(nodeRef); - assertEquals(v1count, vh2.getAllVersions().size()); - - int v2count = 3; - - for (int i = 1; i <= v2count; i++) - { - versionProperties = new HashMap(); - versionProperties.put(Version.PROP_DESCRIPTION, "This is a test checkin - " + (v1count + i)); - - cociService.checkin(workingCopyNodeRef, versionProperties); - - vh2 = version2Service.getVersionHistory(nodeRef); - assertEquals((v1count + i), vh2.getAllVersions().size()); - - workingCopyNodeRef = cociService.checkout(nodeRef); - - vh2 = version2Service.getVersionHistory(nodeRef); - assertEquals((v1count + i), vh2.getAllVersions().size()); - } - - logger.info("testMigrateOneCheckoutVersion: Migrated from oldVHNodeRef = " + oldVHNodeRef + " to newVHNodeRef = " + newVHNodeRef); - } - - /** - * Test migration of a single versioned node with versioned child assocs & peer assocs - * - * @since 3.3 Ent - applies only to direct upgrade from 2.x to 3.3 Ent or higher - */ - public void testMigrateVersionWithAssocs() throws Exception - { - if (version2Service.useDeprecatedV1 == true) - { - logger.info("testMigrateVersionWithAssocs: skip"); - return; - } - - NodeRef versionableNode = createNewVersionableNode(); - NodeRef targetNode = createNewNode(); - - nodeService.createAssociation(versionableNode, targetNode, TEST_ASSOC); - - // Get the next version label and snapshot the date-time - String nextVersionLabel1 = peekNextVersionLabel(versionableNode, versionProperties); - - // Snap-shot the node created date-time - long beforeVersionTime1 = ((Date)nodeService.getProperty(versionableNode, ContentModel.PROP_CREATED)).getTime(); - - Version version1 = createVersion(versionableNode); - logger.info(version1); - - VersionHistory vh1 = version1Service.getVersionHistory(versionableNode); - assertEquals(1, vh1.getAllVersions().size()); - - List oldChildAssocs = nodeService.getChildAssocs(version1.getFrozenStateNodeRef()); - List oldAssocs = nodeService.getTargetAssocs(version1.getFrozenStateNodeRef(), RegexQNamePattern.MATCH_ALL); - - logger.info("testMigrateVersionWithAssocs: versionedNodeRef = " + versionableNode); - - NodeRef oldVHNodeRef = version1Service.getVersionHistoryNodeRef(versionableNode); - - // Migrate and delete old version history ! - NodeRef versionedNodeRef = versionMigrator.v1GetVersionedNodeRef(oldVHNodeRef); - NodeRef newVHNodeRef = versionMigrator.migrateVersionHistory(oldVHNodeRef, versionedNodeRef); - versionMigrator.v1DeleteVersionHistory(oldVHNodeRef); - - VersionHistory vh2 = version2Service.getVersionHistory(versionableNode); - assertEquals(1, vh2.getAllVersions().size()); - - // check new version - switch to new version service to do the check - super.setVersionService(version2Service); - - Version[] newVersions = vh2.getAllVersions().toArray(new Version[]{}); - - Version newVersion1 = newVersions[0]; - - checkVersion(beforeVersionTime1, nextVersionLabel1, newVersion1, versionableNode); - - List newChildAssocs = nodeService.getChildAssocs(newVersion1.getFrozenStateNodeRef()); - assertEquals(oldChildAssocs.size(), newChildAssocs.size()); - for (ChildAssociationRef oldChildAssoc : oldChildAssocs) - { - boolean found = false; - for (ChildAssociationRef newChildAssoc : newChildAssocs) - { - if (newChildAssoc.getParentRef().getId().equals(oldChildAssoc.getParentRef().getId()) && - newChildAssoc.getChildRef().equals(oldChildAssoc.getChildRef()) && - newChildAssoc.getTypeQName().equals(oldChildAssoc.getTypeQName()) && - newChildAssoc.getQName().equals(oldChildAssoc.getQName()) && - (newChildAssoc.isPrimary() == oldChildAssoc.isPrimary()) && - (newChildAssoc.getNthSibling() == oldChildAssoc.getNthSibling())) - { - found = true; - break; - } - } - - if (! found) - { - fail(oldChildAssoc.toString()+ " not found"); - } - } - - List newAssocs = nodeService.getTargetAssocs(newVersion1.getFrozenStateNodeRef(), RegexQNamePattern.MATCH_ALL); - assertEquals(oldAssocs.size(), newAssocs.size()); - for (AssociationRef oldAssoc : oldAssocs) - { - boolean found = false; - for (AssociationRef newAssoc : newAssocs) - { - if (newAssoc.getSourceRef().getId().equals(oldAssoc.getSourceRef().getId()) && - newAssoc.getTargetRef().equals(oldAssoc.getTargetRef()) && - newAssoc.getTypeQName().equals(oldAssoc.getTypeQName()) && - EqualsHelper.nullSafeEquals(newAssoc.getId(), oldAssoc.getId())) - { - found = true; - break; - } - } - - if (! found) - { - fail(oldAssoc.toString()+ " not found"); - } - } - - logger.info("testMigrateVersionWithAssocs: Migrated from oldVHNodeRef = " + oldVHNodeRef + " to newVHNodeRef = " + newVHNodeRef); - } -} diff --git a/source/test-java/org/alfresco/repo/version/VersionServiceImplTest.java b/source/test-java/org/alfresco/repo/version/VersionServiceImplTest.java index ccc7edf8d4..433667cd5f 100644 --- a/source/test-java/org/alfresco/repo/version/VersionServiceImplTest.java +++ b/source/test-java/org/alfresco/repo/version/VersionServiceImplTest.java @@ -426,8 +426,6 @@ public class VersionServiceImplTest extends BaseVersionStoreTest versionService.setPolicyComponent(policyComponent); versionService.setPolicyBehaviourFilter(policyBehaviourFilter); versionService.setPermissionService(permissionService); - versionService.setOnlyUseDeprecatedV1(false); - versionService.setVersionMigrator(versionMigrator); versionService.setVersionComparatorClass(versionComparatorClass); versionService.initialise(); setVersionService(versionService); @@ -2471,10 +2469,6 @@ public class VersionServiceImplTest extends BaseVersionStoreTest authenticationComponent.setSystemUserAsCurrentUser(); - // TEMP - for migration testing - force V1 store (override repository property) - final Version2ServiceImpl version2ServiceImpl = (Version2ServiceImpl)ctx.getBean("versionService"); - version2ServiceImpl.setOnlyUseDeprecatedV1(true); - System.out.println("Using: " + versionService.getVersionStoreReference()); // Create a new store diff --git a/source/test-java/org/alfresco/repo/version/VersionTestSuite.java b/source/test-java/org/alfresco/repo/version/VersionTestSuite.java index b579c93cfc..286e4929da 100644 --- a/source/test-java/org/alfresco/repo/version/VersionTestSuite.java +++ b/source/test-java/org/alfresco/repo/version/VersionTestSuite.java @@ -60,7 +60,6 @@ public class VersionTestSuite extends TestSuite suite.addTestSuite(VersionServiceImplTest.class); suite.addTestSuite(NodeServiceImplTest.class); suite.addTestSuite(ContentServiceImplTest.class); - suite.addTestSuite(VersionMigratorTest.class); return suite; } }