mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
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:
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
||||
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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" />
|
||||
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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'
|
||||
);
|
@@ -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
|
||||
|
@@ -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" />
|
||||
|
@@ -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 #
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user