Merged DEV to HEAD (5.0)

87804: ACE-2030: Retire jbpm-upgrade.sql including patches using it
    The from-to schema values match those of the 'patch.db-V3.2-Upgrade-JBPM' bean and they both referenced the
    same SQL file.  Therefore, it was simply a duplicate with the V3.2 bean being the one doing the actual work.
    This bean is therefore joining the V3.2 version in retirement.  The 'targetSchema' is for information purposes
    only and has been changed from 6001 to 2018, which is what it actually did.
  87805: ACE-2030: Remove more patches introduced for upgrade to V3.2
  87806: ACE-2030: Remove more patches introduced for upgrade to V3.3.x
  87807: Move patch.migrateAttrDropOldTables out of the danger zone (ACE-2030) before continuing clean up.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@87812 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2014-10-11 20:57:42 +00:00
parent 1217371e37
commit 958b298f4a
33 changed files with 131 additions and 3330 deletions

View File

@@ -44,15 +44,3 @@ CREATE TABLE alf_audit_entry
CONSTRAINT fk_alf_aud_ent_pro FOREIGN KEY (audit_values_id) REFERENCES alf_prop_root (id),
PRIMARY KEY (id)
) ENGINE=InnoDB;
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-AuditTables';
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.2-AuditTables', 'Manually executed script upgrade V3.2: Audit Tables',
0, 3001, -1, 3002, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -56,15 +56,3 @@ CREATE TABLE alf_content_data
CONSTRAINT fk_alf_cont_loc FOREIGN KEY (content_locale_id) REFERENCES alf_locale (id),
PRIMARY KEY (id)
) ENGINE=InnoDB;
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-ContentTables';
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.2-ContentTables', 'Manually executed script upgrade V3.2: Content Tables',
0, 2011, -1, 2012, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -32,15 +32,3 @@ CREATE TABLE alf_lock
PRIMARY KEY (id),
UNIQUE INDEX idx_alf_lock_key (shared_resource_id, excl_resource_id)
) ENGINE=InnoDB;
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-LockTables';
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.2-LockTables', 'Manually executed script upgrade V3.2: Lock Tables',
0, 2010, -1, 2011, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -108,15 +108,3 @@ CREATE TABLE alf_prop_unique_ctx
CONSTRAINT fk_alf_propuctx_p1 FOREIGN KEY (prop1_id) REFERENCES alf_prop_root (id),
PRIMARY KEY (id)
) ENGINE=InnoDB;
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-PropertyValueTables';
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.2-PropertyValueTables', 'Manually executed script upgrade V3.2: PropertyValue Tables',
0, 3000, -1, 3001, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -52,15 +52,3 @@ CREATE INDEX idx_alf_aud_ent_tm ON alf_audit_entry(audit_time);
CREATE INDEX fk_alf_aud_ent_app ON alf_audit_entry(audit_app_id);
CREATE INDEX fk_alf_aud_ent_use ON alf_audit_entry(audit_user_id);
CREATE INDEX fk_alf_aud_ent_pro ON alf_audit_entry(audit_values_id);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-AuditTables';
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.2-AuditTables', 'Manually executed script upgrade V3.2: Audit Tables',
0, 3001, -1, 3002, null, 'UNKOWN', TRUE, TRUE, 'Script completed'
);

View File

@@ -64,15 +64,3 @@ CREATE INDEX fk_alf_cont_url ON alf_content_data (content_url_id);
CREATE INDEX fk_alf_cont_mim ON alf_content_data (content_mimetype_id);
CREATE INDEX fk_alf_cont_enc ON alf_content_data (content_encoding_id);
CREATE INDEX fk_alf_cont_loc ON alf_content_data (content_locale_id);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-ContentTables';
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.2-ContentTables', 'Manually executed script upgrade V3.2: Content Tables',
0, 2011, -1, 2012, null, 'UNKOWN', TRUE, TRUE, 'Script completed'
);

View File

@@ -35,15 +35,3 @@ CREATE TABLE alf_lock
);
CREATE UNIQUE INDEX idx_alf_lock_key ON alf_lock (shared_resource_id, excl_resource_id);
CREATE INDEX fk_alf_lock_excl ON alf_lock (excl_resource_id);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-LockTables';
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.2-LockTables', 'Manually executed script upgrade V3.2: Lock Tables',
0, 2010, -1, 2011, null, 'UNKOWN', TRUE, TRUE, 'Script completed'
);

View File

@@ -120,15 +120,3 @@ CREATE UNIQUE INDEX idx_alf_propuctx ON alf_prop_unique_ctx(value1_prop_id, valu
CREATE INDEX fk_alf_propuctx_v2 ON alf_prop_unique_ctx(value2_prop_id);
CREATE INDEX fk_alf_propuctx_v3 ON alf_prop_unique_ctx(value3_prop_id);
CREATE INDEX fk_alf_propuctx_p1 ON alf_prop_unique_ctx(prop1_id);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-PropertyValueTables';
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.2-PropertyValueTables', 'Manually executed script upgrade V3.2: PropertyValue Tables',
0, 3000, -1, 3001, null, 'UNKOWN', TRUE, TRUE, 'Script completed'
);

View File

@@ -41,23 +41,11 @@
<property name="schemaBootstrap" ref="schemaBootstrap" />
<property name="preUpdateScriptPatches">
<list>
<ref bean="patch.db-V3.2-LockTables" />
<ref bean="patch.db-V3.2-ContentTables" />
<ref bean="patch.db-V3.2-ContentTables2" />
<ref bean="patch.db-V3.2-PropertyValueTables" />
<ref bean="patch.db-V3.2-AuditTables" />
<ref bean="patch.db-V3.2-Child-Assoc-QName-CRC" />
<ref bean="patch.db-V3.3-modify-index-permission_id" />
<ref bean="patch.db-V3.2-AddFKIndexes" />
<ref bean="patch.db-V3.2-AddFKIndexes-2" />
<ref bean="patch.db-V4.1-update-activiti-nullable-columns" />
</list>
</property>
<property name="postUpdateScriptPatches">
<list>
<ref bean="patch.db-V3.3-Remove-VersionCount" />
<ref bean="patch.db-V3.3-Fix-Repo-Seqs" />
<ref bean="patch.db-V3.3-Node-Prop-Serializable" />
<ref bean="patch.db-V3.4-property-unique-ctx-value" />
<ref bean="patch.db-V3.4-property-unique-ctx-idx" />
<ref bean="patch.db-V3.4-authority-unique-idx" />
@@ -112,7 +100,6 @@
<list>
<ref bean="patch.db-V3.3-JBPM-Extra" />
<ref bean="patch.db-V3.4-JBPM-FK-indexes" />
<ref bean="patch.db-V3.4-Upgrade-JBPM" />
<ref bean="patch.db-V3.4-alter-jBPM331-CLOB-columns-to-nvarchar" />
<ref bean="patch.db-V3.4-JBPM-varinst-indexes" />
<ref bean="patch.db-V3.4-remove-redundant-jbpm-indexes" />

View File

@@ -1,63 +0,0 @@
--
-- Title: Upgrade to V3.2 - Add extra FK indexes
-- Database: Generic
-- Since: V3.2 schema 3503
-- Author: Derek Hulley
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- ALF-5396: Missing FK indexes on non-MySQL databases
-- All statements are made optional to cater for varying introductions of tables
-- using create scripts that have been fixed up.
-- ==========
-- V3.2 diffs
-- ==========
-- alf_audit_* tables
CREATE INDEX fk_alf_aud_mod_cd ON alf_audit_model(content_data_id); -- (optional)
CREATE INDEX fk_alf_aud_app_mod ON alf_audit_app(audit_model_id); -- (optional)
CREATE INDEX fk_alf_aud_app_dis ON alf_audit_app(disabled_paths_id); -- (optional)
CREATE INDEX fk_alf_aud_ent_app ON alf_audit_entry(audit_app_id); -- (optional)
CREATE INDEX fk_alf_aud_ent_use ON alf_audit_entry(audit_user_id); -- (optional)
CREATE INDEX fk_alf_aud_ent_pro ON alf_audit_entry(audit_values_id); -- (optional)
-- Only missing on Oracle
ALTER TABLE avm_stores
ADD CONSTRAINT fk_avm_s_acl
FOREIGN KEY (acl_id)
REFERENCES alf_access_control_list (id); -- (optional)
CREATE INDEX fk_avm_s_acl ON avm_stores (acl_id); -- (optional)
-- alf_content_* tables
CREATE INDEX fk_alf_cont_url ON alf_content_data (content_url_id); -- (optional)
CREATE INDEX fk_alf_cont_mim ON alf_content_data (content_mimetype_id); -- (optional)
CREATE INDEX fk_alf_cont_enc ON alf_content_data (content_encoding_id); -- (optional)
CREATE INDEX fk_alf_cont_loc ON alf_content_data (content_locale_id); -- (optional)
-- alf_lock_* tables
CREATE INDEX fk_alf_lock_excl ON alf_lock (excl_resource_id); -- (optional)
-- alf_prop_* tables
CREATE INDEX fk_alf_propln_key ON alf_prop_link(key_prop_id); -- (optional)
CREATE INDEX fk_alf_propln_val ON alf_prop_link(value_prop_id); -- (optional)
CREATE INDEX fk_alf_propuctx_v2 ON alf_prop_unique_ctx(value2_prop_id); -- (optional)
CREATE INDEX fk_alf_propuctx_v3 ON alf_prop_unique_ctx(value3_prop_id); -- (optional)
-- ==========
-- V3.4 diffs
-- ==========
CREATE INDEX fk_alf_propuctx_p1 ON alf_prop_unique_ctx(prop1_id); -- (optional)
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-AddFKIndexes-2';
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.2-AddFKIndexes-2', 'Script fix for ALF-5396: Missing FK indexes on non-MySQL databases',
0, 4111, -1, 4112, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,23 +0,0 @@
--
-- Title: Upgrade to V3.2 - Add extra FK indexes
-- Database: MySQL
-- Since: V3.2 schema 3503
-- Author: Derek Hulley
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- ALF-5396: Missing FK indexes on non-MySQL databases
-- Not relevant to MySQL
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-AddFKIndexes-2';
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.2-AddFKIndexes-2', 'Script fix for ALF-5396: Missing FK indexes on non-MySQL databases',
0, 4111, -1, 4112, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,38 +0,0 @@
--
-- Title: Update Content tables (pre 3.2 Enterprise Final)
-- Database: MySQL InnoDB
-- Since: V3.2 Schema 3009
-- Author: Derek Hulley
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- This update is required for installations that have run any of the early 3.2
-- codelines i.e. anything installed or upgraded to pre-3.2 Enterprise Final.
-- This is to (a) fix the naming convention and (b) to ensure that the index is UNIQUE
DROP INDEX idx_alf_cont_url_crc ON alf_content_url; --(optional)
DROP INDEX idx_alf_conturl_cr ON alf_content_url; --(optional)
CREATE UNIQUE INDEX idx_alf_conturl_cr ON alf_content_url (content_url_short, content_url_crc);
-- If this statement fails, it will be because the table already contains
-- the orphan column and index
ALTER TABLE alf_content_url
DROP COLUMN version,
ADD COLUMN orphan_time BIGINT NULL AFTER content_size,
ADD INDEX idx_alf_conturl_ot (orphan_time)
; --(optional)
-- This table will not exist for upgrades from pre 3.2 to 3.2 Enterprise Final
DROP TABLE alf_content_clean; --(optional)
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-ContentTables2';
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.2-ContentTables2', 'Manually executed script upgrade V3.2: Content Tables 2 (pre 3.2 Enterprise Final)',
0, 3008, -1, 3009, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,44 +0,0 @@
--
-- Title: Upgrade to V3.2 - Add qname_crc column to alf_child_assoc
-- Database: MySQL
-- Since: V3.2 schema 3006
-- Author: davew
--
-- Add qname_crc column to alf_child_assoc and change indexes
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
ALTER TABLE alf_child_assoc
ADD COLUMN qname_crc BIGINT NOT NULL DEFAULT 0 AFTER qname_localname
;
-- Enable additional patches to run by CRC-ing the descriptor nodes
UPDATE alf_child_assoc
SET qname_crc = 147310537
WHERE qname_ns_id = (SELECT id FROM alf_namespace WHERE uri = 'http://www.alfresco.org/model/system/1.0')
AND qname_localname = 'descriptor';
UPDATE alf_child_assoc
SET qname_crc = 369154895
WHERE qname_ns_id = (SELECT id FROM alf_namespace WHERE uri = 'http://www.alfresco.org/model/system/1.0')
AND qname_localname = 'descriptor-current';
ALTER TABLE alf_child_assoc
DROP INDEX idx_alf_cass_qnln,
ALTER COLUMN qname_crc DROP DEFAULT
;
CREATE INDEX idx_alf_cass_qncrc ON alf_child_assoc (qname_crc, type_qname_id, parent_node_id);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-Child-Assoc-QName-CRC';
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.2-Child-Assoc-QName-CRC', 'Manually executed script upgrade V3.2 to Add qname_crc column to alf_child_assoc and change indexes',
0, 3005, -1, 3006, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,25 +0,0 @@
--
-- Title: Upgrade to V3.2 - upgrade jbpm tables to jbpm 3.3.1
-- Database: MySql
-- Since: V3.2 schema 2013
-- Author:
--
-- upgrade jbpm tables to jbpm 3.3.1
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- we mark next statement as optional to not fail the upgrade from 2.1.a (as it doesn't contain jbpm)
alter table JBPM_MODULEDEFINITION modify NAME_ varchar(255); -- (optional)
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-Upgrade-JBPM';
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.2-Upgrade-JBPM', 'Manually executed script upgrade V3.2 to jbpm version 3.3.1 usage',
0, 2017, -1, 2018, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,38 +0,0 @@
--
-- Title: Update Content tables (pre 3.2 Enterprise Final)
-- Database: PostgreSQLDialect
-- Since: V3.2 Schema 3009
-- Author: Derek Hulley
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- This update is required for installations that have run any of the early 3.2
-- codelines i.e. anything installed or upgraded to pre-3.2 Enterprise Final.
-- This is to (a) fix the naming convention and (b) to ensure that the index is UNIQUE
DROP INDEX idx_alf_cont_url_crc; --(optional)
DROP INDEX idx_alf_conturl_cr; --(optional)
CREATE UNIQUE INDEX idx_alf_conturl_cr ON alf_content_url (content_url_short, content_url_crc);
-- If this statement fails, it will be because the table already contains the orphan column
ALTER TABLE alf_content_url
DROP COLUMN version,
ADD COLUMN orphan_time INT8 NULL
; --(optional)
CREATE INDEX idx_alf_conturl_ot ON alf_content_url (orphan_time)
; --(optional)
-- This table will not exist for upgrades from pre 3.2 to 3.2 Enterprise Final
DROP TABLE alf_content_clean; --(optional)
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-ContentTables2';
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.2-ContentTables2', 'Manually executed script upgrade V3.2: Content Tables 2 (pre 3.2 Enterprise Final)',
0, 3008, -1, 3009, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,42 +0,0 @@
--
-- Title: Upgrade to V3.2 - Add qname_crc column to alf_child_assoc
-- Database: PostgreSQL
-- Since: V3.2 schema 3006
-- Author: Pavel Yurkevich
--
-- Add qname_crc column to alf_child_assoc and change indexes
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
ALTER TABLE alf_child_assoc
ADD COLUMN qname_crc INT8 NOT NULL DEFAULT 0;
-- Enable additional patches to run by CRC-ing the descriptor nodes
UPDATE alf_child_assoc
SET qname_crc = 147310537
WHERE qname_ns_id = (SELECT id FROM alf_namespace WHERE uri = 'http://www.alfresco.org/model/system/1.0')
AND qname_localname = 'descriptor';
UPDATE alf_child_assoc
SET qname_crc = 369154895
WHERE qname_ns_id = (SELECT id FROM alf_namespace WHERE uri = 'http://www.alfresco.org/model/system/1.0')
AND qname_localname = 'descriptor-current';
ALTER TABLE alf_child_assoc ALTER COLUMN qname_crc DROP DEFAULT;
DROP INDEX idx_alf_cass_qnln;
CREATE INDEX idx_alf_cass_qncrc ON alf_child_assoc (qname_crc, type_qname_id, parent_node_id);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-Child-Assoc-QName-CRC';
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.2-Child-Assoc-QName-CRC', 'Manually executed script upgrade V3.2 to Add qname_crc column to alf_child_assoc and change indexes',
0, 3005, -1, 3006, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,40 +0,0 @@
--
-- Title: Upgrade to V3.2 - upgrade jbpm tables to jbpm 3.3.1
-- Database: PostgreSQL
-- Since: V3.2 schema 2013
-- Author:
--
-- upgrade jbpm tables to jbpm 3.3.1
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- we mark next statement as optional to not fail the upgrade from 2.1.a (as it doesn't contain jbpm)
alter table JBPM_ACTION alter column EXPRESSION_ type text; -- (optional)
alter table JBPM_COMMENT alter column MESSAGE_ type text; -- (optional)
alter table JBPM_DELEGATION alter column CLASSNAME_ type text; -- (optional)
alter table JBPM_DELEGATION alter column CONFIGURATION_ type text; -- (optional)
alter table JBPM_EXCEPTIONHANDLER alter column EXCEPTIONCLASSNAME_ type text; -- (optional)
alter table JBPM_JOB alter column EXCEPTION_ type text; -- (optional)
alter table JBPM_LOG alter column MESSAGE_ type text,
alter column EXCEPTION_ type text,
alter column OLDSTRINGVALUE_ type text,
alter column NEWSTRINGVALUE_ type text; -- (optional)
alter table JBPM_MODULEDEFINITION alter column NAME_ type varchar(255); -- (optional)
alter table JBPM_NODE alter column DESCRIPTION_ type text; -- (optional)
alter table JBPM_PROCESSDEFINITION alter column DESCRIPTION_ type text; -- (optional)
alter table JBPM_TASK alter column DESCRIPTION_ type text; -- (optional)
alter table JBPM_TASKINSTANCE alter column DESCRIPTION_ type text; -- (optional)
alter table JBPM_TRANSITION alter column DESCRIPTION_ type text; -- (optional)
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.2-Upgrade-JBPM';
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.2-Upgrade-JBPM', 'Manually executed script upgrade V3.2 to jbpm version 3.3.1 usage',
0, 2017, -1, 2018, null, 'UNKOWN', TRUE, TRUE, 'Script completed'
);

View File

@@ -1,23 +0,0 @@
--
-- Title: Upgrade to V3.3 - Create repo sequences
-- Database: Generic
-- Since: V3.4 schema 4105
-- Author: unknown
--
-- creates sequences for repo tables
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.3-Fix-Repo-Seqs';
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.3-Fix-Repo-Seqs', 'Manually executed script upgrade V3.3 to create repo sequences',
0, 4104, -1, 4105, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,19 +0,0 @@
--
-- Title: Upgrade to V3.3
-- Database: DB2
-- Since: V3.3 schema 4106
-- Author: janv
--
-- This patch is only required to fix column on DB2.
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.3-Node-Prop-Serializable';
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.3-Node-Prop-Serializable', 'Manually executed script upgrade V3.3',
0, 4105, -1, 4106, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,24 +0,0 @@
--
-- Title: Upgrade to V3.3 - Remove Version Count
-- Database: Generic
-- Since: V3.3 schema 4003
-- Author: janv
--
-- remove (obsolete) version count table
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
drop table alf_version_count;
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.3-Remove-VersionCount';
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.3-Remove-VersionCount', 'Manually executed script upgrade V3.3 to remove Version Count',
0, 4002, -1, 4003, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,154 +0,0 @@
--
-- Title: Upgrade to V3.3 - Remove context_id from the permission_id index on alf_access_control_list_entry
-- Database: MySQL
-- Since: V3.3 schema 4011
-- Author: andyh
--
-- Remove context_id from the permission_id unique index (as it alwaays contains null and therefore has no effect)
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- The remainder of this script is adapted from
-- Repository/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoSchemaUpdate-2.2-ACL.sql
-- Ports should do the same and reflect the DB specific improvements
CREATE TABLE alf_tmp_min_ace (
min BIGINT NOT NULL,
permission_id BIGINT NOT NULL,
authority_id BIGINT NOT NULL,
allowed BIT(1) NOT NULL,
applies INT NOT NULL,
UNIQUE (permission_id, authority_id, allowed, applies)
) ENGINE=InnoDB;
INSERT INTO alf_tmp_min_ace (min, permission_id, authority_id, allowed, applies)
SELECT
min(ace1.id),
ace1.permission_id,
ace1.authority_id,
ace1.allowed,
ace1.applies
FROM
alf_access_control_entry ace1
GROUP BY
ace1.permission_id, ace1.authority_id, ace1.allowed, ace1.applies
;
CREATE TABLE alf_tmp_acl_members (
id BIGINT NOT NULL,
min BIGINT NOT NULL,
acl_id BIGINT NOT NULL,
pos BIGINT,
ace_id BIGINT NOT NULL,
PRIMARY KEY (id),
UNIQUE (min, acl_id, pos, ace_id)
) ENGINE=InnoDB;
INSERT INTO
alf_tmp_acl_members
SELECT
mem.id, help.min, mem.acl_id, mem.pos, mem.ace_id
FROM
alf_acl_member mem
JOIN
alf_access_control_entry ace
ON
mem.ace_id = ace.id
JOIN
alf_tmp_min_ace help
ON
help.permission_id = ace.permission_id AND
help.authority_id = ace.authority_id AND
help.allowed = ace.allowed AND
help.applies = ace.applies;
CREATE TABLE alf_tmp_acl_groups (
min BIGINT NOT NULL,
acl_id BIGINT NOT NULL,
pos BIGINT,
group_min BIGINT NOT NULL,
UNIQUE (min, acl_id, pos)
) ENGINE=InnoDB;
INSERT INTO
alf_tmp_acl_groups
SELECT
mems.min, mems.acl_id, mems.pos, min(mems.ace_id)
FROM
alf_tmp_acl_members mems
GROUP BY
mems.min, mems.acl_id, mems.pos
HAVING
count(*) > 1;
DELETE FROM
alf_acl_member
WHERE
id IN (
SELECT
mems.id
FROM
alf_tmp_acl_members mems
JOIN
alf_tmp_acl_groups groups
ON
mems.min = groups.min AND
mems.acl_id = groups.acl_id AND
mems.pos = groups.pos
WHERE
mems.ace_id <> groups.group_min
);
DROP TABLE
alf_tmp_acl_members;
DROP TABLE
alf_tmp_acl_groups;
-- Update members to point to the first use of an access control entry
UPDATE alf_acl_member mem
SET ace_id = (SELECT help.min FROM alf_access_control_entry ace
JOIN alf_tmp_min_ace help
ON help.permission_id = ace.permission_id AND
help.authority_id = ace.authority_id AND
help.allowed = ace.allowed AND
help.applies = ace.applies
WHERE ace.id = mem.ace_id );
DROP TABLE alf_tmp_min_ace;
-- Remove duplicate aces the mysql way (as you can not use the deleted table in the where clause ...)
CREATE TABLE tmp_to_delete SELECT ace.id FROM alf_acl_member mem RIGHT OUTER JOIN alf_access_control_entry ace ON mem.ace_id = ace.id WHERE mem.ace_id IS NULL;
DELETE FROM ace USING alf_access_control_entry ace JOIN tmp_to_delete t ON ace.id = t.id;
DROP TABLE tmp_to_delete;
-- Add constraint for duplicate acls (this no longer includes the context)
ALTER TABLE alf_access_control_entry DROP INDEX permission_id;
ALTER TABLE alf_access_control_entry
ADD UNIQUE permission_id (permission_id, authority_id, allowed, applies);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.3-modify-index-permission_id';
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.3-modify-index-permission_id', 'Remove context_id from the permission_id unique index (as it always contains null and therefore has no effect)',
0, 4102, -1, 4103, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,63 +0,0 @@
--
-- Title: Upgrade to V3.3 - Create repo sequences
-- Database: PostgreSQL
-- Since: V3.4 schema 4105
-- Author: unknown
--
-- creates sequences for repo tables
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
--ASSIGN:hibernate_seq_next_value=value
SELECT NEXTVAL('hibernate_sequence') AS value;
CREATE SEQUENCE alf_namespace_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1; -- (optional)
CREATE SEQUENCE alf_qname_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1; -- (optional)
CREATE SEQUENCE alf_permission_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_ace_context_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_authority_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_access_control_entry_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_acl_change_set_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_access_control_list_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_acl_member_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_authority_alias_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_server_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_transaction_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_store_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_node_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_child_assoc_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_locale_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_attributes_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_node_assoc_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1;
CREATE SEQUENCE alf_usage_delta_seq START WITH ${hibernate_seq_next_value} INCREMENT BY 1; -- (optional)
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.3-Fix-Repo-Seqs';
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.3-Fix-Repo-Seqs', 'Manually executed script upgrade V3.3 to create repo sequences',
0, 4104, -1, 4105, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,153 +0,0 @@
--
-- Title: Upgrade to V3.3 - Remove context_id from the permission_id index on alf_access_control_list_entry
-- Database: PostgreSQL
-- Since: V3.3 schema 4011
-- Author:
--
-- Remove context_id from the permission_id unique index (as it alwaays contains null and therefore has no effect)
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- The remainder of this script is adapted from
-- Repository/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoSchemaUpdate-2.2-ACL.sql
-- Ports should do the same and reflect the DB specific improvements
CREATE TABLE alf_tmp_min_ace (
min INT8 NOT NULL,
permission_id INT8 NOT NULL,
authority_id INT8 NOT NULL,
allowed BOOL NOT NULL,
applies INT4 NOT NULL,
UNIQUE (permission_id, authority_id, allowed, applies)
);
INSERT INTO alf_tmp_min_ace (min, permission_id, authority_id, allowed, applies)
SELECT
min(ace1.id),
ace1.permission_id,
ace1.authority_id,
ace1.allowed,
ace1.applies
FROM
alf_access_control_entry ace1
GROUP BY
ace1.permission_id, ace1.authority_id, ace1.allowed, ace1.applies
;
CREATE TABLE alf_tmp_acl_members (
id INT8 NOT NULL,
min INT8 NOT NULL,
acl_id INT8 NOT NULL,
pos INT8,
ace_id INT8 NOT NULL,
PRIMARY KEY (id),
UNIQUE (min, acl_id, pos, ace_id)
);
INSERT INTO
alf_tmp_acl_members
SELECT
mem.id, help.min, mem.acl_id, mem.pos, mem.ace_id
FROM
alf_acl_member mem
JOIN
alf_access_control_entry ace
ON
mem.ace_id = ace.id
JOIN
alf_tmp_min_ace help
ON
help.permission_id = ace.permission_id AND
help.authority_id = ace.authority_id AND
help.allowed = ace.allowed AND
help.applies = ace.applies;
CREATE TABLE alf_tmp_acl_groups (
min INT8 NOT NULL,
acl_id INT8 NOT NULL,
pos INT8,
group_min INT8 NOT NULL,
UNIQUE (min, acl_id, pos)
);
INSERT INTO
alf_tmp_acl_groups
SELECT
mems.min, mems.acl_id, mems.pos, min(mems.ace_id)
FROM
alf_tmp_acl_members mems
GROUP BY
mems.min, mems.acl_id, mems.pos
HAVING
count(*) > 1;
DELETE FROM
alf_acl_member
WHERE
id IN (
SELECT
mems.id
FROM
alf_tmp_acl_members mems
JOIN
alf_tmp_acl_groups groups
ON
mems.min = groups.min AND
mems.acl_id = groups.acl_id AND
mems.pos = groups.pos
WHERE
mems.ace_id <> groups.group_min
);
DROP TABLE
alf_tmp_acl_members;
DROP TABLE
alf_tmp_acl_groups;
-- Update members to point to the first use of an access control entry
UPDATE alf_acl_member mem
SET ace_id = (SELECT help.min FROM alf_access_control_entry ace
JOIN alf_tmp_min_ace help
ON help.permission_id = ace.permission_id AND
help.authority_id = ace.authority_id AND
help.allowed = ace.allowed AND
help.applies = ace.applies
WHERE ace.id = mem.ace_id );
DROP TABLE alf_tmp_min_ace;
-- Remove duplicate aces the mysql way (as you can not use the deleted table in the where clause ...)
CREATE TABLE tmp_to_delete AS SELECT ace.id FROM alf_acl_member mem RIGHT OUTER JOIN alf_access_control_entry ace ON mem.ace_id = ace.id WHERE mem.ace_id IS NULL;
DELETE FROM alf_access_control_entry ace USING tmp_to_delete t WHERE ace.id = t.id;
DROP TABLE tmp_to_delete;
-- Add constraint for duplicate acls (this no longer includes the context)
ALTER TABLE alf_access_control_entry DROP CONSTRAINT alf_access_control_entry_permission_id_key; -- (optional)
ALTER TABLE alf_access_control_entry DROP CONSTRAINT alf_access_control_entry_permission_id_authority_id_allowed_key; -- (optional)
ALTER TABLE alf_access_control_entry
ADD UNIQUE (permission_id, authority_id, allowed, applies);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V3.3-modify-index-permission_id';
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.3-modify-index-permission_id', 'Remove context_id from the permission_id unique index (as it always contains null and therefore has no effect)',
0, 4102, -1, 4103, null, 'UNKOWN', TRUE, TRUE, 'Script completed'
);

View File

@@ -28,123 +28,76 @@ patch.genericMimetypeUpdate.indexed=\n\tIndexed {0} nodes in store ''{1}''.
patch.genericMimetypeUpdate.done=\n\tFinished updating mimetypes.
patch.genericMimetypeUpdate.doneReindex=\n\tFinished updating mimetypes. Selective reindexing was disabled; a reindex is required to search for the new mimetype(s).
# Individual patch messages
patch.noOpPatch.description=A placeholder patch; usually marks a superceded patch.
patch.noOpPatch.result=No-op patch
patch.marker.description=Marker patch to record installations and upgrades
patch.marker.result=Marker patch applied
patch.schemaUpgradeScript.description=Ensures that the database upgrade script has been run.
patch.schemaUpgradeScript.err.not_executed=The schema upgrade script, ''{0}'', has not been run against this database.
# Individual patch messages
patch.savedSearchesFolder.description=Ensures the existence of the 'Saved Searches' folder.
patch.savedSearchesFolder.result.exists=The saved searches folder already exists: {0}
patch.savedSearchesFolder.result.created=The saved searches folder was successfully created: {0}
patch.savedSearchesPermission.description=Sets required permissions on 'Saved Searches' folder.
patch.savedSearchesPermission.result.applied=Granted CONTRIBUTOR role to EVERYONE on ''Saved Searches'' folder: {0}.
patch.savedSearchesPermission.err.not_found='Saved Searches' folder could not be found.
patch.updatePermissionData.description=Update permissions from 'folder' to 'cmobject' [JIRA: AR-344].
patch.updatePermissionData.result=Changed {0} ''folder'' access control entries to ''cmobject''.
patch.authoritiesFolder.description=Ensures the existence of the user authorities folder [JIRA: AR-497].
patch.authoritiesFolderPermission.description=Ensures group authorities are visible to everyone.
patch.guestUser.description=Add the guest user, guest home space; and fix permissions on company home, guest home and guest person.
patch.guestUser.result=Added guest user and fixed permissions.
patch.fixNodeSerializableValues.description=Ensure that property values are not stored as Serializable if at all possible
patch.fixNodeSerializableValues.result=Fixed {0} node property serialized values
patch.updateGuestPermission.description=Rename guest permission from 'Guest' to 'Consumer'
patch.updateGuestPermission.result=Changed {0} ''Guest'' access control entries to ''Consumer''.
patch.categoryRootPermission.description=Sets required permissions on 'Category Root' folder.
patch.categoryRootPermission.result=Granted CONSUMER role to GUEST on ''Category Root'' folder: {0}.
patch.categoryRootPermission.err.not_found=''Category Root'' folder ({0}) could not be found.
patch.guestPersonPermission.description=Change Guest Person permission from 'Consumer' to 'Read'
patch.guestPersonPermission.result=Updated Guest Person permission from 'Consumer' to 'Read'
patch.spacesRootPermission.description=Change Spaces store root permission from 'Consumer' to 'Read'
patch.spacesRootPermission.result=Updated Spaces store root permission from 'Consumer' to 'Read'
patch.contentPermission.description=Update permission entries from 'cm:content' to 'sys:base'.
patch.contentPermission.result=Changed {0} ''cm:content'' access control entries to ''sys:base''.
patch.forumsIcons.description=Updates forums icon references
patch.forumsIcons.result=Updated {0} icon references
patch.emailTemplatesFolder.description=Ensures the existence of the 'Email Templates' folder.
patch.emailTemplatesFolder.result.exists=The email templates folder already exists: {0}
patch.emailTemplatesFolder.result.created=The email templates folder was successfully created: {0}
patch.emailInviteAndNotifyTemplatesFolder.description=Ensures the existence of the 'Email Invite Templates' and 'Email Notify Templates' folders.
patch.emailNotifyTemplatesFolder.result.exists=The Email Notify Templates folder already exists: {0}
patch.emailNotifyTemplatesFolder.result.created=The Email Notify Templates folder was successfully created: {0}
patch.emailInviteTemplatesFolder.result.exists=The Email Invite Templates folder already exists: {0}
patch.emailInviteTemplatesFolder.result.created=The Email Invite Templates folder was successfully created: {0}
patch.emailTemplatesContent.description=Loads the email templates into the Email Templates folder.
patch.emailTemplatesContent.result=Imported the Email Templates into the default folder.
patch.descriptorUpdate.description=Update Repository descriptor
patch.descriptorUpdate.result=Repository descriptor updated
patch.scriptsFolder.description=Ensures the existence of the 'Scripts' folder.
patch.scriptsFolder.result.exists=The scripts folder already exists: {0}
patch.scriptsFolder.result.created=The scripts folder was successfully created: {0}
patch.topLevelGroupParentChildAssociationTypePatch.description=Ensure top level groups have the correct child association type.
patch.topLevelGroupParentChildAssociationTypePatch.result=Fixed {0} top level groups child association types.
patch.topLevelGroupParentChildAssociationTypePatch.err.sys_path_not_found=Required authority system path not found: {0}
patch.topLevelGroupParentChildAssociationTypePatch.err.auth_path_not_found=Required authority path not found: {0}
patch.actionRuleDecouplingPatch.description=Migrate existing rules to the updated model where rules are decoupled from actions.
patch.actionRuleDecouplingPatch.result=Updated {0} rules.
patch.systemWorkflowFolder.description=Ensures the existence of the system workflow container.
patch.systemWorkflowFolder.result.created=Created system workflow container {0}.
patch.rssTemplatesFolder.description=Ensures the existence of the 'RSS Templates' folder.
patch.rssTemplatesFolder.result.exists=The RSS Templates folder already exists: {0}. Re-applying guest permissions.
patch.rssTemplatesFolder.result.created=The RSS Templates folder was successfully created: {0}
patch.rendition.rendering_actions.exists=The Rendering Actions folder already exists: {0}.
patch.rendition.rendering_actions.created=The Rendering Actions folder was successfully created: {0}
patch.rendition.rendering_actions.description=Creates the Rendering Actions folder.
patch.replication.replication_actions.exists=The Replication Actions folder already exists: {0}.
patch.replication.replication_actions.created=The Replication Actions folder was successfully created: {0}
patch.replication.replication_actions.description=Creates the Replication Actions folder.
patch.uifacetsAspectRemovalPatch.description=Removes the incorrectly applied uifacets aspect from presentation template files.
patch.uifacetsAspectRemovalPatch.updated=Successfully removed the uifacets aspect from {0} presentation template files.
patch.guestPersonPermission2.description=Change Guest Person permission to visible by all users as 'Consumer'.
patch.guestPersonPermission2.result=Updated Guest Person permission to visible by all users as 'Consumer'.
patch.schemaUpgradeScript.description=Ensures that the database upgrade script has been run.
patch.schemaUpgradeScript.err.not_executed=The schema upgrade script, ''{0}'', has not been run against this database.
patch.uniqueChildName.description=Checks and renames duplicate children.
patch.uniqueChildName.copyOf=({0}-{1})
patch.uniqueChildName.result=Checked {0} associations and fixed {1} duplicates. See file {2} for details.
patch.uniqueChildName.err.unable_to_fix=Auto-fixing of duplicate names failed. See file {0} for details.
patch.invalidNameEnding.description=Fixes names ending with a space or full stop.
patch.invalidNameEnding.result=Fixed {0} names ending with a space or full stop. See file {1} for details.
patch.invalidNameEnding.err.unable_to_fix=Auto-fixing of names ending with a space or full stop failed. See file {0} for details.
patch.invalidNameEnding.rewritten=Name ''{0}'' rewritten to ''{1}''
patch.systemDescriptorContent.description=Adds the version properties content to the system descriptor.
patch.systemDescriptorContent.result=Added the version properties content to the system descriptor.
patch.systemDescriptorContent.err.no_version_properties=The version.properties resource could not be found.
patch.systemDescriptorContent.err.no_descriptor=The system descriptor could not be found.
patch.versionHistoryPerformance.description=Improves the performance of version history lookups.
patch.versionHistoryPerformance.result=Updated {0} version history objects to improve performance.
patch.multilingualBootstrap.description=Bootstraps the node that will hold the multilingual containers.
@@ -156,20 +109,14 @@ patch.siteLoadPatch.siteNotCreated=The site {0} is only created for new installs
patch.siteLoadPatch.siteLoadDisabled=The load of site {0} is disabled.
patch.linkNodeExtension.description=Fixes link node file extensions to have a .url extension.
patch.linkNodeExtension.result=Fixed {0} link node file extensions. See file {1} for details.
patch.linkNodeExtension.err.unable_to_fix=Auto-fixing of link node file extensions failed. See file {0} for details.
patch.linkNodeExtension.rewritten=Name ''{0}'' rewritten to ''{1}''
patch.systemRegistryBootstrap.description=Bootstraps the node that will hold system registry metadata.
patch.userAndPersonUserNamesAsIdentifiers.description=Reindex usr:user and cm:person uids as identifiers
patch.userAndPersonUserNamesAsIdentifiers.result=Reindexed user:user and cm:person uids as identifiers
patch.groupNamesAsIdentifiers.description=Reindex usr:authorityContainer gids as identifiers
patch.groupNamesAsIdentifiers.result=Reindexed usr:authorityContainer with identifiers
patch.invalidUserPersonAndGroup.description=Fix up invalid uids for people and users; and invalid gids for groups
patch.invalidUserPersonAndGroup.result=Fixed ''{0}'' invalid user nodes, ''{1}'' invalid person nodes and ''{2}'' invalid authority nodes.
patch.webscripts.description=Adds Web Scripts to Data Dictionary.
patch.webscripts2.description=Adds Web Scripts (second set) to Data Dictionary.
@@ -207,7 +154,6 @@ patch.updateDmPermissions.description=Update ACLs on all DM node objects to the
patch.db-V3.0-0-CreateActivitiesExtras.description=Replaced by 'patch.db-V3.0-ActivityTables', which must run first.
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)
@@ -228,62 +174,26 @@ patch.mtShareExistingTenants.description=Update existing tenants for MT Share.
patch.redeployInvitationProcess.description=Re-deploy Invitation Process Definitions.
patch.imapFolders.description=Creates folders tree necessary for IMAP functionality
patch.imapFolders.result.exists=The 'Imap Configs' folder already exists
patch.imapFolders.result.created=The 'Imap Configs' folder was successfully created
patch.zonedAuthorities.description=Adds the remodelled cm:authority container to the spaces store
patch.authorityMigration.description=Copies any old authorities from the user store to the spaces store.
patch.authorityMigration.process.name=Authority Migration
patch.authorityMigration.warning.assoc=Ignoring group memberships of non-existent user {1}
patch.authorityMigration.result=Migrated {0} groups and {1} group associations to the spaces store.
patch.authorityDefaultZonesPatch.description=Adds groups and people to the appropriate zones for share and everything else.
patch.authorityDefaultZonesPatch.result=Unzoned groups and people added to the default zones.
patch.authorityDefaultZonesPatch.users= Adding users to zones ...
patch.authorityDefaultZonesPatch.groups= Adding groups to zones ...
patch.fixNameCrcValues.description=Fixes name and qname CRC32 values to match UTF-8 encoding.
patch.fixNameCrcValues.result=Fixed CRC32 values for UTF-8 encoding for {0} node child associations. See file {1} for details.
patch.fixNameCrcValues.fixed=Updated CRC32 values for association ID {0}, name ''{1}'': {2} -> {3}, qname ''{4}'': {5} -> {6}.
patch.fixNameCrcValues.unableToChange=Failed to update the CRC32 value for association ID {0}: \n Node name: {1} \n name CRC old: {2} \n name CRC new: {3} \n qname: {4} \n qname CRC old: {5} \n qname CRC new: {6} \n Error: {7}
patch.fixNameCrcValues.fixingLocalname=Fixing invalid localname for association ID {0}: \n Was: ''{1}'' \n Now: ''{2}''
patch.fixNameCrcValues.associationTypeNotDefined=Association type ''{0}'' has not been defined for child association ID {1}.
patch.fixNameCrcValues.associationTypeNotChild=Association type ''{0}'' does not represent a child association but is used as one; for child association ID {1}.
patch.personUsagePatch.description=Add person 'cm:sizeCurrent' property (if missing).
patch.personUsagePatch.result1=Added ''cm:sizeCurrent'' property to {0} people that were missing this property.
patch.personUsagePatch.result2=No people were missing the 'cm:sizeCurrent' property.
patch.redeployNominatedInvitationProcessWithPropsForShare.description=Redeploy nominated invitation workflow
patch.redeployNominatedInvitationProcessWithPropsForShare.result=Nominated invitation workflow redeployed
patch.redeployJbpmAdhocWorkflow.description=Redeploy JBPM adhoc workflow
patch.redeployJbpmAdhocWorkflow.result=JBPM adhoc workflow redeployed
patch.transferDefinitions.description=Add transfer definitions folder to data dictionary.
patch.transferDefinitions.result=Transfer definitions folder added to data dictionary.
patch.redeployNominatedInvitationProcessWithPropsForShare.description=Redeploy nominated invitation workflow
patch.redeployNominatedInvitationProcessWithPropsForShare.result=Nominated invitation workflow redeployed
patch.thumbnailsAssocQName.description=Update the 'cm:thumbnails' association QName to 'rn:rendition'.
patch.convertContentUrls.description=Converts pre-3.2 content URLs to use the alf_content_data table. The conversion work can also be done on a schedule; please contact Alfresco Support for further details.
patch.convertContentUrls.bypassingPatch=Content URL conversion was NOT performed by this patch. Activate the scheduled job 'contentUrlConverterTrigger'.
patch.convertContentUrls.start=Content URL conversion progress:
patch.convertContentUrls.error=Content URL conversion failed: {0}
patch.convertContentUrls.inProgress=Content URL conversion increment completed. Awaiting next scheduled call...
patch.convertContentUrls.done=Content URL conversion completed.
patch.convertContentUrls.adm.start=\tProcessing ADM Content URLs.
patch.convertContentUrls.adm.done=\tFinished processing ADM nodes up to ID {0}.
patch.convertContentUrls.store.start=\tReading content URLs from store {0}.
patch.convertContentUrls.store.readOnly=\tNo content URLs will be marked for deletion. The content store is read-only.
patch.convertContentUrls.store.pending=\tContent URLs will be marked for deletion once the URL conversion process is complete.
patch.convertContentUrls.store.noSupport=\tNo content URLs will be marked for deletion. The store does not support URL enumeration.
patch.convertContentUrls.store.progress=\t\tProcessed {0} content URLs from store.
patch.convertContentUrls.store.scheduled=\tScheduled {0} content URLs for deletion from store: {1}
patch.convertContentUrls.store.done=This job is complete. Deactivate the scheduled job 'contentUrlConverterTrigger'.
patch.fixAuthoritiesCrcValues.description=Fixes authority CRC32 values to match UTF-8 encoding.
patch.fixAuthoritiesCrcValues.result=Fixed CRC32 values for UTF-8 encoding for {0} authorities. See file {1} for details.
@@ -299,6 +209,9 @@ patch.updateMimetypesSVG.description=Fix mimetype for SVG Image
patch.updateMimetypesVISIO.description=Fix mimetype for Microsoft Visio
patch.updateMimetypesSVG.description=Fix mimetype for Scalable Vector Graphics Image
patch.redeployJbpmAdhocWorkflow.description=Redeploy JBPM adhoc workflow
patch.redeployJbpmAdhocWorkflow.result=JBPM adhoc workflow redeployed
patch.db-V3.2-AddFKIndexes.description=Fixes ALF-3189: Added missing FK indexes. Note: The script is empty for MySQL.
patch.migrateAttrTenants.description=Migrate old Tenant attributes

View File

@@ -173,6 +173,9 @@
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>5</value></property>
<property name="targetSchema"><value>6</value></property>
<property name="lastSupportedVersion" >
<value>3.3</value>
</property>
</bean>
<bean id="patch.spacesRootPermission" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.spacesRootPermission</value></property>
@@ -904,175 +907,106 @@
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.2-LockTables" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.2-LockTables" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-LockTables</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2010</value></property>
<property name="targetSchema"><value>2011</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-LockTables.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.zonedAuthorities" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
<bean id="patch.zonedAuthorities" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.zonedAuthorities</value></property>
<property name="description"><value>patch.zonedAuthorities.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2011</value></property>
<property name="targetSchema"><value>2012</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
</property>
<property name="importerBootstrap">
<ref bean="spacesBootstrap" />
</property>
<property name="checkPath">
<value>/${system.system_container.childname}/${system.authorities_container.childname}</value>
</property>
<property name="bootstrapView">
<props>
<prop key="path">/${system.system_container.childname}</prop>
<prop key="location">alfresco/bootstrap/alfrescoAuthorityStore.xml</prop>
</props>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.authorityMigration" class="org.alfresco.repo.admin.patch.impl.AuthorityMigrationPatch" parent="basePatch" >
<bean id="patch.authorityMigration" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.authorityMigration</value></property>
<property name="description"><value>patch.authorityMigration.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2012</value></property>
<property name="targetSchema"><value>2013</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.fixUserQNames" />
<ref bean="patch.updateDmPermissions" />
<ref bean="patch.zonedAuthorities" />
</list>
</property>
<property name="authorityService">
<ref bean="authorityService" />
</property>
<property name="ruleService">
<ref bean="ruleService" />
</property>
<property name="userBootstrap">
<ref bean="userBootstrap" />
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.authorityDefaultZonesPatch" class="org.alfresco.repo.admin.patch.impl.AuthorityDefaultZonesPatch" parent="basePatch" >
<bean id="patch.authorityDefaultZonesPatch" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.authorityDefaultZonesPatch</value></property>
<property name="description"><value>patch.authorityDefaultZonesPatch.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2013</value></property>
<property name="targetSchema"><value>2014</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
<ref bean="patch.authorityMigration" />
<ref bean="patch.personUsagePatch" />
</list>
</property>
<property name="authorityService">
<ref bean="authorityService" />
</property>
<property name="siteService">
<ref bean="siteService" />
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.2-ContentTables" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.2-ContentTables" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-ContentTables</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2015</value></property>
<property name="targetSchema"><value>2016</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-ContentTables.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.4-Upgrade-JBPM" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.4-Upgrade-JBPM" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.4-Upgrade-JBPM</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2017</value></property>
<property name="targetSchema"><value>6001</value></property>
<property name="alternatives">
<list>
<ref bean="patch.db-V3.2-Upgrade-JBPM" />
</list>
</property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/jbpm-upgrade.sql</value>
<property name="targetSchema"><value>2018</value></property>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.2-Upgrade-JBPM" class="org.alfresco.repo.admin.patch.impl.NoOpPatch" parent="basePatch">
<bean id="patch.db-V3.2-Upgrade-JBPM" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-Upgrade-JBPM</value></property>
<property name="description"><value>patch.noOpPatch.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2017</value></property>
<property name="targetSchema"><value>2018</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.db-V3.4-alter-jBPM331-CLOB-columns-to-nvarchar" />
</list>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.imapFolders" class="org.alfresco.repo.admin.patch.impl.ImapFoldersPatch" parent="basePatch" >
<bean id="patch.imapFolders" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.imapFolders</value></property>
<property name="description"><value>patch.imapFolders.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>2018</value></property>
<property name="targetSchema"><value>2019</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
<property name="importerBootstrap">
<ref bean="spacesBootstrap" />
</property>
<property name="messageSource">
<ref bean="bootstrapSpacesMessageSource" />
</property>
<property name="importerService">
<ref bean="importerComponent" />
</property>
<property name="configFoldersACP"><value>alfresco/templates/imap/imap_config_space.acp</value></property>
<property name="emailActionsACP"><value>alfresco/templates/imap/email_actions_space.acp</value></property>
<property name="scriptsACP"><value>alfresco/templates/imap/command_processor_scripts.acp</value></property>
</bean>
<bean id="patch.db-V3.2-PropertyValueTables" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.2-PropertyValueTables" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-PropertyValueTables</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>3000</value></property>
<property name="targetSchema"><value>3001</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-PropertyValueTables.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.2-AuditTables" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.2-AuditTables" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-AuditTables</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>3001</value></property>
<property name="targetSchema"><value>3002</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/create/${db.script.dialect}/AlfrescoCreate-AuditTables.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.1-Allow-IPv6" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.1-Allow-IPv6</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
@@ -1083,253 +1017,115 @@
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.personUsagePatch" class="org.alfresco.repo.admin.patch.impl.PersonUsagePatch" parent="basePatch" >
<bean id="patch.personUsagePatch" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.personUsagePatch</value></property>
<property name="description"><value>patch.personUsagePatch.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>3004</value></property>
<property name="targetSchema"><value>3005</value></property>
<property name="patchDAO">
<ref bean="patchDAO"/>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.2-Child-Assoc-QName-CRC" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.2-Child-Assoc-QName-CRC" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-Child-Assoc-QName-CRC</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>3005</value></property>
<property name="targetSchema"><value>3006</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/child-assoc-qname-crc.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.fixNameCrcValues-2" class="org.alfresco.repo.admin.patch.impl.FixNameCrcValuesPatch" parent="basePatch" >
<bean id="patch.fixNameCrcValues-2" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.fixNameCrcValues-2</value></property>
<property name="description"><value>patch.fixNameCrcValues.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>3006</value></property>
<property name="targetSchema"><value>3007</value></property>
<property name="applyToTenants"><value>false</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.thumbnailsAssocQName" />
<ref bean="patch.uniqueChildName" />
<ref bean="patch.InvalidNameEnding" />
</list>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
<property name="patchDAO" ref="patchDAO" />
<property name="qnameDAO" ref="qnameDAO" />
<property name="controlDAO" ref="controlDAO" />
<property name="dictionaryService" ref="dictionaryService" />
<property name="batchThreads" value="2"/>
<property name="batchSize" value="1000"/>
<property name="batchMaxQueryRange" value="5000"/>
<property name="batchQuerySize" value="2000"/>
</bean>
<bean id="patch.redeployNominatedInvitationProcessWithPropsForShare" class="org.alfresco.repo.admin.patch.impl.GenericWorkflowPatch" parent="baseWorkflowPatch" >
<bean id="patch.redeployNominatedInvitationProcessWithPropsForShare" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.redeployNominatedInvitationProcessWithPropsForShare</value></property>
<property name="description"><value>patch.redeployNominatedInvitationProcessWithPropsForShare.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4000</value></property>
<property name="targetSchema"><value>4001</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
</property>
<property name="workflowDefinitions">
<list>
<props>
<prop key="engineId">jbpm</prop>
<prop key="location">alfresco/workflow/invitation-nominated_processdefinition.xml</prop>
<prop key="mimetype">text/xml</prop>
</props>
</list>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.redeployJbpmAdhocWorkflow" class="org.alfresco.repo.admin.patch.impl.GenericWorkflowPatch" parent="baseWorkflowPatch" >
<property name="id"><value>patch.redeployJbpmAdhocWorkflow</value></property>
<property name="description"><value>patch.redeployJbpmAdhocWorkflow.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4204</value></property>
<property name="targetSchema"><value>4205</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
</property>
<property name="workflowDefinitions">
<list>
<props>
<prop key="engineId">jbpm</prop>
<prop key="location">alfresco/workflow/adhoc_processdefinition.xml</prop>
<prop key="mimetype">text/xml</prop>
</props>
</list>
</property>
</bean>
<bean id="patch.db-V3.2-ContentTables2" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.2-ContentTables2" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-ContentTables2</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4001</value></property>
<property name="targetSchema"><value>4002</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.db-V3.2-ContentTables" />
</list>
</property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/AlfrescoSchemaUpdate-3.2-ContentTables2.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.3-Remove-VersionCount" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.3-Remove-VersionCount" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.3-Remove-VersionCount</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4002</value></property>
<property name="targetSchema"><value>4003</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/remove-VersionCount.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.rendition.rendering_actions" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
<bean id="patch.rendition.rendering_actions" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.rendition.rendering_actions</value></property>
<property name="description"><value>patch.rendition.rendering_actions.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4003</value></property>
<property name="targetSchema"><value>4004</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
</property>
<property name="importerBootstrap">
<ref bean="spacesBootstrap" />
</property>
<property name="checkPath">
<value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.rendition.rendering_actions.childname}</value>
</property>
<property name="bootstrapView">
<props>
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}</prop>
<prop key="location">alfresco/bootstrap/renderingActionSpace.xml</prop>
<prop key="messages">alfresco/messages/bootstrap-spaces</prop>
</props>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<!-- This patch updates Thumbnails from Alfresco 3.2.x and earlier to their Alfresco 3.3
equivalents: renditions. It changes the QName of the old cm:thumbnails child-association
to rn:rendition -->
<bean id="patch.thumbnailsAssocQName" class="org.alfresco.repo.admin.patch.impl.QNamePatch" parent="basePatch" >
<bean id="patch.thumbnailsAssocQName" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.thumbnailsAssocQName</value></property>
<property name="description"><value>patch.thumbnailsAssocQName.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4004</value></property>
<property name="targetSchema"><value>4005</value></property>
<property name="patchDAO">
<ref bean="patchDAO" />
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
<property name="nodeDAO">
<ref bean="nodeDAO" />
</property>
<property name="retryingTransactionHelper">
<ref bean="retryingTransactionHelper" />
</property>
<property name="qnameDAO">
<ref bean="qnameDAO" />
</property>
<property name="qnameBefore">
<value>{http://www.alfresco.org/model/content/1.0}thumbnails</value>
</property>
<property name="qnameAfter">
<value>{http://www.alfresco.org/model/rendition/1.0}rendition</value>
</property>
<!-- This patch is of an association type QName and so no reindexing is necessary.
However, if we wanted to reindex the QName that we'd changed we could do it like so
<property name="reindexClass">
<value>TYPE</value>
or
<value>ASPECT</value>
</property>
-->
</bean>
<bean id="patch.emailInviteAndNotifyTemplatesFolder" class="org.alfresco.repo.admin.patch.impl.EmailTemplatesInviteAndNotifyFoldersPatch" parent="basePatch" >
<bean id="patch.emailInviteAndNotifyTemplatesFolder" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.emailInviteAndNotifyTemplatesFolder</value></property>
<property name="description"><value>patch.emailInviteAndNotifyTemplatesFolder.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4006</value></property>
<property name="targetSchema"><value>4007</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
<property name="importerBootstrap">
<ref bean="spacesBootstrap" />
</property>
<property name="messageSource">
<ref bean="bootstrapSpacesMessageSource" />
</property>
</bean>
<bean id="patch.transferServiceFolder" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
<bean id="patch.transferServiceFolder" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch" >
<property name="id"><value>patch.transferServiceFolder</value></property>
<property name="description"><value>patch.transferDefinitions.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4008</value></property>
<property name="targetSchema"><value>4009</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
</property>
<property name="importerBootstrap">
<ref bean="spacesBootstrap" />
</property>
<property name="checkPath">
<value>/${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.transfers.childname}</value>
</property>
<property name="bootstrapView">
<props>
<prop key="path">/${spaces.company_home.childname}/${spaces.dictionary.childname}</prop>
<prop key="location">alfresco/bootstrap/transferSpaces.xml</prop>
<prop key="messages">alfresco/messages/bootstrap-spaces</prop>
</props>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.convertContentUrls" class="org.alfresco.repo.admin.patch.impl.ContentUrlConverterPatch" parent="basePatch">
<bean id="patch.convertContentUrls" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.convertContentUrls</value></property>
<property name="description"><value>patch.convertContentUrls.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4007</value></property>
<property name="targetSchema"><value>4008</value></property>
<property name="applyToTenants"><value>false</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
<property name="registryService" ref="registryService"/>
<property name="jobLockService" ref="jobLockService"/>
<property name="patchDAO" ref="patchDAO"/>
<property name="controlDAO" ref="controlDAO"/>
<property name="contentDataDAO" ref="contentDataDAO"/>
<property name="contentStore" ref="fileContentStore"/>
<property name="threadCount" value="${system.content.contentUrlConverter.threadCount}" />
<property name="batchSize" value="${system.content.contentUrlConverter.batchSize}" />
<property name="runAsScheduledJob" value="${system.content.contentUrlConverter.runAsScheduledJob}" />
</bean>
<bean id="patch.db-V3.4-authority-unique-idx" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
@@ -1399,36 +1195,34 @@
</property>
</bean>
<bean id="patch.db-V3.3-modify-index-permission_id" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.3-modify-index-permission_id" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.3-modify-index-permission_id</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4102</value></property>
<property name="targetSchema"><value>4103</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/modify-index-permission_id.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.2-AddFKIndexes" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.2-AddFKIndexes" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-AddFKIndexes</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>3007</value></property>
<property name="fixesToSchema"><value>4103</value></property>
<property name="targetSchema"><value>4104</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/2.2/${db.script.dialect}/AddFKIndexes.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
<bean id="patch.db-V3.3-Fix-Repo-Seqs" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.3-Fix-Repo-Seqs" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.3-Fix-Repo-Seqs</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4104</value></property>
<property name="targetSchema"><value>4105</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/fix-Repo-seqs.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
@@ -1480,14 +1274,14 @@
</property>
</bean>
<bean id="patch.db-V3.3-Node-Prop-Serializable" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.3-Node-Prop-Serializable" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.3-Node-Prop-Serializable</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4105</value></property>
<property name="targetSchema"><value>4106</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/3.3/${db.script.dialect}/node-prop-serializable.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
@@ -1564,25 +1358,6 @@
<property name="fixesToSchema"><value>4106</value></property>
<property name="targetSchema"><value>4107</value></property>
</bean>
<bean id="patch.migrateAttrDropOldTables" class="org.alfresco.repo.admin.patch.impl.MigrateAttrDropOldTablesPatch" parent="basePatch">
<property name="id"><value>patch.migrateAttrDropOldTables</value></property>
<property name="description"><value>patch.migrateAttrDropOldTables.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>5006</value></property>
<property name="targetSchema"><value>5007</value></property>
<property name="applyToTenants"><value>false</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.migrateAttrTenants"/>
<ref bean="patch.migrateAttrPropBackedBeans"/>
<ref bean="patch.migrateAttrChainingURS"/>
</list>
</property>
<property name="patchDAO">
<ref bean="patchDAO"/>
</property>
</bean>
<bean id="patch.replication.replication_actions" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
<property name="id"><value>patch.replication.replication_actions</value></property>
<property name="description"><value>patch.replication.replication_actions.description</value></property>
@@ -1725,14 +1500,14 @@
</property>
</bean>
<bean id="patch.db-V3.2-AddFKIndexes-2" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<bean id="patch.db-V3.2-AddFKIndexes-2" class="org.alfresco.repo.admin.patch.impl.NoLongerSupportedPatch" parent="basePatch">
<property name="id"><value>patch.db-V3.2-AddFKIndexes-2</value></property>
<property name="description"><value>patch.schemaUpgradeScript.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4111</value></property>
<property name="targetSchema"><value>4112</value></property>
<property name="scriptUrl">
<value>classpath:alfresco/dbscripts/upgrade/3.2/${db.script.dialect}/AlfrescoSchemaUpdate-3.2-AddFKIndexes-2.sql</value>
<property name="lastSupportedVersion" >
<value>4.2.x</value>
</property>
</bean>
@@ -1740,6 +1515,28 @@
<!--====== LIVE PATCHES =======-->
<!--===========================-->
<bean id="patch.redeployJbpmAdhocWorkflow" class="org.alfresco.repo.admin.patch.impl.GenericWorkflowPatch" parent="baseWorkflowPatch" >
<property name="id"><value>patch.redeployJbpmAdhocWorkflow</value></property>
<property name="description"><value>patch.redeployJbpmAdhocWorkflow.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>4204</value></property>
<property name="targetSchema"><value>4205</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.updateDmPermissions" />
</list>
</property>
<property name="workflowDefinitions">
<list>
<props>
<prop key="engineId">jbpm</prop>
<prop key="location">alfresco/workflow/adhoc_processdefinition.xml</prop>
<prop key="mimetype">text/xml</prop>
</props>
</list>
</property>
</bean>
<!-- Used to bootstrap imapSpacesLocales Prior to share/alfresco split of 3.5 -->
<bean id="patch.imapSpacesLocaleTemplates" class="org.alfresco.repo.admin.patch.impl.NoOpPatch" parent="basePatch">
<property name="id"><value>patch.imapSpacesLocaleTemplates</value></property>
@@ -2023,6 +1820,25 @@
</property>
</bean>
<bean id="patch.migrateAttrDropOldTables" class="org.alfresco.repo.admin.patch.impl.MigrateAttrDropOldTablesPatch" parent="basePatch">
<property name="id"><value>patch.migrateAttrDropOldTables</value></property>
<property name="description"><value>patch.migrateAttrDropOldTables.description</value></property>
<property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>5006</value></property>
<property name="targetSchema"><value>5007</value></property>
<property name="applyToTenants"><value>false</value></property>
<property name="dependsOn" >
<list>
<ref bean="patch.migrateAttrTenants"/>
<ref bean="patch.migrateAttrPropBackedBeans"/>
<ref bean="patch.migrateAttrChainingURS"/>
</list>
</property>
<property name="patchDAO">
<ref bean="patchDAO"/>
</property>
</bean>
<bean id="patch.db-V4.0-AclChangeSet" class="org.alfresco.repo.admin.patch.impl.SchemaUpgradeScriptPatch" parent="basePatch">
<property name="id" value="patch.db-V4.0-AclChangeSet" />
<property name="description" value="patch.schemaUpgradeScript.description" />

View File

@@ -257,12 +257,6 @@ system.content.orphanProtectDays=14
system.content.deletionFailureAction=IGNORE
# The CRON expression to trigger the deletion of resources associated with orphaned content.
system.content.orphanCleanup.cronExpression=0 0 4 * * ?
# The CRON expression to trigger content URL conversion. This process is not intesive and can
# be triggered on a live system. Similarly, it can be triggered using JMX on a dedicated machine.
system.content.contentUrlConverter.cronExpression=* * * * * ? 2099
system.content.contentUrlConverter.threadCount=2
system.content.contentUrlConverter.batchSize=500
system.content.contentUrlConverter.runAsScheduledJob=false
# #################### #
# Lucene configuration #

View File

@@ -93,33 +93,6 @@
</property>
</bean>
<bean id="contentUrlConverterJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>org.alfresco.repo.admin.patch.impl.ContentUrlConverterPatch$ContentUrlConverterJob</value>
</property>
<property name="jobDataAsMap">
<map>
<entry key="contentUrlConverter">
<ref bean="patch.convertContentUrls" />
</entry>
</map>
</property>
</bean>
<bean id="contentUrlConverterTrigger" class="org.alfresco.util.CronTriggerBean">
<property name="jobDetail">
<ref bean="contentUrlConverterJobDetail" />
</property>
<property name="scheduler">
<ref bean="schedulerFactory" />
</property>
<property name="cronExpression">
<value>${system.content.contentUrlConverter.cronExpression}</value>
</property>
<property name="startDelayMinutes">
<value>${system.cronJob.startDelayMinutes}</value>
</property>
</bean>
<bean id="patchSharedFolderJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass">
<value>org.alfresco.repo.admin.patch.impl.SharedFolderPatch$SharedFolderPatchJob</value>

View File

@@ -1,203 +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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.admin.patch.PatchExecuter;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Patch to assign users and groups to default zones
*
* @author andyh
*/
public class AuthorityDefaultZonesPatch extends AbstractPatch
{
/** Success message. */
private static final String MSG_SUCCESS = "patch.authorityDefaultZonesPatch.result";
private static final String MSG_UPDATE_USERS = "patch.authorityDefaultZonesPatch.users";
private static final String MSG_UPDATE_GROUPS = "patch.authorityDefaultZonesPatch.groups";
private static Log progress_logger = LogFactory.getLog(PatchExecuter.class);
/** The authority service. */
private AuthorityService authorityService;
private SiteService siteService;
/**
* Sets the authority service.
*
* @param authorityService
* the authority service
*/
public void setAuthorityService(AuthorityService authorityService)
{
this.authorityService = authorityService;
}
/**
* Set the site service
*/
public void setSiteService(SiteService siteService)
{
this.siteService = siteService;
}
@Override
protected String applyInternal() throws Exception
{
int count = 0;
int total = authorityService.getAllAuthorities(AuthorityType.USER).size() + authorityService.getAllAuthorities(AuthorityType.GROUP).size();
reportProgress(total, count);
String msg = I18NUtil.getMessage(MSG_UPDATE_USERS);
progress_logger.info(msg);
count = setZonesForPeople(total, count);
msg = I18NUtil.getMessage(MSG_UPDATE_GROUPS);
progress_logger.info(msg);
setZonesForGroups(total, count);
return MSG_SUCCESS;
}
private int setZonesForPeople(int total, int start)
{
Set<String> defaultZones = new HashSet<String>(2, 1.0f);
defaultZones.add(AuthorityService.ZONE_APP_DEFAULT);
defaultZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
List<Action> personActions = new ArrayList<Action>(1);
personActions.add(new Action(null, defaultZones, ActionType.SET));
return setZones(AuthorityType.USER, personActions, total, start);
}
private int setZonesForGroups(int total, int start)
{
Set<String> defaultZones = new HashSet<String>(2, 1.0f);
defaultZones.add(AuthorityService.ZONE_APP_DEFAULT);
defaultZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
Set<String> shareZones = new HashSet<String>(2, 1.0f);
shareZones.add(AuthorityService.ZONE_APP_SHARE);
shareZones.add(AuthorityService.ZONE_AUTH_ALFRESCO);
List<SiteInfo> sites = siteService.listSites(null, null);
List<Action> groupActions = new ArrayList<Action>(sites.size() * 5 + 1);
for (SiteInfo site : sites)
{
groupActions.add(new Action("GROUP_site_" + site.getShortName(), shareZones, ActionType.SET));
groupActions.add(new Action("GROUP_site_" + site.getShortName()+"_SiteManager", shareZones, ActionType.SET));
groupActions.add(new Action("GROUP_site_" + site.getShortName()+"_SiteCollaborator", shareZones, ActionType.SET));
groupActions.add(new Action("GROUP_site_" + site.getShortName()+"_SiteContributor", shareZones, ActionType.SET));
groupActions.add(new Action("GROUP_site_" + site.getShortName()+"_SiteConsumer", shareZones, ActionType.SET));
}
groupActions.add(new Action(null, defaultZones, ActionType.SET));
return setZones(AuthorityType.GROUP, groupActions, total, start);
}
private int setZones(AuthorityType authorityType, List<Action> actions, int total, int start)
{
int count = start;
Set<String> authorities = authorityService.getAllAuthorities(authorityType);
for (String authority : authorities)
{
for (Action action : actions)
{
if (action.name != null)
{
if (action.name.equals(authority))
{
fixAuthority(action.actionType, action.zones, authority);
break;
}
}
else
{
fixAuthority(action.actionType, action.zones, authority);
break;
}
}
count++;
reportProgress(total, count);
}
return count;
}
private void fixAuthority(ActionType actionType, Set<String> zones, String authority)
{
Set<String> current;
switch (actionType)
{
case ADD:
authorityService.addAuthorityToZones(authority, zones);
break;
case SET:
current = authorityService.getAuthorityZones(authority);
authorityService.removeAuthorityFromZones(authority, current);
authorityService.addAuthorityToZones(authority, zones);
break;
case SET_IF_UNSET:
current = authorityService.getAuthorityZones(authority);
if (current.size() == 0)
{
authorityService.addAuthorityToZones(authority, zones);
}
break;
}
}
private enum ActionType
{
ADD, SET, SET_IF_UNSET;
}
private static class Action
{
String name;
Set<String> zones;
ActionType actionType;
Action(String name, Set<String> zones, ActionType actionType)
{
this.name = name;
this.zones = zones;
this.actionType = actionType;
}
}
}

View File

@@ -1,477 +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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.admin.patch.PatchExecuter;
import org.alfresco.repo.batch.BatchProcessor;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authority.UnknownAuthorityException;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Migrates authority information previously stored in the user store to the spaces store, using the new structure used
* by AuthorityService.
*
* @author dward
*/
public class AuthorityMigrationPatch extends AbstractPatch
{
/** The title we give to the batch process in progress messages / JMX. */
private static final String MSG_PROCESS_NAME = "patch.authorityMigration.process.name";
/** The warning message when a 'dangling' assoc is found that can't be created */
private static final String MSG_WARNING_INVALID_ASSOC = "patch.authorityMigration.warning.assoc";
/** Success message. */
private static final String MSG_SUCCESS = "patch.authorityMigration.result";
/** The progress_logger. */
private static Log progress_logger = LogFactory.getLog(PatchExecuter.class);
/** The old authority name property. */
private static final QName PROP_AUTHORITY_NAME = QName.createQName(ContentModel.USER_MODEL_URI, "authorityName");
/** The old authority display name property. */
private static final QName PROP_AUTHORITY_DISPLAY_NAME = QName.createQName(ContentModel.USER_MODEL_URI,
"authorityDisplayName");
/** The old authority members property. */
private static final QName PROP_MEMBERS = QName.createQName(ContentModel.USER_MODEL_URI, "members");
/** The authority service. */
private AuthorityService authorityService;
/** The rule service. */
private RuleService ruleService;
/** The user bootstrap. */
private ImporterBootstrap userBootstrap;
/**
* Sets the authority service.
*
* @param authorityService
* the authority service
*/
public void setAuthorityService(AuthorityService authorityService)
{
this.authorityService = authorityService;
}
/**
* Sets the rule service.
*
* @param ruleService
* the rule service
*/
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
/**
* Sets the user bootstrap.
*
* @param userBootstrap
* the user bootstrap
*/
public void setUserBootstrap(ImporterBootstrap userBootstrap)
{
this.userBootstrap = userBootstrap;
}
/**
* Recursively retrieves the authorities under the given node and their associations.
*
* @param parentAuthority
* the full name of the parent authority corresponding to the given node, or <code>null</code> if it is
* not an authority node.
* @param nodeRef
* the node to find authorities below
* @param authoritiesToCreate
* the authorities to create
* @param parentAssocs
* the parent associations
* @return count of the number of parent associations
*/
private int retrieveAuthorities(String parentAuthority, NodeRef nodeRef, Map<String, String> authoritiesToCreate,
Map<String, Set<String>> parentAssocs)
{
int assocCount = 0;
// Process all children
List<ChildAssociationRef> cars = this.nodeService.getChildAssocs(nodeRef);
for (ChildAssociationRef car : cars)
{
NodeRef current = car.getChildRef();
// Record an authority to create
String authorityName = DefaultTypeConverter.INSTANCE.convert(String.class, this.nodeService.getProperty(
current, AuthorityMigrationPatch.PROP_AUTHORITY_NAME));
authoritiesToCreate.put(authorityName, DefaultTypeConverter.INSTANCE.convert(String.class, this.nodeService
.getProperty(current, AuthorityMigrationPatch.PROP_AUTHORITY_DISPLAY_NAME)));
// Record the parent association (or empty set if this is a root)
Set<String> parents = parentAssocs.get(authorityName);
if (parents == null)
{
parents = new TreeSet<String>();
parentAssocs.put(authorityName, parents);
}
if (parentAuthority != null)
{
parents.add(parentAuthority);
assocCount++;
}
// loop over properties
Collection<String> members = DefaultTypeConverter.INSTANCE.getCollection(String.class, this.nodeService
.getProperty(current, AuthorityMigrationPatch.PROP_MEMBERS));
if (members != null)
{
String tenantDomain = null;
if (tenantAdminService.isEnabled())
{
tenantDomain = tenantAdminService.getCurrentUserDomain();
}
for (String user : members)
{
// Believe it or not, some old authorities have null members in them!
if (user != null)
{
if ((tenantDomain != null) && (! (tenantDomain.equals(TenantService.DEFAULT_DOMAIN))))
{
if (tenantAdminService.getUserDomain(user).equals(TenantService.DEFAULT_DOMAIN))
{
if (user.equals(tenantAdminService.getBaseNameUser(AuthenticationUtil.getAdminUserName())))
{
// MT: workaround for CHK-11393 (eg. EMAIL_CONTRIBUTORS with member "admin" instead of "admin@tenant")
user = tenantAdminService.getDomainUser(user, tenantDomain);
}
}
}
Set<String> propParents = parentAssocs.get(user);
if (propParents == null)
{
propParents = new TreeSet<String>();
parentAssocs.put(user, propParents);
}
propParents.add(authorityName);
assocCount++;
}
}
}
assocCount += retrieveAuthorities(authorityName, current, authoritiesToCreate, parentAssocs);
}
return assocCount;
}
/**
* Truncates authority names so that they are within {@link QName#MAX_LENGTH} characters.
*
* @param authoritiesToCreate
* the original, untruncated authorities to create
* @param parentAssocs
* the original parent associations to create
* @param targetAuthoritiesToCreate
* the authorities to create with names shortened to QName.MAX_LENGTH
* @param targetParentAssocs
* the parent associations modified to match targetAuthoritiesToCreate
*/
private void truncateAuthorities(final Map<String, String> authoritiesToCreate,
Map<String, Set<String>> parentAssocs, Map<String, String> targetAuthoritiesToCreate,
Map<String, Set<String>> targetParentAssocs)
{
// Work through each authority, creating a unique truncated name where necessary and populating a map of old to
// new names
Map<String, String> targetLookup = new TreeMap<String, String>();
for (Map.Entry<String, String> entry : authoritiesToCreate.entrySet())
{
String sourceName = entry.getKey();
int sourceLength = sourceName.length();
String targetName = sourceLength > QName.MAX_LENGTH ? sourceName.substring(0, QName.MAX_LENGTH) : sourceName;
int i=0;
while (targetAuthoritiesToCreate.containsKey(targetName))
{
String suffix = String.valueOf(++i);
int prefixLength = QName.MAX_LENGTH - suffix.length();
if (prefixLength < 0)
{
break;
}
targetName = (sourceLength > prefixLength ? sourceName.substring(0, prefixLength) : sourceName) + suffix;
}
targetLookup.put(sourceName, targetName);
targetAuthoritiesToCreate.put(targetName, entry.getValue());
}
// Apply the name mapping to the parent associations
for (Map.Entry<String, Set<String>> entry: parentAssocs.entrySet())
{
Set<String> parents = new TreeSet<String>();
for (String parent : entry.getValue())
{
String targetParent = targetLookup.get(parent);
parents.add(targetParent == null ? parent : targetParent);
}
String sourceChild = entry.getKey();
String targetChild = targetLookup.get(sourceChild);
targetParentAssocs.put(targetChild == null ? sourceChild : targetChild, parents);
}
}
/**
* Migrates the authorities and their associations.
*
* @param authoritiesToCreate
* the authorities to create
* @param parentAssocs
* the parent associations to create (if they don't exist already)
* @return the number of authorities migrated
*/
private void migrateAuthorities(final Map<String, String> authoritiesToCreate, Map<String, Set<String>> parentAssocs)
{
final String tenantDomain = tenantAdminService.getCurrentUserDomain();
BatchProcessor.BatchProcessWorker<Map.Entry<String, Set<String>>> worker = new BatchProcessor.BatchProcessWorker<Map.Entry<String, Set<String>>>()
{
public String getIdentifier(Entry<String, Set<String>> entry)
{
return entry.getKey();
}
public void beforeProcess() throws Throwable
{
// Disable rules
ruleService.disableRules();
// Authentication
// TODO tenant switch
String tenantSystemUser = tenantAdminService.getDomainUser(AuthenticationUtil.getSystemUserName(), tenantDomain);
AuthenticationUtil.setRunAsUser(tenantSystemUser);
}
public void afterProcess() throws Throwable
{
// Enable rules
ruleService.enableRules();
// Clear authentication
AuthenticationUtil.clearCurrentSecurityContext();
}
public void process(Entry<String, Set<String>> authority) throws Throwable
{
String authorityName = authority.getKey();
boolean existed = AuthorityMigrationPatch.this.authorityService.authorityExists(authorityName);
Set<String> knownParents;
if (existed)
{
knownParents = AuthorityMigrationPatch.this.authorityService.getContainingAuthorities(
AuthorityType.GROUP, authorityName, true);
}
else
{
knownParents = Collections.emptySet();
AuthorityType authorityType = AuthorityType.getAuthorityType(authorityName);
// We have associations to a non-existent authority. If it is a user, just skip it because it must
// have been a 'dangling' reference
if (authorityType == AuthorityType.USER)
{
AuthorityMigrationPatch.progress_logger.warn(I18NUtil.getMessage(
AuthorityMigrationPatch.MSG_WARNING_INVALID_ASSOC, authorityName));
return;
}
AuthorityMigrationPatch.this.authorityService.createAuthority(authorityType,
AuthorityMigrationPatch.this.authorityService.getShortName(authorityName),
authoritiesToCreate.get(authorityName), null);
}
Set<String> parentAssocsToCreate = authority.getValue();
parentAssocsToCreate.removeAll(knownParents);
if (!parentAssocsToCreate.isEmpty())
{
try
{
AuthorityMigrationPatch.this.authorityService.addAuthority(parentAssocsToCreate, authorityName);
}
catch (UnknownAuthorityException e)
{
// Let's force a transaction retry if a parent doesn't exist. It may be because we are
// waiting for another worker thread to create it
throw new ConcurrencyFailureException("Forcing batch retry for unknown authority", e);
}
catch (InvalidNodeRefException e)
{
// Another thread may have written the node, but it is not visible to this transaction
// See: ALF-5471: 'authorityMigration' patch can report 'Node does not exist'
throw new ConcurrencyFailureException("Forcing batch retry for invalid node", e);
}
}
}
};
// Migrate using 2 threads, 20 authorities per transaction. Log every 100 entries.
new BatchProcessor<Map.Entry<String, Set<String>>>(
I18NUtil.getMessage(AuthorityMigrationPatch.MSG_PROCESS_NAME),
transactionHelper,
parentAssocs.entrySet(),
2, 20,
AuthorityMigrationPatch.this.applicationEventPublisher,
AuthorityMigrationPatch.progress_logger, 100).process(worker, true);
}
/**
* Gets the old authority container.
*
* @return the old authority container or <code>null</code> if not found
*/
private NodeRef getAuthorityContainer()
{
NodeRef rootNodeRef = this.nodeService.getRootNode(this.userBootstrap.getStoreRef());
QName qnameAssocSystem = QName.createQName("sys", "system", this.namespaceService);
List<ChildAssociationRef> results = this.nodeService.getChildAssocs(rootNodeRef, RegexQNamePattern.MATCH_ALL,
qnameAssocSystem);
NodeRef sysNodeRef = null;
if (results.size() == 0)
{
return null;
}
else
{
sysNodeRef = results.get(0).getChildRef();
}
QName qnameAssocAuthorities = QName.createQName("sys", "authorities", this.namespaceService);
results = this.nodeService.getChildAssocs(sysNodeRef, RegexQNamePattern.MATCH_ALL, qnameAssocAuthorities);
NodeRef authNodeRef = null;
if (results.size() == 0)
{
return null;
}
else
{
authNodeRef = results.get(0).getChildRef();
}
return authNodeRef;
}
/**
* TODO: The walking of the group associations should be wrapped up in a BatchProcessWorkProvider, if possible
*/
@Override
protected String applyInternal() throws Exception
{
NodeRef authorityContainer = getAuthorityContainer();
int authorities = 0, assocs = 0;
if (authorityContainer != null)
{
// Crawl the old tree of authorities
Map<String, String> authoritiesToCreate = new TreeMap<String, String>();
Map<String, Set<String>> parentAssocs = new TreeMap<String, Set<String>>();
assocs = retrieveAuthorities(null, authorityContainer, authoritiesToCreate, parentAssocs);
// Truncate names to an acceptable length
Map<String, String> targetAuthoritiesToCreate = new TreeMap<String, String>();
Map<String, Set<String>> targetParentAssocs = new TreeMap<String, Set<String>>();
truncateAuthorities(authoritiesToCreate, parentAssocs, targetAuthoritiesToCreate, targetParentAssocs);
// Sort the group associations in parent-first order (root groups first)
Map<String, Set<String>> sortedParentAssocs = new LinkedHashMap<String, Set<String>>(
parentAssocs.size() * 2);
List<String> authorityPath = new ArrayList<String>(5);
for (String authority : targetParentAssocs.keySet())
{
authorityPath.add(authority);
visitGroupAssociations(authorityPath, targetParentAssocs, sortedParentAssocs);
authorityPath.clear();
}
// Recreate the authorities and their associations in parent-first order
migrateAuthorities(targetAuthoritiesToCreate, sortedParentAssocs);
authorities = authoritiesToCreate.size();
}
// build the result message
return I18NUtil.getMessage(AuthorityMigrationPatch.MSG_SUCCESS, authorities, assocs);
}
/**
* Visits the last authority in the given list by recursively visiting its parents in associationsOld and then
* adding the authority to associationsNew. Used to sort associationsOld into 'parent-first' order.
*
* @param authorityPath
* The authority to visit, preceeded by all its descendants. Allows detection of cyclic child
* associations.
* @param associationsOld
* the association map to sort
* @param associationsNew
* the association map to add to in parent-first order
*/
private static void visitGroupAssociations(List<String> authorityPath, Map<String, Set<String>> associationsOld,
Map<String, Set<String>> associationsNew)
{
String authorityName = authorityPath.get(authorityPath.size() - 1);
if (!associationsNew.containsKey(authorityName))
{
Set<String> associations = associationsOld.get(authorityName);
if (!associations.isEmpty())
{
int insertIndex = authorityPath.size();
for (String parentAuthority : associations)
{
// Prevent cyclic paths
if (!authorityPath.contains(parentAuthority))
{
authorityPath.add(parentAuthority);
visitGroupAssociations(authorityPath, associationsOld, associationsNew);
authorityPath.remove(insertIndex);
}
}
}
associationsNew.put(authorityName, associations);
}
}
}

View File

@@ -1,602 +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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.sql.Savepoint;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.admin.patch.PatchExecuter;
import org.alfresco.repo.admin.registry.RegistryKey;
import org.alfresco.repo.admin.registry.RegistryService;
import org.alfresco.repo.batch.BatchProcessor;
import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorkerAdaptor;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.ContentStore.ContentUrlHandler;
import org.alfresco.repo.domain.contentdata.ContentDataDAO;
import org.alfresco.repo.domain.control.ControlDAO;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.lock.JobLockService;
import org.alfresco.repo.lock.JobLockService.JobLockRefreshCallback;
import org.alfresco.repo.lock.LockAcquisitionException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair;
import org.alfresco.util.PropertyCheck;
import org.alfresco.util.VmShutdownListener;
import org.alfresco.util.VmShutdownListener.VmShutdownException;
import org.apache.commons.lang.mutable.MutableInt;
import org.apache.commons.lang.mutable.MutableLong;
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.dao.DataIntegrityViolationException;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Component to migrate old-style content URL storage (<tt>contentUrl=store://...|mimetype=...</tt>)
* to the newer <b>alf_content_url</b> storage.
* <p/>
* The {@link ServiceRegistry} is used to record progress. The component picks up ranges of node IDs
* (DM) and records the progress. Since new nodes will not need converting, the converter
* will stop once it hits the largest node ID that it found upon first initiation. Once completed,
* the content store reader will start to pick up orphaned content and schedule it for deletion.
* <p/>
* A cluster-wide lock is set so that a single instance of this job will be running per Alfresco
* installation.
*
* @author Derek Hulley
* @since 3.2.1
*/
public class ContentUrlConverterPatch extends AbstractPatch
{
// Registry keys
private static final RegistryKey KEY_ADM_MAX_ID = new RegistryKey(
NamespaceService.SYSTEM_MODEL_1_0_URI, "ContentUrlConverter", "adm", "max-id");
private static final RegistryKey KEY_ADM_RANGE_START_ID = new RegistryKey(
NamespaceService.SYSTEM_MODEL_1_0_URI, "ContentUrlConverter", "adm", "range-start-id");
private static final RegistryKey KEY_ADM_DONE = new RegistryKey(
NamespaceService.SYSTEM_MODEL_1_0_URI, "ContentUrlConverter", "adm", "done");
private static final RegistryKey KEY_STORE_DONE = new RegistryKey(
NamespaceService.SYSTEM_MODEL_1_0_URI, "ContentUrlConverter", "store", "done");
// Lock key
private static final QName LOCK = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "ContentUrlConverter");
// Lock as per patching
private static Log logger = LogFactory.getLog(PatchExecuter.class);
private RegistryService registryService;
private JobLockService jobLockService;
private PatchDAO patchDAO;
private ControlDAO controlDAO;
private ContentStore contentStore;
private ContentDataDAO contentDataDAO;
private int threadCount;
private int batchSize;
private boolean runAsScheduledJob;
private ThreadLocal<Boolean> runningAsJob = new ThreadLocal<Boolean>();
/**
* Default constructor
*/
public ContentUrlConverterPatch()
{
runningAsJob.set(Boolean.FALSE);
threadCount = 2;
batchSize=500;
}
/**
* Service to record progress for later pick-up
*/
public void setRegistryService(RegistryService registryService)
{
this.registryService = registryService;
}
/**
* Service to prevent concurrent execution
*/
public void setJobLockService(JobLockService jobLockService)
{
this.jobLockService = jobLockService;
}
/**
* Component that provides low-level queries and updates to support this patch
*/
public void setPatchDAO(PatchDAO patchDAO)
{
this.patchDAO = patchDAO;
}
/**
* Component that provides low-level database-specific control to support the patch
*/
public void setControlDAO(ControlDAO controlDAO)
{
this.controlDAO = controlDAO;
}
/**
* Set the store containing the content URLs to lift for potential cleaning.
*
* @param contentStore the store containing the system's content URLs
*/
public void setContentStore(ContentStore contentStore)
{
this.contentStore = contentStore;
}
/**
* Set the component that will write URLs coming from the
* {@link ContentStore#getUrls(ContentUrlHandler) content store}.
*
* @param contentDataDAO the DAO to write the URLs
*/
public void setContentDataDAO(ContentDataDAO contentDataDAO)
{
this.contentDataDAO = contentDataDAO;
}
/**
* Set the number of threads that will be used process the required work.
*
* @param threadCount the number of threads
*/
public void setThreadCount(int threadCount)
{
this.threadCount = threadCount;
}
/**
* Set the number of URLs that are processed per job pass; this property is ignored
* when this component is run as a patch. Keep the number low (500) when running
* at short intervals on a on a live machine.
*
* @param batchSize the number of nodes to process per batch when running on a schedule
*/
public void setBatchSize(int batchSize)
{
this.batchSize = batchSize;
}
/**
* Set whether the patch execution should just bypass any actual work i.e. the admin has
* chosen to manually trigger the work.
*
* @param runAsScheduledJob <tt>true</tt> to leave all work up to the scheduled job
*/
public void setRunAsScheduledJob(boolean runAsScheduledJob)
{
this.runAsScheduledJob = runAsScheduledJob;
}
@Override
protected void checkProperties()
{
PropertyCheck.mandatory(this, "registryService", registryService);
PropertyCheck.mandatory(this, "jobLockService", jobLockService);
PropertyCheck.mandatory(this, "patchDAO", patchDAO);
super.checkProperties();
}
/**
* Method called when executed as a scheduled job.
*/
private void executeViaJob()
{
AuthenticationUtil.RunAsWork<String> patchRunAs = new AuthenticationUtil.RunAsWork<String>()
{
public String doWork() throws Exception
{
RetryingTransactionCallback<String> patchTxn = new RetryingTransactionCallback<String>()
{
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. If kicked off via a job,
* the task will exit before completion, on the assumption that it will be kicked off at regular
* intervals. When called as a patch, it will run to completion with full progress logging.
*/
@Override
protected String applyInternal() throws Exception
{
if (AlfrescoTransactionSupport.getTransactionReadState() != TxnReadState.TXN_READ_WRITE)
{
// Nothing to do
return null;
}
boolean isRunningAsJob = runningAsJob.get().booleanValue();
// Do we bug out of patch execution
if (runAsScheduledJob && !isRunningAsJob)
{
return I18NUtil.getMessage("patch.convertContentUrls.bypassingPatch");
}
// Lock in proportion to the batch size (0.1s per node or 0.8 min per 500)
String lockToken = getLock(batchSize*100L);
if (lockToken == null)
{
// Some other process is busy
if (isRunningAsJob)
{
// Fine, we're doing batches
return null;
}
else
{
throw new RuntimeException("Unable to get job lock during patch execution. Only one server should perform the upgrade.");
}
}
// Use a flag to keep track of the running job
final AtomicBoolean running = new AtomicBoolean(true);
jobLockService.refreshLock(lockToken, LOCK, batchSize*100, new JobLockRefreshCallback()
{
@Override
public boolean isActive()
{
return running.get();
}
@Override
public void lockReleased()
{
running.set(false);
}
});
boolean completed = false;
try
{
logger.info(I18NUtil.getMessage("patch.convertContentUrls.start"));
logger.info(I18NUtil.getMessage("patch.convertContentUrls.adm.start"));
boolean admCompleted = applyADMLooping(running);
logger.info(I18NUtil.getMessage("patch.convertContentUrls.store.start", contentStore));
boolean urlLiftingCompleted = applyUrlLifting(running);
completed = admCompleted && urlLiftingCompleted;
}
catch (RuntimeException e)
{
logger.error(
I18NUtil.getMessage("patch.convertContentUrls.error", e.getMessage()),
e);
return I18NUtil.getMessage("patch.convertContentUrls.error", e.getMessage());
}
finally
{
// The lock will self-release if answer isActive in the negative
running.set(false);
}
if (completed)
{
return I18NUtil.getMessage("patch.convertContentUrls.done");
}
else
{
return I18NUtil.getMessage("patch.convertContentUrls.inProgress");
}
}
/**
* Attempts to get the lock. If the lock couldn't be taken, then <tt>null</tt> is returned.
*
* @return Returns the lock token or <tt>null</tt>
*/
private String getLock(long time)
{
try
{
return jobLockService.getLock(LOCK, time);
}
catch (LockAcquisitionException e)
{
return null;
}
}
private boolean applyADMLooping(final AtomicBoolean running)
{
RetryingTransactionCallback<Boolean> callback = new RetryingTransactionCallback<Boolean>()
{
public Boolean execute() throws Throwable
{
return applyADM();
}
};
boolean done = false;
while (running.get())
{
done = transactionHelper.doInTransaction(callback, false, true);
if (done)
{
break;
}
}
return done;
}
/**
* Do the DM conversion work
* @return Returns <tt>true</tt> if the work is done
*/
private boolean applyADM() throws Exception
{
Long maxId = (Long) registryService.getProperty(KEY_ADM_MAX_ID);
// Must we run at all?
Boolean done = (Boolean) registryService.getProperty(KEY_ADM_DONE);
if (done != null && done.booleanValue())
{
logger.info(I18NUtil.getMessage("patch.convertContentUrls.adm.done", maxId));
return true;
}
if (maxId == null)
{
maxId = patchDAO.getMaxAdmNodeID();
registryService.addProperty(KEY_ADM_MAX_ID, maxId);
}
Long startId = (Long) registryService.getProperty(KEY_ADM_RANGE_START_ID);
if (startId == null)
{
startId = 1L;
registryService.addProperty(KEY_ADM_RANGE_START_ID, startId);
}
// Each thread gets 10 executions i.e. we get ranges for threadCount*10 lots of work
Long endId = startId;
Collection<Pair<Long, Long>> batchProcessorWork = new ArrayList<Pair<Long,Long>>(2);
for (long i = 0; i < threadCount*10; i++)
{
endId = startId + (i+1L) * batchSize;
Pair<Long, Long> batchEntry = new Pair<Long, Long>(
startId + i * batchSize,
endId);
batchProcessorWork.add(batchEntry);
}
BatchProcessWorkerAdaptor<Pair<Long, Long>> batchProcessorWorker = new BatchProcessWorkerAdaptor<Pair<Long, Long>>()
{
public void process(Pair<Long, Long> range) throws Throwable
{
Long startId = range.getFirst();
Long endId = range.getSecond();
// Bulk-update the old content properties
patchDAO.updateAdmV31ContentProperties(startId, endId);
}
};
BatchProcessor<Pair<Long, Long>> batchProcessor = new BatchProcessor<Pair<Long, Long>>(
"ContentUrlConverter.ADM (" + maxId + ")",
transactionHelper,
batchProcessorWork, threadCount, 1,
applicationEventPublisher, null, 1);
batchProcessor.process(batchProcessorWorker, true);
if (batchProcessor.getTotalErrors() > 0)
{
// Something went wrong. We don't advance the start range so that the patch re-execution will
// start at the start of the range that failed.
throw AlfrescoRuntimeException.create("patch.convertContentUrls.error", batchProcessor.getLastError());
}
// Advance
startId = endId;
// Have we
if (startId > maxId)
{
startId = maxId + 1;
// We're past the max ID that we're interested in
done = Boolean.TRUE;
registryService.addProperty(KEY_ADM_DONE, done);
logger.info(I18NUtil.getMessage("patch.convertContentUrls.adm.done", maxId));
return true;
}
// Progress
super.reportProgress(maxId, startId);
// Move the start ID on
registryService.addProperty(KEY_ADM_RANGE_START_ID, startId);
// More to do
return false;
}
private boolean applyUrlLifting(final AtomicBoolean running) throws Exception
{
RetryingTransactionCallback<Boolean> callback = new RetryingTransactionCallback<Boolean>()
{
public Boolean execute() throws Throwable
{
return applyUrlLiftingInTxn(running);
}
};
return transactionHelper.doInTransaction(callback, false, true);
}
private boolean applyUrlLiftingInTxn(final AtomicBoolean running) throws Exception
{
// Check the store
if (!contentStore.isWriteSupported())
{
logger.info(I18NUtil.getMessage("patch.convertContentUrls.store.readOnly"));
return true;
}
Boolean admDone = (Boolean) registryService.getProperty(KEY_ADM_DONE);
if ((admDone == null || !admDone.booleanValue()))
{
logger.info(I18NUtil.getMessage("patch.convertContentUrls.store.pending"));
return false;
}
// Must we run at all?
Boolean done = (Boolean) registryService.getProperty(KEY_STORE_DONE);
if (done != null && done.booleanValue())
{
logger.info(I18NUtil.getMessage("patch.convertContentUrls.store.done"));
return true;
}
final long totalSize = contentStore.getSpaceTotal();
final MutableLong currentSize = new MutableLong(0L);
final MutableInt count = new MutableInt();
count.setValue(0);
ContentUrlHandler handler = new ContentUrlHandler()
{
private int allCount = 0;
public void handle(String contentUrl)
{
if (!running.get())
{
// Either VM shutdown or lock release. Either way, bug out.
throw new VmShutdownListener.VmShutdownException();
}
ContentReader reader = contentStore.getReader(contentUrl);
if (!reader.exists())
{
// Not there any more
return;
}
currentSize.setValue(currentSize.longValue() + reader.getSize());
// Create a savepoint
String savepointName = new Long(System.nanoTime()).toString();
Savepoint savepoint = controlDAO.createSavepoint(savepointName);
try
{
contentDataDAO.createContentUrlOrphaned(contentUrl, null);
controlDAO.releaseSavepoint(savepoint);
count.setValue(count.intValue()+1);
}
catch (DataIntegrityViolationException e)
{
// That's OK, the URL was already managed
controlDAO.rollbackToSavepoint(savepoint);
}
allCount++;
if (allCount % batchSize == 0)
{
if (totalSize < 0)
{
// Report
logger.info(I18NUtil.getMessage("patch.convertContentUrls.store.progress", allCount));
}
else
{
ContentUrlConverterPatch.super.reportProgress(totalSize, currentSize.longValue());
}
}
}
};
try
{
contentStore.getUrls(handler);
}
catch (UnsupportedOperationException e)
{
logger.info(I18NUtil.getMessage("patch.convertContentUrls.store.noSupport"));
}
catch (VmShutdownException e)
{
// We didn't manage to complete
return false;
}
// Record the completion
done = Boolean.TRUE;
registryService.addProperty(KEY_STORE_DONE, done);
// Done
logger.info(I18NUtil.getMessage("patch.convertContentUrls.store.scheduled", count.intValue(), contentStore));
return true;
}
/**
* Job to initiate the {@link ContentUrlConverterPatch}
*
* @author Derek Hulley
* @since 3.2.1
*/
public static class ContentUrlConverterJob implements Job
{
public ContentUrlConverterJob()
{
}
/**
* Calls the cleaner to do its work
*/
public void execute(JobExecutionContext context) throws JobExecutionException
{
JobDataMap jobData = context.getJobDetail().getJobDataMap();
// extract the content cleaner to use
Object contentUrlConverterObj = jobData.get("contentUrlConverter");
if (contentUrlConverterObj == null || !(contentUrlConverterObj instanceof ContentUrlConverterPatch))
{
throw new AlfrescoRuntimeException(
"'contentUrlConverter' data must contain valid 'ContentUrlConverter' reference");
}
ContentUrlConverterPatch contentUrlConverter = (ContentUrlConverterPatch) contentUrlConverterObj;
contentUrlConverter.executeViaJob();
}
}
}

View File

@@ -1,298 +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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.springframework.context.MessageSource;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Ensures that the <b>invite email templates</b> and <b>notify email templates</b> folders are present.
* <p>
* This uses the bootstrap importer to get the paths to look for. If not present,
* the required structures are created.
* <p>
*
* @author valerysh
*
*/
public class EmailTemplatesInviteAndNotifyFoldersPatch extends AbstractPatch {
public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname";
public static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname";
public static final String PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME = "spaces.templates.email.childname";
public static final String PROPERTY_EMAIL_NOTIFY_TEMPLATES_FOLDER_CHILDNAME = "spaces.templates.email.notify.childname";
public static final String PROPERTY_EMAIL_INVITE_TEMPLATES_FOLDER_CHILDNAME = "spaces.templates.email.invite1.childname";
private static final String PROPERTY_EMAIL_NOTIFY_TEMPLATES_FOLDER_NAME = "spaces.notify_templates.email.name";
private static final String PROPERTY_EMAIL_NOTIFY_TEMPLATES_FOLDER_DESCRIPTION = "spaces.notify_templates.email.description";
private static final String PROPERTY_EMAIL_INVITE_TEMPLATES_FOLDER_NAME = "spaces.invite_templates.email.name";
private static final String PROPERTY_EMAIL_INVITE_TEMPLATES_FOLDER_DESCRIPTION = "spaces.invite_templates.email.description";
private static final String SAMPLE_NOTIFY_TEMPLATE_NAME = "notify_user_email.ftl.sample";
private static final String INVITE_TEMPLATE_NAME = "invite_user_email.ftl";
private static final String MSG_EMAIL_INVITE_TEMPLATES_FOLDER_EXISTS = "patch.emailInviteTemplatesFolder.result.exists";
private static final String MSG_EMAIL_INVITE_TEMPLATES_FOLDER_CREATED = "patch.emailInviteTemplatesFolder.result.created";
private static final String MSG_EMAIL_NOTIFY_TEMPLATES_FOLDER_EXISTS = "patch.emailNotifyTemplatesFolder.result.exists";
private static final String MSG_EMAIL_NOTIFY_TEMPLATES_FOLDER_CREATED = "patch.emailNotifyTemplatesFolder.result.created";
private static final String PROPERTY_ICON = "space-icon-default";
private ImporterBootstrap importerBootstrap;
private MessageSource messageSource;
protected NodeRef emailNotifyTemplatesFolderNodeRef;
protected NodeRef emailInviteTemplatesFolderNodeRef;
protected Properties configuration;
protected NodeRef emailTemplatesFolderNodeRef;
private String emailTemplatesFolderXPath;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
public void setMessageSource(MessageSource messageSource)
{
this.messageSource = messageSource;
}
/**
* Ensure that required common properties have been set
*/
protected void checkCommonProperties() throws Exception
{
checkPropertyNotNull(importerBootstrap, "importerBootstrap");
checkPropertyNotNull(messageSource, "messageSource");
}
/**
* Extracts pertinent references and properties that are common to execution
* of this and derived patches.
*/
protected void setUp() throws Exception
{
// get the node store that we must work against
StoreRef storeRef = importerBootstrap.getStoreRef();
if (storeRef == null)
{
throw new PatchException("Bootstrap store has not been set");
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
this.configuration = importerBootstrap.getConfiguration();
// get the association names that form the path
String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME);
if (companyHomeChildName == null || companyHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present");
}
String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME);
if (dictionaryChildName == null || dictionaryChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present");
}
String emailTemplatesChildName = configuration.getProperty(PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME);
if (emailTemplatesChildName == null || emailTemplatesChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME + "' is not present");
}
String emailNotifyTemplatesChildName = configuration.getProperty(PROPERTY_EMAIL_NOTIFY_TEMPLATES_FOLDER_CHILDNAME);
if (emailNotifyTemplatesChildName == null || emailNotifyTemplatesChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_NOTIFY_TEMPLATES_FOLDER_CHILDNAME + "' is not present");
}
String emailInviteTemplatesChildName = configuration.getProperty(PROPERTY_EMAIL_INVITE_TEMPLATES_FOLDER_CHILDNAME);
if (emailInviteTemplatesChildName == null || emailInviteTemplatesChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_INVITE_TEMPLATES_FOLDER_CHILDNAME + "' is not present");
}
StringBuilder sb = new StringBuilder();
sb.append("/").append(companyHomeChildName)
.append("/").append(dictionaryChildName)
.append("/").append(emailTemplatesChildName);
emailTemplatesFolderXPath = sb.toString();
// get the email templates node
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, emailTemplatesFolderXPath, null, namespaceService, false);
if (nodeRefs.size() == 0)
{
throw new PatchException("XPath didn't return any results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + emailTemplatesFolderXPath);
}
else if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + emailTemplatesFolderXPath + "\n" +
" results: " + nodeRefs);
}
this.emailTemplatesFolderNodeRef = nodeRefs.get(0);
emailNotifyTemplatesFolderNodeRef = searchFolder(emailNotifyTemplatesChildName);
emailInviteTemplatesFolderNodeRef = searchFolder(emailInviteTemplatesChildName);
}
@Override
protected String applyInternal() throws Exception
{
// common properties must be set before we can continue
checkCommonProperties();
if (messageSource == null)
{
throw new PatchException("'messageSource' property has not been set");
}
setUp();
// create the folder if needed - output a message to describe the result
StringBuffer msg = new StringBuffer();
if (emailNotifyTemplatesFolderNodeRef == null)
{
emailNotifyTemplatesFolderNodeRef = createFolderAndMoveTemplate(PROPERTY_EMAIL_NOTIFY_TEMPLATES_FOLDER_CHILDNAME,
PROPERTY_EMAIL_NOTIFY_TEMPLATES_FOLDER_NAME,
PROPERTY_EMAIL_NOTIFY_TEMPLATES_FOLDER_DESCRIPTION,
SAMPLE_NOTIFY_TEMPLATE_NAME);
msg.append(I18NUtil.getMessage(MSG_EMAIL_NOTIFY_TEMPLATES_FOLDER_CREATED, emailNotifyTemplatesFolderNodeRef));
}
else
{
msg.append(I18NUtil.getMessage(MSG_EMAIL_NOTIFY_TEMPLATES_FOLDER_EXISTS, emailNotifyTemplatesFolderNodeRef));
}
msg.append("; ");
if (emailInviteTemplatesFolderNodeRef == null)
{
emailInviteTemplatesFolderNodeRef = createFolderAndMoveTemplate(PROPERTY_EMAIL_INVITE_TEMPLATES_FOLDER_CHILDNAME,
PROPERTY_EMAIL_INVITE_TEMPLATES_FOLDER_NAME,
PROPERTY_EMAIL_INVITE_TEMPLATES_FOLDER_DESCRIPTION,
INVITE_TEMPLATE_NAME);
msg.append(I18NUtil.getMessage(MSG_EMAIL_INVITE_TEMPLATES_FOLDER_CREATED, emailNotifyTemplatesFolderNodeRef));
}
else
{
msg.append(I18NUtil.getMessage(MSG_EMAIL_INVITE_TEMPLATES_FOLDER_EXISTS, emailNotifyTemplatesFolderNodeRef));
}
return msg.toString();
}
private NodeRef searchFolder(String xpath)
{
List<NodeRef> nodeRefs = searchService.selectNodes(emailTemplatesFolderNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" email templates node: " + emailTemplatesFolderNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
else if (nodeRefs.size() == 0)
{
// the node does not exist
return null;
}
else
{
return nodeRefs.get(0);
}
}
private NodeRef createFolderAndMoveTemplate(String folderChildName, String folderName, String folderDescription, String templateName)
{
// get required properties
String emailTemplatesChildName = configuration.getProperty(folderChildName);
if (emailTemplatesChildName == null)
{
throw new PatchException("Bootstrap property '" + folderChildName + "' is not present");
}
String emailTemplatesName = messageSource.getMessage(
folderName,
null,
I18NUtil.getLocale());
if (emailTemplatesName == null || emailTemplatesName.length() == 0)
{
throw new PatchException("Bootstrap property '" + folderName + "' is not present");
}
String emailTemplatesDescription = messageSource.getMessage(
folderDescription,
null,
I18NUtil.getLocale());
if (emailTemplatesDescription == null || emailTemplatesDescription.length() == 0)
{
throw new PatchException("Bootstrap property '" + folderDescription + "' is not present");
}
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(7);
properties.put(ContentModel.PROP_NAME, emailTemplatesName);
properties.put(ContentModel.PROP_TITLE, emailTemplatesName);
properties.put(ContentModel.PROP_DESCRIPTION, emailTemplatesDescription);
properties.put(ApplicationModel.PROP_ICON, PROPERTY_ICON);
// create the node
ChildAssociationRef childAssocRef = nodeService.createNode(
emailTemplatesFolderNodeRef,
ContentModel.ASSOC_CONTAINS,
QName.resolveToQName(namespaceService, emailTemplatesChildName),
ContentModel.TYPE_FOLDER,
properties);
NodeRef createdFolderNodeRef = childAssocRef.getChildRef();
// add the required aspects
nodeService.addAspect(createdFolderNodeRef, ApplicationModel.ASPECT_UIFACETS, null);
//move template
String xpath = emailTemplatesFolderXPath + "/cm:" + templateName;
List<NodeRef> templateNodeRefs = searchService.selectNodes(emailTemplatesFolderNodeRef, xpath, null, namespaceService, false);
for (NodeRef templateNodeRef : templateNodeRefs)
{
QName qname = nodeService.getPrimaryParent(templateNodeRef).getQName();
nodeService.moveNode(
templateNodeRef,
createdFolderNodeRef,
ContentModel.ASSOC_CHILDREN,
qname);
}
return createdFolderNodeRef;
}
}

View File

@@ -1,384 +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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.sql.Savepoint;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.alfresco.error.StackTraceUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.admin.patch.PatchExecuter;
import org.alfresco.repo.batch.BatchProcessWorkProvider;
import org.alfresco.repo.batch.BatchProcessor;
import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorker;
import org.alfresco.repo.domain.control.ControlDAO;
import org.alfresco.repo.domain.node.ChildAssocEntity;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.domain.qname.QNameDAO;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Fixes <a href=https://issues.alfresco.com/jira/browse/ETWOTWO-1133>ETWOTWO-1133</a>.
* Checks all CRC values for <b>alf_child_assoc.child_node_name_crc and alf_child_assoc.qname_crc</b>.
*
* @author Derek Hulley
* @since V2.2SP4
*/
public class FixNameCrcValuesPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.fixNameCrcValues.result";
private static final String MSG_REWRITTEN = "patch.fixNameCrcValues.fixed";
private static final String MSG_UNABLE_TO_CHANGE = "patch.fixNameCrcValues.unableToChange";
private static final String MSG_FIXING_LOCALNAME = "patch.fixNameCrcValues.fixingLocalname";
private static final String ERR_ASSOCIATION_TYPE_NOT_DEFINED = "patch.fixNameCrcValues.associationTypeNotDefined";
private static final String ERR_ASSOCIATION_TYPE_NOT_CHILD = "patch.fixNameCrcValues.associationTypeNotChild";
private PatchDAO patchDAO;
private QNameDAO qnameDAO;
private ControlDAO controlDAO;
private DictionaryService dictionaryService;
private int batchThreads = 2;
private int batchSize = 1000;
private long batchMaxQueryRange = Long.MAX_VALUE;
private int batchQuerySize = 2000;
private static Log logger = LogFactory.getLog(FixNameCrcValuesPatch.class);
private static Log progress_logger = LogFactory.getLog(PatchExecuter.class);
public FixNameCrcValuesPatch()
{
}
public void setPatchDAO(PatchDAO patchDAO)
{
this.patchDAO = patchDAO;
}
/**
* @param qnameDAO resolved QNames
*/
public void setQnameDAO(QNameDAO qnameDAO)
{
this.qnameDAO = qnameDAO;
}
/**
* @param controlDAO used to create Savepoints
*/
public void setControlDAO(ControlDAO controlDAO)
{
this.controlDAO = controlDAO;
}
/**
* @param dictionaryService used to check the child associations for unique checking
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* @param batchThreads the number of threads that will write child association changes
*/
public void setBatchThreads(int batchThreads)
{
this.batchThreads = batchThreads;
}
/**
* @param batchSize the number of child associations that will be modified per transaction
*/
public void setBatchSize(int batchSize)
{
this.batchSize = batchSize;
}
/**
* @param batchMaxQueryRange the largest ID range that the work provider can query for.
* Lower this if the distribution of ID in alf_child_assoc is not
* uniform and memory problems are encountered.
*/
public void setBatchMaxQueryRange(long batchMaxQueryRange)
{
this.batchMaxQueryRange = batchMaxQueryRange;
}
/**
* @param batchQuerySize the maximum number of results to pull back before handing off to
* the threads (usually threads * batch size)
*/
public void setBatchQuerySize(int batchQuerySize)
{
this.batchQuerySize = batchQuerySize;
}
@Override
protected void checkProperties()
{
super.checkProperties();
checkPropertyNotNull(patchDAO, "patchDAO");
checkPropertyNotNull(qnameDAO, "qnameDAO");
checkPropertyNotNull(controlDAO, "controlDAO");
checkPropertyNotNull(dictionaryService, "dictionaryService");
checkPropertyNotNull(applicationEventPublisher, "applicationEventPublisher");
}
@Override
protected String applyInternal() throws Exception
{
// initialise the helper
FixNameCrcValuesHelper helper = new FixNameCrcValuesHelper();
try
{
String msg = helper.fixCrcValues();
// done
return msg;
}
finally
{
helper.closeWriter();
}
}
private class FixNameCrcValuesHelper
{
private File logFile;
private FileChannel channel;
private Integer assocCount;
private Long minAssocId = 0L;
private Long maxAssocId;
private FixNameCrcValuesHelper() throws IOException
{
// put the log file into a long life temp directory
File tempDir = TempFileProvider.getLongLifeTempDir("patches");
logFile = new File(tempDir, "FixNameCrcValuesPatch.log");
// open the file for appending
RandomAccessFile outputFile = new RandomAccessFile(logFile, "rw");
channel = outputFile.getChannel();
// move to the end of the file
channel.position(channel.size());
// add a newline and it's ready
writeLine("").writeLine("");
writeLine("FixNameCrcValuesPatch executing on " + new Date());
}
private FixNameCrcValuesHelper write(Object obj) throws IOException
{
channel.write(ByteBuffer.wrap(obj.toString().getBytes("UTF-8")));
return this;
}
private FixNameCrcValuesHelper writeLine(Object obj) throws IOException
{
write(obj);
write("\n");
return this;
}
private void closeWriter()
{
try { channel.close(); } catch (Throwable e) {}
}
public String fixCrcValues() throws Exception
{
BatchProcessWorkProvider<Map<String, Object>> workProvider = new BatchProcessWorkProvider<Map<String,Object>>()
{
public synchronized int getTotalEstimatedWorkSize()
{
if (assocCount == null)
{
assocCount = patchDAO.getChildAssocCount();
}
return assocCount.intValue();
}
public synchronized Collection<Map<String, Object>> getNextWork()
{
if (maxAssocId == null)
{
maxAssocId = patchDAO.getMaxChildAssocId();
}
double total = (double) getTotalEstimatedWorkSize();
long rangeMultipler = Math.round(maxAssocId.doubleValue() / total);
// Get the next collection
List<Map<String, Object>> results = patchDAO.getChildAssocsForCrcFix(
minAssocId, maxAssocId, rangeMultipler, batchMaxQueryRange, batchQuerySize);
// Find out what the last ID is
int resultsSize = results.size();
if (resultsSize > 0)
{
Map<String, Object> lastResult = results.get(resultsSize - 1);
Long id = (Long) lastResult.get("id");
minAssocId = id + 1L;
}
// Hand back the results
return results;
}
};
// get the association types to check
BatchProcessor<Map<String, Object>> batchProcessor = new BatchProcessor<Map<String, Object>>(
"FixNameCrcValuesPatch",
transactionHelper,
workProvider,
batchThreads, batchSize,
applicationEventPublisher,
progress_logger, 1000);
BatchProcessWorker<Map<String, Object>> worker = new BatchProcessWorker<Map<String, Object>>()
{
public String getIdentifier(Map<String, Object> entry)
{
return entry.toString();
}
public void beforeProcess() throws Throwable
{
}
public void process(Map<String, Object> row) throws Throwable
{
Long assocId = (Long) row.get("id");
Long typeQNameId = (Long) row.get("typeQNameId");
Long qnameNamespaceId = (Long) row.get("qnameNamespaceId");
String qnameLocalName = (String) row.get("qnameLocalName");
Long childNodeNameCrc = (Long) row.get("childNodeNameCrc");
Long qnameCrc = (Long) row.get("qnameCrc");
String childNodeUuid = (String) row.get("childNodeUuid");
String childNodeName = (String) row.get("childNodeName");
// Use the UUID if there is no cm:name
childNodeName = (childNodeName == null) ? childNodeUuid : childNodeName;
// Ensure that we generate a valid QName (see comments on ALF-4529)
if (qnameLocalName == null || qnameLocalName.length() == 0)
{
String qnameLocalNameNew = "fix-" + assocId;
logger.warn(
I18NUtil.getMessage(MSG_FIXING_LOCALNAME, assocId, qnameLocalName, qnameLocalNameNew));
qnameLocalName = qnameLocalNameNew;
}
// Resolve QNames
QName typeQName = qnameDAO.getQName(typeQNameId).getSecond();
String namespace = qnameDAO.getNamespace(qnameNamespaceId).getSecond();
QName qname = QName.createQName(namespace, qnameLocalName);
ChildAssocEntity entity = new ChildAssocEntity();
entity.setChildNodeNameAll(dictionaryService, typeQName, childNodeName);
entity.setQNameAll(qnameDAO, qname, false);
Long childNodeNameCrcNew = entity.getChildNodeNameCrc();
Long qnameCrcNew = entity.getQnameCrc();
entity = null; // Just checking that we don't misuse it
AssociationDefinition assocDef = dictionaryService.getAssociation(typeQName);
if (assocDef == null)
{
throw new DictionaryException(ERR_ASSOCIATION_TYPE_NOT_DEFINED, typeQName, assocId);
}
else if (!assocDef.isChild())
{
throw new DictionaryException(ERR_ASSOCIATION_TYPE_NOT_CHILD, typeQName, assocId);
}
ChildAssociationDefinition childAssocDef = (ChildAssociationDefinition) assocDef;
boolean requiresNameConstraint = !childAssocDef.getDuplicateChildNamesAllowed();
// Check the CRC for the QName
if (qnameCrcNew.equals(qnameCrc))
{
// Check the CRC values for cm:name
// - value might have stayed the same
// - Any existing name crc negative value is fine if the name constraint need not be enforced
if (childNodeNameCrcNew.equals(childNodeNameCrc) || (childNodeNameCrc < 0 && !requiresNameConstraint))
{
// This child assoc is good
return;
}
}
Savepoint savepoint = null;
try
{
// Being here indicates that the association needs to be updated
savepoint = controlDAO.createSavepoint("FixNameCrcValuesPatch");
patchDAO.updateChildAssocCrc(assocId, childNodeNameCrcNew, qnameCrcNew);
controlDAO.releaseSavepoint(savepoint);
String msg = I18NUtil.getMessage(
MSG_REWRITTEN,
assocId,
childNodeName, childNodeNameCrc, childNodeNameCrcNew,
qname, qnameCrc, qnameCrcNew);
writeLine(msg);
}
catch (Throwable e)
{
if (savepoint != null)
{
controlDAO.rollbackToSavepoint(savepoint);
}
String msg = I18NUtil.getMessage(
MSG_UNABLE_TO_CHANGE,
assocId,
childNodeName, childNodeNameCrc, childNodeNameCrcNew,
qname, qnameCrc, qnameCrcNew,
e.getMessage());
// We just log this and add details to the message file
if (logger.isDebugEnabled())
{
logger.debug(msg, e);
}
else
{
logger.warn(msg);
}
StringBuilder sb = new StringBuilder(1024);
StackTraceUtil.buildStackTrace(msg, e.getStackTrace(), sb, 0);
writeLine(sb.toString());
}
}
public void afterProcess() throws Throwable
{
}
};
int updated = batchProcessor.process(worker, true);
String msg = I18NUtil.getMessage(MSG_SUCCESS, updated, logFile);
return msg;
}
}
}

View File

@@ -1,73 +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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil;
/**
* Patch to add person usage ('cm:sizeCurrent') property to person (if missing)
*
* @author janv
*/
public class PersonUsagePatch extends AbstractPatch
{
private static Log logger = LogFactory.getLog(PersonUsagePatch.class);
/** Success messages. */
private static final String MSG_SUCCESS1 = "patch.personUsagePatch.result1";
private static final String MSG_SUCCESS2 = "patch.personUsagePatch.result2";
private PatchDAO patchDAO;
public void setPatchDAO(PatchDAO patchDAO)
{
this.patchDAO = patchDAO;
}
@Override
protected String applyInternal() throws Exception
{
logger.info("Checking for people with missing 'cm:sizeCurrent' property ...");
int count = addPersonSizeCurrentProperty();
String msg = null;
if (count > 0)
{
logger.info("... missing 'cm:sizeCurrent' property added to "+count+" people");
msg = I18NUtil.getMessage(MSG_SUCCESS1, count);
}
else
{
logger.info("... no people were missing the 'cm:sizeCurrent' property");
msg = I18NUtil.getMessage(MSG_SUCCESS2);
}
return msg;
}
private int addPersonSizeCurrentProperty()
{
return patchDAO.addSizeCurrentProp();
}
}