IDEMPIERE-4191 Process to migrate storage provider (FHCA-1165)

This commit is contained in:
Carlos Ruiz 2020-03-04 16:28:57 +01:00
parent a60a4a8845
commit 86a483eec8
6 changed files with 868 additions and 4 deletions

View File

@ -0,0 +1,227 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- IDEMPIERE-4191
-- Feb 28, 2020, 2:24:36 PM CET
INSERT INTO AD_Process (AD_Process_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,IsReport,Value,IsDirectPrint,Classname,AccessLevel,EntityType,Statistic_Count,Statistic_Seconds,IsBetaFunctionality,IsServerProcess,ShowHelp,CopyFromProcess,AD_Process_UU,AllowMultipleExecution) VALUES (200117,0,0,'Y',TO_DATE('2020-02-28 14:24:35','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:24:35','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Storage Provider','Migrate the storage provider for attachments, archives and/or images','N','MigrateStorageProvider','N','org.idempiere.process.MigrateStorageProvider','6','D',0,0,'N','N','Y','N','e88ade56-8e2f-4dcf-a29c-687b83ee31ed','P')
;
-- Feb 28, 2020, 2:24:49 PM CET
INSERT INTO AD_Menu (AD_Menu_ID,Name,Description,Action,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsSummary,AD_Process_ID,IsSOTrx,IsReadOnly,EntityType,IsCentrallyMaintained,AD_Menu_UU) VALUES (200173,'Migrate Storage Provider','Migrate the storage provider for attachments, archives and/or images','P',0,0,'Y',TO_DATE('2020-02-28 14:24:48','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:24:48','YYYY-MM-DD HH24:MI:SS'),100,'N',200117,'Y','N','D','Y','66ef5225-0a24-4471-abcb-9d127aa6e6f3')
;
-- Feb 28, 2020, 2:24:49 PM CET
INSERT INTO AD_TreeNodeMM (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNodeMM_UU) SELECT t.AD_Client_ID, 0, 'Y', SysDate, 100, SysDate, 100,t.AD_Tree_ID, 200173, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='MM' AND NOT EXISTS (SELECT * FROM AD_TreeNodeMM e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200173)
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=0, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=218
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=1, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=153
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=2, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=263
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=3, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=166
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=4, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=203
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=5, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=53242
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=6, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=236
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=7, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=183
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=8, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=160
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=9, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=278
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=10, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=345
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=11, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=53296
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=12, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=53014
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=13, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=53108
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=0, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=261
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=1, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=53202
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=2, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=225
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=3, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200026
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=4, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200009
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=5, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=148
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=6, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=529
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=7, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=397
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=8, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=532
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=9, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=53084
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=10, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=514
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=11, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200069
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=12, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200070
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=13, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200067
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=14, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200068
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=15, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200027
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=16, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200173
;
-- Feb 28, 2020, 2:36:57 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200287,0,0,'Y',TO_DATE('2020-02-28 14:36:56','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:36:56','YYYY-MM-DD HH24:MI:SS'),100,'Client (All)',200117,10,19,'N',10,'N','AD_AllClients_V_ID','Y','D',203119,'0e5fb109-e45c-40c6-86bd-ddb870b3c54f','N')
;
-- Feb 28, 2020, 2:41:33 PM CET
UPDATE AD_Process_Para SET DefaultValue='@SQL=SELECT CASE WHEN @#AD_Client_ID@>0 THEN @#AD_Client_ID@ ELSE -1 END', ReadOnlyLogic='@#AD_Client_ID@>0',Updated=TO_DATE('2020-02-28 14:41:33','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200287
;
-- Feb 28, 2020, 2:42:41 PM CET
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203404,0,0,'Y',TO_DATE('2020-02-28 14:41:52','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:41:52','YYYY-MM-DD HH24:MI:SS'),100,'Actual_StorageProvider_ID','Actual Storage Provider',NULL,NULL,'Actual Storage Provider','D','0cfa1388-b17c-4c16-8506-8209d566cbd9')
;
-- Feb 28, 2020, 2:43:45 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,AD_Reference_Value_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200288,0,0,'Y',TO_DATE('2020-02-28 14:43:45','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:43:45','YYYY-MM-DD HH24:MI:SS'),100,'Actual Storage Provider',200117,20,18,200023,'N',10,'N','Actual_StorageProvider_ID','Y','D',203404,'e8760265-8b93-4535-bc62-3267597b8148','N')
;
-- Feb 28, 2020, 2:44:40 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200289,0,0,'Y',TO_DATE('2020-02-28 14:44:40','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:44:40','YYYY-MM-DD HH24:MI:SS'),100,'Storage Provider',200117,30,19,'N',10,'Y','AD_StorageProvider_ID','Y','D',200238,'fcded692-5976-4c18-be93-1de330b2c0f7','N')
;
-- Feb 28, 2020, 2:45:25 PM CET
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203405,0,0,'Y',TO_DATE('2020-02-28 14:45:09','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:45:09','YYYY-MM-DD HH24:MI:SS'),100,'IsMigrateAttachment','Migrate Attachment',NULL,NULL,'Migrate Attachment','D','d8cebb40-2e30-4561-9c0c-34ce599f602f')
;
-- Feb 28, 2020, 2:45:55 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200290,0,0,'Y',TO_DATE('2020-02-28 14:45:55','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:45:55','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Attachment',200117,40,20,'N',1,'Y','N','IsMigrateAttachment','Y','D',203405,'90601452-26c5-40f4-89fe-9a3875973afa','N')
;
-- Feb 28, 2020, 2:46:10 PM CET
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203406,0,0,'Y',TO_DATE('2020-02-28 14:46:00','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:46:00','YYYY-MM-DD HH24:MI:SS'),100,'IsMigrateArchive','Migrate Archive',NULL,NULL,'Migrate Archive','D','b7080f1a-398e-4a19-9ccf-03d22aa8e605')
;
-- Feb 28, 2020, 2:46:17 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200291,0,0,'Y',TO_DATE('2020-02-28 14:46:16','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:46:16','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Archive',200117,50,20,'N',1,'Y','N','IsMigrateArchive','Y','D',203406,'a35d4b7a-2647-4ad1-a994-68b376ef696e','N')
;
-- Feb 28, 2020, 2:46:30 PM CET
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203407,0,0,'Y',TO_DATE('2020-02-28 14:46:21','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:46:21','YYYY-MM-DD HH24:MI:SS'),100,'IsMigrateImage','Migrate Image',NULL,NULL,'Migrate Image','D','da9b6551-af77-4e28-b788-bf94462cd342')
;
-- Feb 28, 2020, 2:46:33 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200292,0,0,'Y',TO_DATE('2020-02-28 14:46:33','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:46:33','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Image',200117,60,20,'N',1,'Y','N','IsMigrateImage','Y','D',203407,'1c6fb7fb-fd93-48a6-8f30-3f8912880947','N')
;
-- Feb 28, 2020, 2:47:29 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200293,0,0,'Y',TO_DATE('2020-02-28 14:47:28','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2020-02-28 14:47:28','YYYY-MM-DD HH24:MI:SS'),100,'Delete old/existing records','Otherwise records will be added',200117,70,20,'N',1,'Y','N','DeleteOld','Y','D',1669,'2de2ab75-8533-4ff6-b01b-62f660c5d7a2','N')
;
-- Feb 28, 2020, 2:49:30 PM CET
UPDATE AD_Process_Para SET Name='Delete old/existing files', Description='Delete the records from the old storage provider after moved', Help='WARNING! This option cannot be rolled back! Be cautious, take backups. If not enabled, the system administrator can/must remove manually the old files from the previous storage provider later.', IsCentrallyMaintained='N',Updated=TO_DATE('2020-02-28 14:49:30','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200293
;
-- Feb 28, 2020, 5:54:24 PM CET
UPDATE AD_Process_Para SET DisplayLogic='@AD_AllClients_V_ID:-1@=-1',Updated=TO_DATE('2020-02-28 17:54:24','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200288
;
-- Mar 4, 2020, 4:19:26 PM CET
UPDATE AD_Process SET Help='<p><span style="color:#ff0000"><b>WARNING: This process can be destructive, so please be sure that you have a backup of the database, as well as a backup of your old storage provider.</b></span></p>
<p>The process migrates files between storage providers.</p>
<ul>
<li><b>Client:</b> Optional, you can select a client to migrate, if empty it will try to migrate storage providers from all clients with the Actual Storage Provider selected below.</li>
<li><b>Actual Storage Provider:</b>&nbsp;If the client is empty, you define here the storage provider to migrate, if empty it migrates clients with the storage provider not set (this is by default DB).</li>
<li><b>Storage Provider:</b>&nbsp;The new storage provider to migrate the files.</li>
<li><b>Migrate Attachment:</b>&nbsp;Check this flag if you want to migrate the attachment files to the new storage provider.</li>
<li><b>Migrate Archive:</b>&nbsp;Check this flag if you want to migrate the attachment files to the new storage provider.</li>
<li><b>Migrate Image:</b>&nbsp;Check this flag if you want to migrate the attachment files to the new storage provider.</li>
<li><b>Delete old/existing files:</b>&nbsp;If this flag is checked, after the attachments are migrated the program tries to delete (free space) the files from the previous storage provider.&nbsp; <span style="color:#ff0000">Note that migrating from/to a DB storage provider is a destructive action that cannot be recovered, it implies deleting the old/existing files</span>.</li>
</ul>
<p>The process provides status updates when running in foreground, however as the process can take long time, it can be executed in background.&nbsp; Please note that during the migration the whole table being migrated (attachment, archive, image) is locked, so operations on these tables are not permitted.&nbsp; Because of this, it is recommended to run this process in a <b>maintenance window</b> without users logged in the system.</p>
<p>There are intermediate commits in ',Updated=TO_DATE('2020-03-04 16:19:26','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200117
;
-- Mar 4, 2020, 4:21:15 PM CET
UPDATE AD_Process_Para SET Name='Client', Description='Client/Tenant for this installation.', Help='A Client is a company or a legal entity. You cannot share data between Clients. Tenant is a synonym for Client.', AD_Reference_ID=18, AD_Reference_Value_ID=129, IsCentrallyMaintained='N',Updated=TO_DATE('2020-03-04 16:21:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200287
;
-- Mar 4, 2020, 4:23:12 PM CET
UPDATE AD_Process_Para SET AD_Reference_ID=19, AD_Reference_Value_ID=NULL,Updated=TO_DATE('2020-03-04 16:23:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200287
;
SELECT register_migration_script('202002281451_IDEMPIERE-4191.sql') FROM dual
;

View File

@ -0,0 +1,224 @@
-- IDEMPIERE-4191
-- Feb 28, 2020, 2:24:36 PM CET
INSERT INTO AD_Process (AD_Process_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,IsReport,Value,IsDirectPrint,Classname,AccessLevel,EntityType,Statistic_Count,Statistic_Seconds,IsBetaFunctionality,IsServerProcess,ShowHelp,CopyFromProcess,AD_Process_UU,AllowMultipleExecution) VALUES (200117,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:24:35','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:24:35','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Storage Provider','Migrate the storage provider for attachments, archives and/or images','N','MigrateStorageProvider','N','org.idempiere.process.MigrateStorageProvider','6','D',0,0,'N','N','Y','N','e88ade56-8e2f-4dcf-a29c-687b83ee31ed','P')
;
-- Feb 28, 2020, 2:24:49 PM CET
INSERT INTO AD_Menu (AD_Menu_ID,Name,Description,"action",AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsSummary,AD_Process_ID,IsSOTrx,IsReadOnly,EntityType,IsCentrallyMaintained,AD_Menu_UU) VALUES (200173,'Migrate Storage Provider','Migrate the storage provider for attachments, archives and/or images','P',0,0,'Y',TO_TIMESTAMP('2020-02-28 14:24:48','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:24:48','YYYY-MM-DD HH24:MI:SS'),100,'N',200117,'Y','N','D','Y','66ef5225-0a24-4471-abcb-9d127aa6e6f3')
;
-- Feb 28, 2020, 2:24:49 PM CET
INSERT INTO AD_TreeNodeMM (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNodeMM_UU) SELECT t.AD_Client_ID, 0, 'Y', statement_timestamp(), 100, statement_timestamp(), 100,t.AD_Tree_ID, 200173, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='MM' AND NOT EXISTS (SELECT * FROM AD_TreeNodeMM e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200173)
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=0, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=218
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=1, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=153
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=2, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=263
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=3, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=166
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=4, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=203
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=5, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=53242
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=6, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=236
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=7, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=183
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=8, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=160
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=9, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=278
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=10, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=345
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=11, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=53296
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=12, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=53014
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=0, SeqNo=13, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=53108
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=0, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=261
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=1, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=53202
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=2, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=225
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=3, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200026
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=4, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200009
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=5, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=148
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=6, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=529
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=7, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=397
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=8, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=532
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=9, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=53084
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=10, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=514
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=11, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200069
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=12, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200070
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=13, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200067
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=14, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200068
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=15, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200027
;
-- Feb 28, 2020, 2:25:18 PM CET
UPDATE AD_TreeNodeMM SET Parent_ID=156, SeqNo=16, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200173
;
-- Feb 28, 2020, 2:36:57 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200287,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:36:56','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:36:56','YYYY-MM-DD HH24:MI:SS'),100,'Client (All)',200117,10,19,'N',10,'N','AD_AllClients_V_ID','Y','D',203119,'0e5fb109-e45c-40c6-86bd-ddb870b3c54f','N')
;
-- Feb 28, 2020, 2:41:33 PM CET
UPDATE AD_Process_Para SET DefaultValue='@SQL=SELECT CASE WHEN @#AD_Client_ID@>0 THEN @#AD_Client_ID@ ELSE -1 END', ReadOnlyLogic='@#AD_Client_ID@>0',Updated=TO_TIMESTAMP('2020-02-28 14:41:33','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200287
;
-- Feb 28, 2020, 2:42:41 PM CET
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203404,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:41:52','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:41:52','YYYY-MM-DD HH24:MI:SS'),100,'Actual_StorageProvider_ID','Actual Storage Provider',NULL,NULL,'Actual Storage Provider','D','0cfa1388-b17c-4c16-8506-8209d566cbd9')
;
-- Feb 28, 2020, 2:43:45 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,AD_Reference_Value_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200288,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:43:45','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:43:45','YYYY-MM-DD HH24:MI:SS'),100,'Actual Storage Provider',200117,20,18,200023,'N',10,'N','Actual_StorageProvider_ID','Y','D',203404,'e8760265-8b93-4535-bc62-3267597b8148','N')
;
-- Feb 28, 2020, 2:44:40 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200289,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:44:40','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:44:40','YYYY-MM-DD HH24:MI:SS'),100,'Storage Provider',200117,30,19,'N',10,'Y','AD_StorageProvider_ID','Y','D',200238,'fcded692-5976-4c18-be93-1de330b2c0f7','N')
;
-- Feb 28, 2020, 2:45:25 PM CET
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203405,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:45:09','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:45:09','YYYY-MM-DD HH24:MI:SS'),100,'IsMigrateAttachment','Migrate Attachment',NULL,NULL,'Migrate Attachment','D','d8cebb40-2e30-4561-9c0c-34ce599f602f')
;
-- Feb 28, 2020, 2:45:55 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200290,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:45:55','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:45:55','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Attachment',200117,40,20,'N',1,'Y','N','IsMigrateAttachment','Y','D',203405,'90601452-26c5-40f4-89fe-9a3875973afa','N')
;
-- Feb 28, 2020, 2:46:10 PM CET
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203406,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:46:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:46:00','YYYY-MM-DD HH24:MI:SS'),100,'IsMigrateArchive','Migrate Archive',NULL,NULL,'Migrate Archive','D','b7080f1a-398e-4a19-9ccf-03d22aa8e605')
;
-- Feb 28, 2020, 2:46:17 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200291,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:46:16','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:46:16','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Archive',200117,50,20,'N',1,'Y','N','IsMigrateArchive','Y','D',203406,'a35d4b7a-2647-4ad1-a994-68b376ef696e','N')
;
-- Feb 28, 2020, 2:46:30 PM CET
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203407,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:46:21','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:46:21','YYYY-MM-DD HH24:MI:SS'),100,'IsMigrateImage','Migrate Image',NULL,NULL,'Migrate Image','D','da9b6551-af77-4e28-b788-bf94462cd342')
;
-- Feb 28, 2020, 2:46:33 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200292,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:46:33','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:46:33','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Image',200117,60,20,'N',1,'Y','N','IsMigrateImage','Y','D',203407,'1c6fb7fb-fd93-48a6-8f30-3f8912880947','N')
;
-- Feb 28, 2020, 2:47:29 PM CET
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200293,0,0,'Y',TO_TIMESTAMP('2020-02-28 14:47:28','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2020-02-28 14:47:28','YYYY-MM-DD HH24:MI:SS'),100,'Delete old/existing records','Otherwise records will be added',200117,70,20,'N',1,'Y','N','DeleteOld','Y','D',1669,'2de2ab75-8533-4ff6-b01b-62f660c5d7a2','N')
;
-- Feb 28, 2020, 2:49:30 PM CET
UPDATE AD_Process_Para SET Name='Delete old/existing files', Description='Delete the records from the old storage provider after moved', Help='WARNING! This option cannot be rolled back! Be cautious, take backups. If not enabled, the system administrator can/must remove manually the old files from the previous storage provider later.', IsCentrallyMaintained='N',Updated=TO_TIMESTAMP('2020-02-28 14:49:30','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200293
;
-- Feb 28, 2020, 5:54:24 PM CET
UPDATE AD_Process_Para SET DisplayLogic='@AD_AllClients_V_ID:-1@=-1',Updated=TO_TIMESTAMP('2020-02-28 17:54:24','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200288
;
-- Mar 4, 2020, 4:19:26 PM CET
UPDATE AD_Process SET Help='<p><span style="color:#ff0000"><b>WARNING: This process can be destructive, so please be sure that you have a backup of the database, as well as a backup of your old storage provider.</b></span></p>
<p>The process migrates files between storage providers.</p>
<ul>
<li><b>Client:</b> Optional, you can select a client to migrate, if empty it will try to migrate storage providers from all clients with the Actual Storage Provider selected below.</li>
<li><b>Actual Storage Provider:</b>&nbsp;If the client is empty, you define here the storage provider to migrate, if empty it migrates clients with the storage provider not set (this is by default DB).</li>
<li><b>Storage Provider:</b>&nbsp;The new storage provider to migrate the files.</li>
<li><b>Migrate Attachment:</b>&nbsp;Check this flag if you want to migrate the attachment files to the new storage provider.</li>
<li><b>Migrate Archive:</b>&nbsp;Check this flag if you want to migrate the attachment files to the new storage provider.</li>
<li><b>Migrate Image:</b>&nbsp;Check this flag if you want to migrate the attachment files to the new storage provider.</li>
<li><b>Delete old/existing files:</b>&nbsp;If this flag is checked, after the attachments are migrated the program tries to delete (free space) the files from the previous storage provider.&nbsp; <span style="color:#ff0000">Note that migrating from/to a DB storage provider is a destructive action that cannot be recovered, it implies deleting the old/existing files</span>.</li>
</ul>
<p>The process provides status updates when running in foreground, however as the process can take long time, it can be executed in background.&nbsp; Please note that during the migration the whole table being migrated (attachment, archive, image) is locked, so operations on these tables are not permitted.&nbsp; Because of this, it is recommended to run this process in a <b>maintenance window</b> without users logged in the system.</p>
<p>There are intermediate commits in ',Updated=TO_TIMESTAMP('2020-03-04 16:19:26','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200117
;
-- Mar 4, 2020, 4:21:15 PM CET
UPDATE AD_Process_Para SET Name='Client', Description='Client/Tenant for this installation.', Help='A Client is a company or a legal entity. You cannot share data between Clients. Tenant is a synonym for Client.', AD_Reference_ID=18, AD_Reference_Value_ID=129, IsCentrallyMaintained='N',Updated=TO_TIMESTAMP('2020-03-04 16:21:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200287
;
-- Mar 4, 2020, 4:23:12 PM CET
UPDATE AD_Process_Para SET AD_Reference_ID=19, AD_Reference_Value_ID=NULL,Updated=TO_TIMESTAMP('2020-03-04 16:23:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200287
;
SELECT register_migration_script('202002281451_IDEMPIERE-4191.sql') FROM dual
;

View File

@ -0,0 +1,388 @@
/**********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Sponsor: *
* - FH *
* Contributors: *
* - Carlos Ruiz *
**********************************************************************/
package org.idempiere.process;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.compiere.model.IArchiveStore;
import org.compiere.model.IAttachmentStore;
import org.compiere.model.IImageStore;
import org.compiere.model.MArchive;
import org.compiere.model.MAttachment;
import org.compiere.model.MClient;
import org.compiere.model.MClientInfo;
import org.compiere.model.MImage;
import org.compiere.model.MStorageProvider;
import org.compiere.model.Query;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.process.SvrProcess;
import org.compiere.util.CacheMgt;
/**
* IDEMPIERE-4191
* @author Carlos Ruiz - globalqss
*/
public class MigrateStorageProvider extends SvrProcess {
private int p_AD_Client_ID = -1;
private int p_Actual_StorageProvider_ID = 0;
private int p_AD_StorageProvider_ID = -1;
private boolean p_IsMigrateAttachment = false;
private boolean p_IsMigrateArchive = false;
private boolean p_IsMigrateImage = false;
private boolean p_DeleteOld = false;
int cntAttachment = 0;
int cntArchive = 0;
int cntImage = 0;
/**
* Prepare - e.g., get Parameters.
*/
protected void prepare() {
for (ProcessInfoParameter para : getParameter()) {
String name = para.getParameterName();
if ("AD_AllClients_V_ID".equals(name)) {
if (para.getParameter() != null) {
p_AD_Client_ID = para.getParameterAsInt();
}
} else if ("Actual_StorageProvider_ID".equals(name)) {
p_Actual_StorageProvider_ID = para.getParameterAsInt();
} else if ("AD_StorageProvider_ID".equals(name)) {
p_AD_StorageProvider_ID = para.getParameterAsInt();
} else if ("IsMigrateAttachment".equals(name)) {
p_IsMigrateAttachment = para.getParameterAsBoolean();
} else if ("IsMigrateArchive".equals(name)) {
p_IsMigrateArchive = para.getParameterAsBoolean();
} else if ("IsMigrateImage".equals(name)) {
p_IsMigrateImage = para.getParameterAsBoolean();
} else if ("DeleteOld".equals(name)) {
p_DeleteOld = para.getParameterAsBoolean();
} else {
log.log(Level.SEVERE, "Unknown Parameter: " + name);
}
}
} // prepare
/**
* Perform process.
* @return Message
* @throws Exception
*/
protected String doIt() throws Exception {
if (log.isLoggable(Level.INFO))
log.info("AD_AllClients_V_ID" + p_AD_Client_ID
+ ", Actual_StorageProvider_ID=" + p_Actual_StorageProvider_ID
+ ", AD_StorageProvider_ID=" + p_AD_StorageProvider_ID
+ ", IsMigrateAttachment=" + p_IsMigrateAttachment
+ ", IsMigrateArchive=" + p_IsMigrateArchive
+ ", IsMigrateImage=" + p_IsMigrateImage
+ ", DeleteOld=" + p_DeleteOld);
if ( ! (p_IsMigrateAttachment || p_IsMigrateArchive || p_IsMigrateImage ) ) {
return "Nothing to migrate, please select an option";
}
// Create list of clients to process:
// - single AD_Client
// - clients using the actual storage provider (depending on the isMigrate flags)
List<Integer> clients = new ArrayList<Integer>();
if (p_AD_Client_ID >= 0) {
clients.add(p_AD_Client_ID);
p_Actual_StorageProvider_ID = 0;
} else {
StringBuilder whereClause = new StringBuilder();
StringBuilder storageClause = new StringBuilder();
if (p_Actual_StorageProvider_ID > 0) {
storageClause.append("=").append(p_Actual_StorageProvider_ID);
} else {
storageClause.append(" IS NULL");
}
if (p_IsMigrateAttachment) {
whereClause.append("AD_StorageProvider_ID").append(storageClause);
}
if (p_IsMigrateArchive) {
if (whereClause.length() > 0) {
whereClause.append(" OR ");
}
whereClause.append("StorageArchive_ID").append(storageClause);
}
if (p_IsMigrateImage) {
if (whereClause.length() > 0) {
whereClause.append(" OR ");
}
whereClause.append("StorageImage_ID").append(storageClause);
}
int[] ids = new Query(getCtx(), MClientInfo.Table_Name, whereClause.toString(), get_TrxName())
.setOrderBy("AD_Client_ID")
.getIDs();
for (int id : ids) {
clients.add(id);
}
}
if ( clients.size() == 0) {
return "Nothing to migrate, no clients with that storage provider";
}
MStorageProvider newProvider = new MStorageProvider(getCtx(), p_AD_StorageProvider_ID, get_TrxName());
boolean isNewStorageDB = MStorageProvider.METHOD_Database.equals(newProvider.getMethod());
int idxClient = 0;
int totalClients = clients.size();
// for each client
for (int clientid : clients) {
idxClient++;
MClientInfo clientInfo = MClientInfo.get(getCtx(), clientid);
MClient client = MClient.get(getCtx(), clientid);
int odometer = 10;
if (p_IsMigrateAttachment) {
if ( clientInfo.getAD_StorageProvider_ID() == p_AD_StorageProvider_ID
|| (clientInfo.getAD_StorageProvider_ID() == 0 && isNewStorageDB)) {
String msg = client.getName() + " has already attachment storage " + newProvider.getName();
addLog(msg);
} else {
migrateAttachments(newProvider, idxClient, totalClients, clientid, clientInfo, client, odometer);
}
}
if (p_IsMigrateArchive) {
if ( clientInfo.getStorageArchive_ID() == p_AD_StorageProvider_ID
|| (clientInfo.getStorageArchive_ID() == 0 && isNewStorageDB)) {
String msg = client.getName() + " has already archive storage " + newProvider.getName();
addLog(msg);
} else {
migrateArchives(newProvider, idxClient, totalClients, clientid, clientInfo, client, odometer);
}
}
if (p_IsMigrateImage) {
if ( clientInfo.getStorageImage_ID() == p_AD_StorageProvider_ID
|| (clientInfo.getStorageImage_ID() == 0 && isNewStorageDB)) {
String msg = client.getName() + " has already image storage " + newProvider.getName();
addLog(msg);
} else {
migrateImages(newProvider, idxClient, totalClients, clientid, clientInfo, client, odometer);
}
}
} // end for each client
return "@Updated@ " + cntAttachment + " @AD_Attachment_ID@, " + cntArchive + " @AD_Archive_ID@, " + cntImage + " @AD_Image_ID@";
} // doIt
private void migrateAttachments(MStorageProvider newProvider, int idxClient, int totalClients, int clientid,
MClientInfo clientInfo, MClient client, int odometer) throws SQLException {
// migrate attachment
status(idxClient, totalClients, "Migrating attachments for " + client.getName());
int[] attachIds = new Query(getCtx(), MAttachment.Table_Name, "AD_Client_ID=?", get_TrxName())
.setParameters(clientid)
.setOrderBy("AD_Attachment_ID")
.setForUpdate(true) // lock these records in the table
.getIDs();
int cntRecords = attachIds.length;
// iterate on each record of the associated table
int idxAttach = 0;
for (int attachId : attachIds) {
idxAttach++;
if (idxAttach % odometer == 0) {
progress(idxClient, totalClients, idxAttach, cntRecords, "Migrating attachment ");
}
MAttachment attachment = new MAttachment(getCtx(), attachId, get_TrxName());
attachment.getEntries();
attachment.setStorageProvider(newProvider);
attachment.set_ValueNoCheck("Updated", new Timestamp(System.currentTimeMillis())); // to force save
// create file on the new storage provider
attachment.saveEx();
cntAttachment++;
}
// set the corresponding storage provider
int oldProviderId = clientInfo.getAD_StorageProvider_ID();
clientInfo.setAD_StorageProvider_ID(p_AD_StorageProvider_ID);
clientInfo.saveEx();
// cache reset
CacheMgt.get().reset(MClientInfo.Table_Name, clientInfo.getAD_Client_ID());
commitEx();
String msg = "Migrated " + cntRecords + " attachments on " + client.getName();
addLog(msg);
// if delete old
if (p_DeleteOld) {
MStorageProvider oldProvider = new MStorageProvider(getCtx(), oldProviderId, get_TrxName());
if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) {
// DB method doesn't require delete
IAttachmentStore oldStore = oldProvider.getAttachmentStore();
// iterate on each record of the associated table
idxAttach = 0;
for (int attachId : attachIds) {
idxAttach++;
if (idxAttach % odometer == 0) {
progress(idxClient, totalClients, idxAttach, cntRecords, "Deleting old attachment ");
}
// delete file on old storage
MAttachment attachment = new MAttachment(getCtx(), attachId, get_TrxName());
attachment.setStorageProvider(newProvider);
attachment.getEntries();
oldStore.delete(attachment, oldProvider);
}
msg = "Deleted " + cntRecords + " old attachment files on " + client.getName();
addLog(msg);
}
}
}
private void migrateArchives(MStorageProvider newProvider, int idxClient, int totalClients, int clientid,
MClientInfo clientInfo, MClient client, int odometer) throws SQLException {
// migrate archive
status(idxClient, totalClients, "Migrating archives for " + client.getName());
int[] archiveIds = new Query(getCtx(), MArchive.Table_Name, "AD_Client_ID=?", get_TrxName())
.setParameters(clientid)
.setOrderBy("AD_Archive_ID")
.setForUpdate(true) // lock these records in the table
.getIDs();
int cntRecords = archiveIds.length;
// iterate on each record of the associated table
int idxArchive = 0;
for (int archiveId : archiveIds) {
idxArchive++;
if (idxArchive % odometer == 0) {
progress(idxClient, totalClients, idxArchive, cntRecords, "Migrating archive ");
}
MArchive archive = new MArchive(getCtx(), archiveId, get_TrxName());
byte[] data = archive.getBinaryData();
archive.setStorageProvider(newProvider);
archive.setBinaryData(data);
archive.set_ValueNoCheck("Updated", new Timestamp(System.currentTimeMillis())); // to force save
// create file on the new storage provider
archive.saveEx();
cntArchive++;
}
// set the corresponding storage provider
int oldProviderId = clientInfo.getStorageArchive_ID();
clientInfo.setStorageArchive_ID(p_AD_StorageProvider_ID);
clientInfo.saveEx();
// cache reset
CacheMgt.get().reset(MClientInfo.Table_Name, clientInfo.getAD_Client_ID());
commitEx();
String msg = "Migrated " + cntRecords + " archives on " + client.getName();
addLog(msg);
// if delete old
if (p_DeleteOld) {
MStorageProvider oldProvider = new MStorageProvider(getCtx(), oldProviderId, get_TrxName());
if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) {
// DB method doesn't require delete
IArchiveStore oldStore = oldProvider.getArchiveStore();
// iterate on each record of the associated table
idxArchive = 0;
for (int archiveId : archiveIds) {
idxArchive++;
if (idxArchive % odometer == 0) {
progress(idxClient, totalClients, idxArchive, cntRecords, "Deleting old archive ");
}
// delete file on old storage
MArchive archive = new MArchive(getCtx(), archiveId, get_TrxName());
archive.setStorageProvider(newProvider);
oldStore.deleteArchive(archive, oldProvider);
}
msg = "Deleted " + cntRecords + " old archive files on " + client.getName();
addLog(msg);
}
}
}
private void migrateImages(MStorageProvider newProvider, int idxClient, int totalClients, int clientid,
MClientInfo clientInfo, MClient client, int odometer) throws SQLException {
// migrate image
status(idxClient, totalClients, "Migrating images for " + client.getName());
int[] imageIds = new Query(getCtx(), MImage.Table_Name, "AD_Client_ID=?", get_TrxName())
.setParameters(clientid)
.setOrderBy("AD_Image_ID")
.setForUpdate(true) // lock these records in the table
.getIDs();
int cntRecords = imageIds.length;
// iterate on each record of the associated table
int idxImage = 0;
for (int imageId : imageIds) {
idxImage++;
if (idxImage % odometer == 0) {
progress(idxClient, totalClients, idxImage, cntRecords, "Migrating image ");
}
MImage image = new MImage(getCtx(), imageId, get_TrxName());
byte[] data = image.getBinaryData();
image.setStorageProvider(newProvider);
image.setBinaryData(data);
image.set_ValueNoCheck("Updated", new Timestamp(System.currentTimeMillis())); // to force save
// create file on the new storage provider
image.saveEx();
cntImage++;
}
// set the corresponding storage provider
int oldProviderId = clientInfo.getStorageImage_ID();
clientInfo.setStorageImage_ID(p_AD_StorageProvider_ID);
clientInfo.saveEx();
// cache reset
CacheMgt.get().reset(MClientInfo.Table_Name, clientInfo.getAD_Client_ID());
commitEx();
String msg = "Migrated " + cntRecords + " images on " + client.getName();
addLog(msg);
// if delete old
if (p_DeleteOld) {
MStorageProvider oldProvider = new MStorageProvider(getCtx(), oldProviderId, get_TrxName());
if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) {
// DB method doesn't require delete
IImageStore oldStore = oldProvider.getImageStore();
// iterate on each record of the associated table
idxImage = 0;
for (int imageId : imageIds) {
idxImage++;
if (idxImage % odometer == 0) {
progress(idxClient, totalClients, idxImage, cntRecords, "Deleting old image ");
}
// delete file on old storage
MImage image = new MImage(getCtx(), imageId, get_TrxName());
image.setStorageProvider(newProvider);
oldStore.delete(image, oldProvider);
}
msg = "Deleted " + cntRecords + " old image files on " + client.getName();
addLog(msg);
}
}
}
private void progress(int idxClient, int totalClients, int idxRecord, int cntRecords, String msg) {
if (processUI != null) {
processUI.statusUpdate("Client " + idxClient + "/" + totalClients + " - " + msg + " " + idxRecord + "/" + cntRecords + " = " + idxRecord*100/cntRecords + "%");
}
}
private void status(int idxClient, int totalClients, String msg) {
if (processUI != null) {
processUI.statusUpdate("Client " + idxClient + "/" + totalClients + " - " + msg);
}
}
} // MigrateStorageProvider

View File

@ -39,7 +39,7 @@ public class MArchive extends X_AD_Archive {
/** /**
* *
*/ */
private static final long serialVersionUID = -9116541441191978777L; private static final long serialVersionUID = -2384941426301490384L;
/** /**
* Get Archives * Get Archives
@ -145,7 +145,7 @@ public class MArchive extends X_AD_Archive {
* @param trxName * @param trxName
*/ */
private void initArchiveStoreDetails(Properties ctx, String trxName) { private void initArchiveStoreDetails(Properties ctx, String trxName) {
MClientInfo clientInfo = MClientInfo.get(ctx); MClientInfo clientInfo = MClientInfo.get(ctx, getAD_Client_ID());
provider=new MStorageProvider(ctx, clientInfo.getStorageArchive_ID(), trxName); provider=new MStorageProvider(ctx, clientInfo.getStorageArchive_ID(), trxName);
} }
@ -286,4 +286,14 @@ public class MArchive extends X_AD_Archive {
if (prov != null && prov.isPendingFlush()) if (prov != null && prov.isPendingFlush())
prov.flush(this,provider); prov.flush(this,provider);
} }
/**
* Set Storage Provider
* Used temporarily for the process to migrate storage provider
* @param Storage provider
*/
public void setStorageProvider(MStorageProvider p) {
provider = p;
}
} // MArchive } // MArchive

View File

@ -57,7 +57,7 @@ public class MAttachment extends X_AD_Attachment
/** /**
* *
*/ */
private static final long serialVersionUID = 6596285414376249694L; private static final long serialVersionUID = -1685512419870004665L;
/** /**
* *
@ -685,4 +685,14 @@ public class MAttachment extends X_AD_Attachment
return destZipFile; return destZipFile;
} }
/**
* Set Storage Provider
* Used temporarily for the process to migrate storage provider
* @param Storage provider
*/
public void setStorageProvider(MStorageProvider p) {
provider = p;
}
} // MAttachment } // MAttachment

View File

@ -339,10 +339,15 @@ public class MImage extends X_AD_Image
* @param trxName * @param trxName
*/ */
private void initImageStoreDetails(Properties ctx, String trxName) { private void initImageStoreDetails(Properties ctx, String trxName) {
MClientInfo clientInfo = MClientInfo.get(ctx); MClientInfo clientInfo = MClientInfo.get(ctx, getAD_Client_ID());
provider=new MStorageProvider(ctx, clientInfo.getStorageImage_ID(), trxName); provider=new MStorageProvider(ctx, clientInfo.getStorageImage_ID(), trxName);
} }
/**
* Set Storage Provider
* Used temporarily for the process to migrate storage provider
* @param Storage provider
*/
public void setStorageProvider(MStorageProvider p) { public void setStorageProvider(MStorageProvider p) {
provider = p; provider = p;
} }