IDEMPIERE-3660 Improve Packin - allow application on all tenants
This commit is contained in:
parent
0962dd0783
commit
89c00b7ada
|
@ -0,0 +1,72 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- IDEMPIERE-3660 Improve Packin - allow application on all tenants
|
||||
-- Mar 15, 2018 4:09:45 PM BRT
|
||||
INSERT INTO AD_Process (AD_Process_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,Help,IsReport,Value,IsDirectPrint,Classname,AccessLevel,EntityType,Statistic_Count,Statistic_Seconds,IsBetaFunctionality,IsServerProcess,ShowHelp,CopyFromProcess,AD_Process_UU) VALUES (200099,0,0,'Y',TO_DATE('2018-03-15 16:09:44','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-03-15 16:09:44','YYYY-MM-DD HH24:MI:SS'),100,'Apply Pack In from Folder','Apply all zip files from a folder following the rules and conventions of Automatic Pack In process','This process apply all the pack in files found in a folder recursively - ordered by timestamp.
|
||||
The filename of the pack in files is important, it must follow the following convention:
|
||||
[Timestamp]_[ClientValue][_AdditionalInformation].zip
|
||||
* Timestamp: must be in the format yyyymmddHHMM
|
||||
* ClientValue: case sensitive and compared against AD_Client.Value to find the tenant where the pack in must be applied
|
||||
* AdditionalInformation: Any additional information to identify the zip file
|
||||
NOTE that AD_Client.Value must not contain underscore in order for this process to work.
|
||||
There is a special case for ClientValue, if the ClientValue is ALL-CLIENTS then the 2pack is intended to be applied in all active non-system clients.
|
||||
If there is a need to apply initially in a seed tenant then the ClientValue must take the form ALL-CLIENTS-Seed.
|
||||
For example:
|
||||
201803151607_ALL-CLIENTS-GardenWorld_Test123.zip','N','ApplyPackInFolder','N','org.adempiere.pipo2.PackInFolder','4','D',0,0,'N','N','Y','N','670d19a4-8072-46c8-9e66-3cb3008d18f3')
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:09 PM BRT
|
||||
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 (200153,'Apply Pack In from Folder','Apply all zip files from a folder following the rules and conventions of Automatic Pack In process','P',0,0,'Y',TO_DATE('2018-03-15 16:10:09','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-03-15 16:10:09','YYYY-MM-DD HH24:MI:SS'),100,'N',200099,'Y','N','D','Y','dee67807-ff1c-45c8-94bd-5c025c3ec902')
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:09 PM BRT
|
||||
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, 200153, 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=200153)
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=0, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=50004
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=1, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=50006
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=2, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=50002
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=3, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=50003
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=4, Updated=SysDate WHERE AD_Tree_ID=10 AND Node_ID=200153
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:12:47 PM BRT
|
||||
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,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200226,0,0,'Y',TO_DATE('2018-03-15 16:12:46','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2018-03-15 16:12:46','YYYY-MM-DD HH24:MI:SS'),100,'Folder','Path on the server where the pack in files are located',200099,10,10,'N',1000,'Y','Folder','N','D',3012,'e0c4b099-68ba-48fe-b629-043befec7bbe','N')
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:43:24 PM BRT
|
||||
UPDATE AD_Process SET Help='<p>This process apply all the pack in files found in a folder recursively - ordered by timestamp.<br />
|
||||
The filename of the pack in files is important, it must follow the following convention:<br />
|
||||
[Timestamp]_[ClientValue][_AdditionalInformation].zip</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Timestamp:</strong> must be in the format yyyymmddHHMM</li>
|
||||
<li><strong>ClientValue:</strong> case sensitive and compared against AD_Client.Value to find the tenant where the pack in must be applied</li>
|
||||
<li><strong>AdditionalInformation:</strong> Any additional information to identify the zip file</li>
|
||||
</ul>
|
||||
|
||||
<p>NOTE that AD_Client.Value must not contain underscore in order for this process to work.<br />
|
||||
There is a special case for ClientValue, if the ClientValue is ALL-CLIENTS then the 2pack is intended to be applied in all active non-system clients.<br />
|
||||
If there is a need to apply initially in a seed tenant then the ClientValue must take the form ALL-CLIENTS-Seed.<br />
|
||||
For example:<br />
|
||||
201803151607_ALL-CLIENTS-GardenWorld_Test123.zip</p>
|
||||
',Updated=TO_DATE('2018-03-15 16:43:24','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200099
|
||||
;
|
||||
|
||||
SELECT register_migration_script('201803151613_IDEMPIERE-3660.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
-- IDEMPIERE-3660 Improve Packin - allow application on all tenants
|
||||
-- Mar 15, 2018 4:09:45 PM BRT
|
||||
INSERT INTO AD_Process (AD_Process_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,Help,IsReport,Value,IsDirectPrint,Classname,AccessLevel,EntityType,Statistic_Count,Statistic_Seconds,IsBetaFunctionality,IsServerProcess,ShowHelp,CopyFromProcess,AD_Process_UU) VALUES (200099,0,0,'Y',TO_TIMESTAMP('2018-03-15 16:09:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-03-15 16:09:44','YYYY-MM-DD HH24:MI:SS'),100,'Apply Pack In from Folder','Apply all zip files from a folder following the rules and conventions of Automatic Pack In process','This process apply all the pack in files found in a folder recursively - ordered by timestamp.
|
||||
The filename of the pack in files is important, it must follow the following convention:
|
||||
[Timestamp]_[ClientValue][_AdditionalInformation].zip
|
||||
* Timestamp: must be in the format yyyymmddHHMM
|
||||
* ClientValue: case sensitive and compared against AD_Client.Value to find the tenant where the pack in must be applied
|
||||
* AdditionalInformation: Any additional information to identify the zip file
|
||||
NOTE that AD_Client.Value must not contain underscore in order for this process to work.
|
||||
There is a special case for ClientValue, if the ClientValue is ALL-CLIENTS then the 2pack is intended to be applied in all active non-system clients.
|
||||
If there is a need to apply initially in a seed tenant then the ClientValue must take the form ALL-CLIENTS-Seed.
|
||||
For example:
|
||||
201803151607_ALL-CLIENTS-GardenWorld_Test123.zip','N','ApplyPackInFolder','N','org.adempiere.pipo2.PackInFolder','4','D',0,0,'N','N','Y','N','670d19a4-8072-46c8-9e66-3cb3008d18f3')
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:09 PM BRT
|
||||
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 (200153,'Apply Pack In from Folder','Apply all zip files from a folder following the rules and conventions of Automatic Pack In process','P',0,0,'Y',TO_TIMESTAMP('2018-03-15 16:10:09','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-03-15 16:10:09','YYYY-MM-DD HH24:MI:SS'),100,'N',200099,'Y','N','D','Y','dee67807-ff1c-45c8-94bd-5c025c3ec902')
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:09 PM BRT
|
||||
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, 200153, 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=200153)
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=0, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=50004
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=1, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=50006
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=2, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=50002
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=3, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=50003
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:10:13 PM BRT
|
||||
UPDATE AD_TreeNodeMM SET Parent_ID=50001, SeqNo=4, Updated=statement_timestamp() WHERE AD_Tree_ID=10 AND Node_ID=200153
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:12:47 PM BRT
|
||||
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,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted) VALUES (200226,0,0,'Y',TO_TIMESTAMP('2018-03-15 16:12:46','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2018-03-15 16:12:46','YYYY-MM-DD HH24:MI:SS'),100,'Folder','Path on the server where the pack in files are located',200099,10,10,'N',1000,'Y','Folder','N','D',3012,'e0c4b099-68ba-48fe-b629-043befec7bbe','N')
|
||||
;
|
||||
|
||||
-- Mar 15, 2018 4:43:24 PM BRT
|
||||
UPDATE AD_Process SET Help='<p>This process apply all the pack in files found in a folder recursively - ordered by timestamp.<br />
|
||||
The filename of the pack in files is important, it must follow the following convention:<br />
|
||||
[Timestamp]_[ClientValue][_AdditionalInformation].zip</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Timestamp:</strong> must be in the format yyyymmddHHMM</li>
|
||||
<li><strong>ClientValue:</strong> case sensitive and compared against AD_Client.Value to find the tenant where the pack in must be applied</li>
|
||||
<li><strong>AdditionalInformation:</strong> Any additional information to identify the zip file</li>
|
||||
</ul>
|
||||
|
||||
<p>NOTE that AD_Client.Value must not contain underscore in order for this process to work.<br />
|
||||
There is a special case for ClientValue, if the ClientValue is ALL-CLIENTS then the 2pack is intended to be applied in all active non-system clients.<br />
|
||||
If there is a need to apply initially in a seed tenant then the ClientValue must take the form ALL-CLIENTS-Seed.<br />
|
||||
For example:<br />
|
||||
201803151607_ALL-CLIENTS-GardenWorld_Test123.zip</p>
|
||||
',Updated=TO_TIMESTAMP('2018-03-15 16:43:24','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200099
|
||||
;
|
||||
|
||||
SELECT register_migration_script('201803151613_IDEMPIERE-3660.sql') FROM dual
|
||||
;
|
||||
|
|
@ -17,6 +17,7 @@ package org.adempiere.base;
|
|||
|
||||
import java.io.File;
|
||||
|
||||
import org.compiere.model.X_AD_Package_Imp_Proc;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
|
@ -28,4 +29,8 @@ import org.osgi.framework.BundleContext;
|
|||
*/
|
||||
public interface IDictionaryService {
|
||||
void merge(BundleContext context, File packageFile) throws Exception;
|
||||
|
||||
default public X_AD_Package_Imp_Proc getAD_Package_Imp_Proc() {
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -35,5 +35,13 @@
|
|||
class="org.adempiere.pipo2.PackRollProcess">
|
||||
</process>
|
||||
</extension>
|
||||
<extension
|
||||
id="org.adempiere.pipo2.PackInFolder"
|
||||
name="PackIn Folder"
|
||||
point="org.adempiere.base.Process">
|
||||
<process
|
||||
class="org.adempiere.pipo2.PackInFolder">
|
||||
</process>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -34,24 +34,28 @@ public class PipoDictionaryService implements IDictionaryService {
|
|||
super();
|
||||
}
|
||||
|
||||
X_AD_Package_Imp_Proc adPackageImp = null;
|
||||
|
||||
@Override
|
||||
public void merge(BundleContext context, File packageFile) throws Exception {
|
||||
if (packageFile == null || !packageFile.exists()) {
|
||||
logger.info("No PackIn Model found");
|
||||
return;
|
||||
}
|
||||
String symbolicName = "org.adempiere.pipo";
|
||||
if (context != null)
|
||||
symbolicName = context.getBundle().getSymbolicName();
|
||||
String trxName = null;
|
||||
X_AD_Package_Imp_Proc adPackageImp = null;
|
||||
PackIn packIn = null;
|
||||
try {
|
||||
trxName = Trx.createTrxName("PipoDS");
|
||||
Trx.get(trxName, true).setDisplayName(getClass().getName()+"_merge");
|
||||
packIn = new PackIn();
|
||||
//external files must not start with "2Pack" prefix in order to work correctly
|
||||
if ("org.adempiere.pipo".equals(context.getBundle().getSymbolicName()) && !packageFile.getName().startsWith("2Pack"))
|
||||
if ("org.adempiere.pipo".equals(symbolicName) && !packageFile.getName().startsWith("2Pack"))
|
||||
packIn.setPackageName(packageFile.getName());
|
||||
else
|
||||
packIn.setPackageName(context.getBundle().getSymbolicName());
|
||||
packIn.setPackageName(symbolicName);
|
||||
|
||||
if (Env.getCtx().getProperty("#AD_Client_ID") == null) {
|
||||
Env.getCtx().put("#AD_Client_ID", 0);
|
||||
|
@ -70,13 +74,13 @@ public class PipoDictionaryService implements IDictionaryService {
|
|||
}
|
||||
}
|
||||
//no version string from file name suffix, get it from bundle header
|
||||
if (packageVersion == null)
|
||||
if (packageVersion == null && context != null)
|
||||
packageVersion = (String) context.getBundle().getHeaders().get("Bundle-Version");
|
||||
|
||||
packIn.setPackageVersion(packageVersion);
|
||||
packIn.setUpdateDictionary(false);
|
||||
packIn.getNotifier().setFileName(packageFile.getName());
|
||||
packIn.getNotifier().setPluginName(context.getBundle().getSymbolicName() + " v" + packageVersion);
|
||||
packIn.getNotifier().setPluginName(symbolicName + " v" + packageVersion);
|
||||
|
||||
adPackageImp = new X_AD_Package_Imp_Proc(Env.getCtx(), 0, null);
|
||||
if (logger.isLoggable(Level.INFO)) logger.info("zipFilepath->" + packageFile);
|
||||
|
@ -144,4 +148,9 @@ public class PipoDictionaryService implements IDictionaryService {
|
|||
return result;
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public X_AD_Package_Imp_Proc getAD_Package_Imp_Proc() {
|
||||
return adPackageImp;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/***********************************************************************
|
||||
* 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. *
|
||||
* *
|
||||
* Contributors: *
|
||||
* - Carlos Ruiz *
|
||||
**********************************************************************/
|
||||
package org.adempiere.pipo2;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.plugin.utils.PackInApplicationActivator;
|
||||
import org.compiere.process.ProcessInfoParameter;
|
||||
import org.compiere.process.SvrProcess;
|
||||
import org.compiere.util.AdempiereSystemError;
|
||||
import org.compiere.util.Util;
|
||||
|
||||
/**
|
||||
* Apply all zip files from a folder following the rules and conventions of Automatic Pack In process
|
||||
* This process apply all the pack in files found in a folder recursively - ordered by timestamp.
|
||||
* The filename of the pack in files is important, it must follow the following convention:
|
||||
* [Timestamp]_[ClientValue][_AdditionalInformation].zip
|
||||
* - Timestamp: must be in the format yyyymmddHHMM
|
||||
* - ClientValue: case sensitive and compared against AD_Client.Value to find the tenant where the pack in must be applied
|
||||
* - AdditionalInformation: Any additional information to identify the zip file
|
||||
* NOTE that AD_Client.Value must not contain underscore in order for this process to work.
|
||||
* There is a special case for ClientValue, if the ClientValue is ALL-CLIENTS then the 2pack is intended to be applied in all active non-system clients.
|
||||
* If there is a need to apply initially in a seed tenant then the ClientValue must take the form ALL-CLIENTS-Seed.
|
||||
* For example:
|
||||
* 201803151607_ALL-CLIENTS-GardenWorld_Test123.zip
|
||||
*
|
||||
* @author Carlos Ruiz
|
||||
*/
|
||||
public class PackInFolder extends SvrProcess {
|
||||
|
||||
/** Folder to apply */
|
||||
private String p_Folder;
|
||||
|
||||
/**
|
||||
* Prepare - e.g., get Parameters.
|
||||
*/
|
||||
protected void prepare () {
|
||||
for (ProcessInfoParameter para : getParameter()) {
|
||||
String name = para.getParameterName();
|
||||
if (para.getParameter() == null)
|
||||
;
|
||||
else if (name.equals("Folder"))
|
||||
p_Folder = para.getParameterAsString();
|
||||
else
|
||||
log.log(Level.SEVERE, "Unknown Parameter: " + name);
|
||||
}
|
||||
} // prepare
|
||||
|
||||
/**
|
||||
* Process
|
||||
* @return info
|
||||
* @throws Exception
|
||||
*/
|
||||
protected String doIt () throws Exception
|
||||
{
|
||||
if (Util.isEmpty(p_Folder, true))
|
||||
throw new AdempiereSystemError("@Mandatory@ @Folder@");
|
||||
|
||||
PackInApplicationActivator piaa = new PackInApplicationActivator();
|
||||
piaa.setProcessInfo(getProcessInfo());
|
||||
piaa.setProcessUI(processUI);
|
||||
piaa.automaticPackin(0, p_Folder, false);
|
||||
String msg = getProcessInfo().getSummary();
|
||||
|
||||
return msg;
|
||||
} // doIt
|
||||
|
||||
}
|
|
@ -45,6 +45,7 @@ public class PackInProcess extends SvrProcess {
|
|||
private String m_packageDirectory = null;
|
||||
public int p_PackIn_ID = 0;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String packageName = null;
|
||||
private String packageVersion = null;
|
||||
|
||||
|
@ -130,7 +131,7 @@ public class PackInProcess extends SvrProcess {
|
|||
|
||||
PackIn packIn = new PackIn();
|
||||
packIn.setPackageDirectory(m_packageDirectory);
|
||||
packIn.setPackageName(packageName);
|
||||
packIn.setPackageName(adPackageImp.getName());
|
||||
packIn.setPackageVersion(packageVersion);
|
||||
packIn.setUpdateDictionary(m_UpdateDictionary);
|
||||
packIn.getNotifier().setFileName(zipFilepath.getName());
|
||||
|
|
|
@ -43,6 +43,7 @@ Import-Package: org.adempiere.base,
|
|||
org.compiere,
|
||||
org.compiere.db,
|
||||
org.compiere.model,
|
||||
org.compiere.process,
|
||||
org.compiere.util,
|
||||
org.osgi.framework;version="1.5.0",
|
||||
org.osgi.util.tracker;version="1.5.0"
|
||||
|
|
|
@ -14,13 +14,19 @@
|
|||
package org.adempiere.plugin.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.adempiere.base.IDictionaryService;
|
||||
import org.adempiere.base.Service;
|
||||
import org.adempiere.util.IProcessUI;
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MSysConfig;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.Query;
|
||||
import org.compiere.model.X_AD_Package_Imp;
|
||||
import org.compiere.process.ProcessInfo;
|
||||
import org.compiere.util.AdempiereSystemError;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.DB;
|
||||
|
@ -38,6 +44,8 @@ public abstract class AbstractActivator implements BundleActivator, ServiceTrack
|
|||
protected ServiceTracker<IDictionaryService, IDictionaryService> serviceTracker;
|
||||
protected IDictionaryService service;
|
||||
private String trxName = "";
|
||||
private ProcessInfo m_processInfo = null;
|
||||
private IProcessUI m_processUI = null;
|
||||
|
||||
protected boolean merge(File zipfile, String version) throws Exception {
|
||||
boolean success = false;
|
||||
|
@ -46,24 +54,47 @@ public abstract class AbstractActivator implements BundleActivator, ServiceTrack
|
|||
service.merge(context, zipfile);
|
||||
success = true;
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "The file was already installed: " + zipfile.getName());
|
||||
logger.log(Level.SEVERE, "The file was previously installed: " + zipfile.getName());
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
protected boolean directMerge(File zipfile, String version) throws Exception {
|
||||
boolean success = false;
|
||||
|
||||
if (!installedPackage(version)) {
|
||||
List<IDictionaryService> list = Service.locator().list(IDictionaryService.class).getServices();
|
||||
if (list != null) {
|
||||
IDictionaryService ids = list.get(0);
|
||||
ids.merge(null, zipfile);
|
||||
success = true;
|
||||
if (ids.getAD_Package_Imp_Proc() != null) {
|
||||
MClient client = MClient.get(Env.getCtx());
|
||||
addLog(Level.INFO, getName() + " in " + client.getValue() + " -> "+ ids.getAD_Package_Imp_Proc().getP_Msg());
|
||||
}
|
||||
} else {
|
||||
addLog(Level.SEVERE, "Could not find an IDictionaryService to process the zip files");
|
||||
}
|
||||
} else {
|
||||
addLog(Level.SEVERE, "The file was previously installed: " + zipfile.getName());
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
protected boolean installedPackage(String version) {
|
||||
StringBuilder where = new StringBuilder("Name=? AND PK_Status = 'Completed successfully'");
|
||||
Object[] params;
|
||||
StringBuilder where = new StringBuilder("AD_Client_ID=? AND Name=? AND PK_Status='Completed successfully'");
|
||||
List<Object> params = new ArrayList<Object>();
|
||||
params.add(Env.getAD_Client_ID(Env.getCtx()));
|
||||
params.add(getName());
|
||||
if (version != null) {
|
||||
where.append(" AND PK_Version LIKE ?");
|
||||
params = new Object[] { getName(), version + "%" };
|
||||
} else {
|
||||
params = new Object[] {getName()};
|
||||
params.add(version + "%");
|
||||
}
|
||||
Query q = new Query(Env.getCtx(), X_AD_Package_Imp.Table_Name,
|
||||
where.toString(), null);
|
||||
q.setParameters(params);
|
||||
Query q = new Query(Env.getCtx(), X_AD_Package_Imp.Table_Name, where.toString(), null)
|
||||
.setParameters(params);
|
||||
return q.match();
|
||||
}
|
||||
|
||||
|
@ -105,4 +136,31 @@ public abstract class AbstractActivator implements BundleActivator, ServiceTrack
|
|||
sysconfig.set_TrxName(trxName);
|
||||
return sysconfig;
|
||||
}
|
||||
|
||||
public void setProcessInfo(ProcessInfo processInfo) {
|
||||
m_processInfo = processInfo;
|
||||
}
|
||||
|
||||
public void setProcessUI(IProcessUI processUI) {
|
||||
m_processUI = processUI;
|
||||
};
|
||||
|
||||
protected void statusUpdate(String message) {
|
||||
logger.warning(message);
|
||||
if (m_processUI != null)
|
||||
m_processUI.statusUpdate(message);
|
||||
}
|
||||
|
||||
public void addLog(Level level, String msg) {
|
||||
logger.log(level, msg);
|
||||
if (m_processInfo != null)
|
||||
m_processInfo.addLog(0, null, null, msg.replaceAll("\\n", "<br>"));
|
||||
}
|
||||
|
||||
public void setSummary(Level level, String msg) {
|
||||
logger.log(level, msg);
|
||||
if (m_processInfo != null)
|
||||
m_processInfo.setSummary(msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.adempiere.plugin.utils;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
@ -34,6 +35,8 @@ import org.compiere.model.MSysConfig;
|
|||
import org.compiere.model.Query;
|
||||
import org.compiere.model.ServerStateChangeEvent;
|
||||
import org.compiere.model.ServerStateChangeListener;
|
||||
import org.compiere.model.X_AD_Package_Imp;
|
||||
import org.compiere.model.X_AD_Package_Imp_Proc;
|
||||
import org.compiere.util.AdempiereSystemError;
|
||||
import org.compiere.util.CLogger;
|
||||
import org.compiere.util.Env;
|
||||
|
@ -88,7 +91,9 @@ public class PackInApplicationActivator extends AbstractActivator {
|
|||
Adempiere.getThreadPoolExecutor().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
automaticPackin();
|
||||
int timeout = MSysConfig.getIntValue(MSysConfig.AUTOMATIC_PACKIN_INITIAL_DELAY, 120) * 1000;
|
||||
String folders = MSysConfig.getValue(MSysConfig.AUTOMATIC_PACKIN_FOLDERS);
|
||||
automaticPackin(timeout, folders, true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
@ -96,7 +101,9 @@ public class PackInApplicationActivator extends AbstractActivator {
|
|||
@Override
|
||||
public void stateChange(ServerStateChangeEvent event) {
|
||||
if (event.getEventType() == ServerStateChangeEvent.SERVER_START && service != null) {
|
||||
automaticPackin();
|
||||
int timeout = MSysConfig.getIntValue(MSysConfig.AUTOMATIC_PACKIN_INITIAL_DELAY, 120) * 1000;
|
||||
String folders = MSysConfig.getValue(MSysConfig.AUTOMATIC_PACKIN_FOLDERS);
|
||||
automaticPackin(timeout, folders, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -104,73 +111,90 @@ public class PackInApplicationActivator extends AbstractActivator {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void automaticPackin() {
|
||||
//Initial delay
|
||||
Timer t = new Timer();
|
||||
t.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(PackInApplicationActivator.class.getClassLoader());
|
||||
setupPackInContext();
|
||||
installPackages();
|
||||
} finally {
|
||||
ServerContext.dispose();
|
||||
service = null;
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
public void automaticPackin(int timeout, String folders, boolean fromService) {
|
||||
if (fromService) {
|
||||
//Initial delay - starting from service
|
||||
Timer t = new Timer();
|
||||
t.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(PackInApplicationActivator.class.getClassLoader());
|
||||
setupPackInContext();
|
||||
installPackages(folders);
|
||||
} finally {
|
||||
ServerContext.dispose();
|
||||
service = null;
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
}
|
||||
t.cancel();
|
||||
}
|
||||
t.cancel();
|
||||
}, timeout);
|
||||
} else {
|
||||
// No delay - starting from process
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(PackInApplicationActivator.class.getClassLoader());
|
||||
setupPackInContext();
|
||||
installPackages(folders);
|
||||
} finally {
|
||||
ServerContext.dispose();
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
}
|
||||
}, MSysConfig.getIntValue(MSysConfig.AUTOMATIC_PACKIN_INITIAL_DELAY, 120) * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void installPackages() {
|
||||
|
||||
String folders = MSysConfig.getValue(MSysConfig.AUTOMATIC_PACKIN_FOLDERS);
|
||||
|
||||
private void installPackages(String folders) {
|
||||
if (Util.isEmpty(folders, true)) {
|
||||
logger.log(Level.INFO, "Not specified folders for automatic packin");
|
||||
setSummary(Level.INFO, "Not specified folders for automatic packin");
|
||||
return;
|
||||
}
|
||||
|
||||
File[] fileArray = getFilesToProcess(folders);
|
||||
|
||||
if (fileArray.length <= 0) {
|
||||
logger.info("No zip files to process");
|
||||
setSummary(Level.INFO, "No zip files to process");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (getDBLock()) {
|
||||
//Create Session to be able to create records in AD_ChangeLog
|
||||
MSession.get(Env.getCtx(), true);
|
||||
if (Env.getContextAsInt(Env.getCtx(), "#AD_Session_ID") <= 0)
|
||||
MSession.get(Env.getCtx(), true);
|
||||
for(File zipFile : fileArray) {
|
||||
currentFile = zipFile;
|
||||
if (!packIn(zipFile)) {
|
||||
// stop processing further packages if one fail
|
||||
addLog(Level.SEVERE, "Failed application of " + zipFile);
|
||||
break;
|
||||
}
|
||||
addLog(Level.INFO, "Successful application of " + zipFile);
|
||||
filesToProcess.remove(zipFile);
|
||||
}
|
||||
releaseLock();
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "Could not acquire the DB lock to automatically install the packins");
|
||||
addLog(Level.SEVERE, "Could not acquire the DB lock to automatically install the packins");
|
||||
return;
|
||||
}
|
||||
} catch (AdempiereSystemError e) {
|
||||
e.printStackTrace();
|
||||
addLog(Level.SEVERE, e.getLocalizedMessage());
|
||||
} finally {
|
||||
releaseLock();
|
||||
}
|
||||
|
||||
if (filesToProcess.size() > 0) {
|
||||
logger.warning("The following packages were not applied: ");
|
||||
StringBuilder pending = new StringBuilder("The following packages were not applied: ");
|
||||
for (File file : filesToProcess) {
|
||||
logger.warning(file.getName());
|
||||
pending.append("\n").append(file.getName());
|
||||
}
|
||||
addLog(Level.WARNING, pending.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean packIn(File packinFile) {
|
||||
if (packinFile != null && service != null) {
|
||||
if (packinFile != null) {
|
||||
String fileName = packinFile.getName();
|
||||
logger.warning("Installing " + fileName + " ...");
|
||||
|
||||
|
@ -178,23 +202,86 @@ public class PackInApplicationActivator extends AbstractActivator {
|
|||
String [] parts = fileName.split("_");
|
||||
String clientValue = parts[1];
|
||||
|
||||
MClient client = getClient(clientValue);
|
||||
if (client == null) {
|
||||
logger.log(Level.SEVERE, "Client does not exist: " + clientValue);
|
||||
return false;
|
||||
boolean allClients = clientValue.startsWith("ALL-CLIENTS");
|
||||
|
||||
int[] clientIDs;
|
||||
if (allClients) {
|
||||
int[] seedClientIDs = new int[0];
|
||||
String seedClientValue = "";
|
||||
if (clientValue.startsWith("ALL-CLIENTS-")) {
|
||||
seedClientValue = clientValue.split("-")[2];
|
||||
seedClientIDs = getClientIDs(seedClientValue);
|
||||
if (seedClientIDs.length == 0) {
|
||||
logger.log(Level.SEVERE, "Seed client does not exist: " + seedClientValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int[] allClientIDs = new Query(Env.getCtx(), MClient.Table_Name, "AD_Client_ID>0 AND Value!=?", null)
|
||||
.setOnlyActiveRecords(true)
|
||||
.setParameters(seedClientValue)
|
||||
.setOrderBy("AD_Client_ID")
|
||||
.getIDs();
|
||||
// Process first the seed client, put seed in front of the array
|
||||
int shift = 0;
|
||||
if (seedClientIDs.length > 0)
|
||||
shift = 1;
|
||||
clientIDs = new int[allClientIDs.length + shift];
|
||||
if (seedClientIDs.length > 0)
|
||||
clientIDs[0] = seedClientIDs[0];
|
||||
for (int i = 0; i < allClientIDs.length; i++) {
|
||||
clientIDs[i+shift] = allClientIDs[i];
|
||||
}
|
||||
} else {
|
||||
clientIDs = getClientIDs(clientValue);
|
||||
if (clientIDs.length == 0) {
|
||||
logger.log(Level.SEVERE, "Client does not exist: " + clientValue);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Env.setContext(Env.getCtx(), "#AD_Client_ID", client.getAD_Client_ID());
|
||||
|
||||
try {
|
||||
// call 2pack
|
||||
if (!merge(packinFile, null))
|
||||
for (int clientID : clientIDs) {
|
||||
MClient client = MClient.get(Env.getCtx(), clientID);
|
||||
if (allClients) {
|
||||
String message = "Installing " + fileName + " in client " + client.getValue() + "/" + client.getName();
|
||||
statusUpdate(message);
|
||||
}
|
||||
Env.setContext(Env.getCtx(), "#AD_Client_ID", client.getAD_Client_ID());
|
||||
try {
|
||||
// call 2pack
|
||||
if (service != null) {
|
||||
if (!merge(packinFile, null)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!directMerge(packinFile, null)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
logger.log(Level.SEVERE, "Pack in failed.", e);
|
||||
return false;
|
||||
} catch (Throwable e) {
|
||||
logger.log(Level.SEVERE, "Pack in failed.", e);
|
||||
return false;
|
||||
} finally {
|
||||
Env.setContext(Env.getCtx(), "#AD_Client_ID", 0);
|
||||
}
|
||||
logger.warning(packinFile.getPath() + " installed");
|
||||
}
|
||||
if (allClients ) {
|
||||
// when arriving here it means an ALL-CLIENTS 2pack was processed successfully
|
||||
// register a record on System to avoid future reprocesses of the same file
|
||||
X_AD_Package_Imp_Proc pimpr = new X_AD_Package_Imp_Proc(Env.getCtx(), 0, null);
|
||||
pimpr.setName(fileName);
|
||||
pimpr.setDateProcessed(new Timestamp(System.currentTimeMillis()));
|
||||
pimpr.setP_Msg("This ALL-CLIENT 2Pack was applied successfully in all tenants");
|
||||
pimpr.setAD_Package_Source_Type(X_AD_Package_Imp_Proc.AD_PACKAGE_SOURCE_TYPE_File);
|
||||
pimpr.saveEx();
|
||||
X_AD_Package_Imp pimp = new X_AD_Package_Imp(Env.getCtx(), 0, null);
|
||||
pimp.setAD_Package_Imp_Proc_ID(pimpr.getAD_Package_Imp_Proc_ID());
|
||||
pimp.setName(fileName);
|
||||
pimp.setPK_Status("Completed successfully");
|
||||
pimp.setDescription("This ALL-CLIENT 2Pack was applied successfully in all tenants");
|
||||
pimp.setProcessed(true);
|
||||
pimp.saveEx();
|
||||
}
|
||||
logger.warning(packinFile.getPath() + " installed");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -282,14 +369,12 @@ public class PackInApplicationActivator extends AbstractActivator {
|
|||
}
|
||||
}
|
||||
|
||||
private MClient getClient(String clientValue) {
|
||||
private int[] getClientIDs(String clientValue) {
|
||||
String where = "Value = ?";
|
||||
Query q = new Query(Env.getCtx(), MClient.Table_Name,
|
||||
where, null)
|
||||
.setParameters(new Object[] {clientValue})
|
||||
Query q = new Query(Env.getCtx(), MClient.Table_Name, where, null)
|
||||
.setParameters(clientValue)
|
||||
.setOnlyActiveRecords(true);
|
||||
|
||||
return q.first();
|
||||
return q.getIDs();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -312,6 +397,6 @@ public class PackInApplicationActivator extends AbstractActivator {
|
|||
Properties serverContext = new Properties();
|
||||
serverContext.setProperty("#AD_Client_ID", "0");
|
||||
ServerContext.setCurrentInstance(serverContext);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ public class ProcessDialog extends AbstractProcessDialog implements EventListene
|
|||
layoutResultPanel (topParameterLayout);
|
||||
|
||||
StringBuilder buildMsg = new StringBuilder(getInitialMessage());
|
||||
buildMsg.append("<p><font color=\"").append(pi.isError() ? "#FF0000" : "#0000FF").append("\">** ")
|
||||
buildMsg.append("<hr><p><font color=\"").append(pi.isError() ? "#FF0000" : "#0000FF").append("\">** ")
|
||||
.append(pi.getSummary())
|
||||
.append("</font></p>");
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ when detect side effect, fix to only apply for parameter window*/
|
|||
}
|
||||
|
||||
.message-paramenter{
|
||||
max-height: 150pt;
|
||||
max-height: 300pt;
|
||||
overflow: hidden;
|
||||
margin: 10px;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue